用JS實現圖片剪裁效果並預覽

今天又瘋狂學習瞭web前端的圖片剪裁效果,可以有個區域來框住圖片的某一部分,並可以預覽框住的部分

效果圖如下:

看著是不是很炫呢

簡單介紹下實現方法吧

1.佈局就是左右兩塊p,右邊的好說,主要是左邊的,左邊的用絕對佈局的方式分瞭3層,最下面一層是一個半透明的圖片,中間一層是原圖,但被剪切成隻有一塊,也隻顯示這一塊,可以用clip:rect方法實現,然後最上面一層就是自己寫的一個邊框,在邊框上加瞭8個點,分別給這8個點定義位置。

2.然後JS代碼用瞭鼠標的點擊事件來實現。

下面貼上自己的代碼:

index.html (這裡要引用兩個js文件,分別是jquery和jquery-ui,其中jquery可以引用網上的,jquery-ui我是自己下在本地引用的,大傢可以自己去官網下載,不引用則不能實現拖動剪切框)

 


<script src=”https://cdn.bootcss.com/jquery/2.2.0/jquery.min.js” type=”text/javascript”></script><script src=”js/jquery-ui-1.12.0/jquery-ui.min.js”></script>

<script type=”text/javascript” src=”img.js”></script>

 

 

 

 

 

 

 

img.css

 

 

body {
	background-color: #333;
}

#box {
	position: absolute;
	top: 200px;
	left: 100px;
	width: 600px;
	height: 319px;
}

#img1 {
	/*不透明度*/
	opacity: 0.3;
	position:absolute;
	top: 0;
	left: 0;

}

#img2 {
	position: absolute;
	top: 0;
	left: 0;

	/*用於剪切圖像的函數
	clip: rect(top,right,bottom,left);
	top表示剪切區域頂部離圖片頂部的距離
	right表示剪切區域右邊離圖片左邊的距離,即長+left
	bottom表示剪切區域底部離圖片頂部的距離,即寬+top
	left表示剪切區域左邊離圖片左邊的距離
	*/
	clip: rect(0, 200px, 200px, 0);
}

#main {
	position: absolute;
	border: 1px solid #fff;
	width:200px;
	height: 200px;
}

#preview {
	position: absolute;
	width: 600px;
	height: 319px;
	top:200px;
	left: 720px;
}
#preview img{
	/*要讓函數setPreview裡的clip函數達到作用,要給img增加絕對定位或者相對定位
	但由於父元素是絕對定位,所以這裡是絕對定位*/
	position: absolute;
}

.minDiv {
	position: absolute;
	width: 8px;
	height: 8px;
	background-color: #fff;
}

.left-up {
	top:-4px;
	left: -4px;

	/*鼠標變化  n-北  w-西  s-南  e-東*/
	cursor: nw-resize;
}

.up {
	/*距最近的一個position屬性為absolute或者relative的父級元素左邊50%的距離
	除此之外 top right bottom也是距最近的一個position屬性為absolute或者relative的父級元素
	的距離
	*/
	left: 50%;
	/*距離左邊-4px即向左邊移動4px*/
	margin-left: -4px;
	top:-4px;
	cursor: n-resize;
}

.right-up {
	right: -4px;
	top: -4px;
	cursor: ne-resize;
}

.right {
	top: 50%;
	margin-top:-4px;
	right: -4px;
	cursor: e-resize;
}

.right-down {
	bottom: -4px;
	right: -4px;
	cursor: se-resize;
}

.down {
	left: 50%;
	margin-left: -4px;
	bottom: -4px;
	cursor: s-resize;
}

.left-down {
	left: -4px;
	bottom: -4px;
	cursor: sw-resize;
}

.left {
	bottom: 50%;
	margin-bottom: -4px;
	left: -4px;
	cursor: w-resize;
}

img.js

 

 

// 在元素加載完之後執行,確保元素可以成功獲取
window.onload =function(){

	document.onselectstart = new Function('event.returnValue=false;');
	$("#main").draggable({containment:'parent', drag:setChoice});
	var img = document.getElementById("img2");

	var rightDiv = document.getElementById("right");
	var upDiv = document.getElementById("up");
	var leftDiv = document.getElementById("left");
	var downDiv = document.getElementById("down");
	var leftupDiv = document.getElementById("left-up");
	var rightupDiv = document.getElementById("right-up");
	var rightdownDiv = document.getElementById("right-down");
	var leftdownDiv = document.getElementById("left-down");

	var mainDiv = document.getElementById("main");
	var ifKeyDown = false; 

	var contact = "";// 表示被按下的觸點

	//鼠標按下狀態
	rightDiv.onmousedown = function(e) {
		/*拖動效果引入的jquery 和 jquery-ui也會去觸發鼠標點擊事件,
		所以為瞭防止自己定義的點擊事件和引入的點擊事件沖突,傳入e並加入以下
		這條語句,防止冒泡。冒泡是指鼠標點擊裡面的元素時也會觸發父元素的一些事件*/
		e.stopPropagation();
		ifKeyDown = true;
		contact = "right";
	}
	upDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "up";
	}
	leftDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "left";
	}
	downDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "down";
	}
	leftupDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "left-up";
	}
	rightupDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "right-up";
	}
	rightdownDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "right-down";
	}
	leftdownDiv.onmousedown = function(e) {
		e.stopPropagation();
		ifKeyDown = true;
		contact = "left-down";
	}

	//鼠標松開狀態
	window.onmouseup = function() {
		ifKeyDown = false;
	}

	//鼠標移動事件
	window.onmousemove = function(e) {
		if(ifKeyDown == true){

			switch(contact){
				case "right": rightMove(e); break;
				case "up": upMove(e); break;
				case "left": leftMove(e); break;
				case "down": downMove(e); break;
				case "left-up": leftMove(e); upMove(e); break;
				case "right-up": rightMove(e); upMove(e); break;
				case "right-down": rightMove(e); downMove(e); break;
				case "left-down": leftMove(e); downMove(e); break;
			}

		}
		setChoice();
		setPreview();
		
	}
	//右邊移動
	function rightMove(e) {
		var x = e.clientX; //鼠標x坐標
		var addWidth = ""; //鼠標移動後選取框增加的寬度
		var widthBefore = mainDiv.offsetWidth - 2;  //選取框變化前的寬度,減2是為瞭減去邊框border的寬,左右兩邊各為1px,所以是2
		addWidth = x - getPosition(mainDiv).left  //鼠標移動後增加的寬度
		if(widthBefore <= img.width){
			mainDiv.style.width = addWidth + "px"; //選取框變化後的寬度
		} else {
			mainDiv.style.width = img.width + "px";
		}
	}

	//上邊移動
	function upMove(e) {
		var topBefore = mainDiv.offsetTop;
		var y = e.clientY;//鼠標縱坐標
		var addHeight = 0;
		var mainY = getPosition(mainDiv).top;//選取框相對於屏幕上邊的距離
		addHeight =  y - mainY; //增加的高度
		var heightBefore = mainDiv.offsetHeight - 2;
		var bottom = topBefore + heightBefore;

		var heightAfter = heightBefore - addHeight;
		var topAfter = mainDiv.offsetTop + addHeight;

		if(topAfter < bottom && topAfter > -2){
			mainDiv.style.height = heightAfter + "px";
			mainDiv.style.top = topAfter + "px";
		}

	}

	//左邊移動
	function leftMove(e) {
		// 左邊框變化前距離父元素左邊的距離
		var leftBefore = mainDiv.offsetLeft;
		// 鼠標按下停止後鼠標距離瀏覽器左邊界的距離
		var x = e.clientX;
		// 定義增加的寬度
		var addWidth = 0;
		// 變化之前剪輯框的寬度
		var widthBefore = mainDiv.offsetWidth - 2;
		// 變化之前左邊框距離瀏覽器左邊界的距離
		var mainDivLeft =  getPosition(mainDiv).left;
		// 右邊框距離父元素的左邊的距離
		var right = leftBefore + widthBefore;
		// 增加的寬度
		addWidth = x - mainDivLeft;
		// 變化之後剪輯框的寬度
		var widthAfter = widthBefore - addWidth;
		// 變化之後剪輯框離左邊的距離
		var leftAfter = mainDiv.offsetLeft + addWidth;
		// 防止左邊框移到右邊框以外區域
		if(leftAfter < right && leftAfter > -2) {
			// 定義變化後的寬度
			mainDiv.style.width = widthAfter + "px";
			// 定義變化後距離左邊父元素的距離
			mainDiv.style.left = leftAfter + "px";
		}
	
	}

	//下邊移動
	function downMove(e) {
		var y = e.clientY;
		var addHeight = 0;
		var heightBefore = mainDiv.offsetHeight - 2;
		addHeight = y - getPosition(mainDiv).top;
		if(heightBefore <= img.height) {
			mainDiv.style.height = addHeight + "px";
		} else {
			mainDiv.style.height = img.height + "px";
		}
	
	}


	// 獲取元素相對於屏幕左邊的距離,利用offsetLeft
	// node為傳入的元素
	function getPosition(node) {
		/*獲取元素相對於父元素的左邊距*/
		var left = node.offsetLeft;
		/*獲取元素相對於父元素的上邊距*/
		var top = node.offsetTop;
		/*獲取元素的父元素*/
		var parent = node.offsetParent;
		/*判斷是否存在父元素,存在則一直加上左邊距,一直算出元素相對於瀏覽器
		左邊界的距離*/
		while(parent != null) {
			/*循環累加子元素相對於父元素的左邊距*/
			left += parent.offsetLeft;
			/*循環累加子元素相對於父元素的上邊距*/
			top += parent.offsetTop;
			/*循環獲取父元素的父元素,直至沒有父元素為止*/
			parent = parent.offsetParent;
		}
		return {"left":left,"top":top};
	}


	//設置選取區域高亮可見
	function setChoice() {
		var top = mainDiv.offsetTop;
		var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
		var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
		var left = mainDiv.offsetLeft;
		img.style.clip = "rect("+ top+"px,"+ right+"px,"+ bottom +"px,"+ left+"px"+")"
	}

	//預覽函數
	function setPreview() {
		var top = mainDiv.offsetTop;
		var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
		var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
		var left = mainDiv.offsetLeft;
		var img3 = document.getElementById("img3");
		img3.style.clip = "rect("+ top+"px,"+ right+"px,"+ bottom +"px,"+ left+"px"+")"
		
		img3.style.top = -(top) + "px";
		img3.style.left = -(left) + "px";
	}
}

發佈留言