1. 程式人生 > >【前端】利用Canvas給圖片新增水印,支援拖拽、編輯、縮放與刪除

【前端】利用Canvas給圖片新增水印,支援拖拽、編輯、縮放與刪除

利用Canvas給圖片新增水印,支援拖拽、編輯、縮放與刪除。

  • 難點一: 如何在偽元素after“刪除按鈕“上新增點選事件。
    通過滑鼠點選位置event中offsetX屬性獲得其偏離元素距離,與元素寬度做比較。若大於元素寬度,則點選在了偽元素上,否則點選到正常元素上。程式碼中有體現。
  • 難點二:如何對水印增加編輯和拖拽功能。
    使用contentEditable屬性來使其可以編輯,使用jqueryUI的draggable使其可拖拽。但是拖拽和編輯會有衝突。所以在單擊時設定拖拽失效。$(this).draggable({ disabled: false }); 雙擊時設定拖拽功能恢復。
  • 難點三:如何縮放水印
    給水印繫結滾輪事件,通過滾輪事件來設定放大字型,並重新繪製canvas。需要注意遮蔽掉 瀏覽器自身的滾動事件。
    event.stopPropagation();
    event.preventDefault();
  • 難點四: 如何在canvas中新增水印
    整體實現思路是通過span標籤覆蓋在canvas上方,同時在span的位置處canvas繪製同樣的水印文字。這樣通過郵件儲存的圖片中是包含水印的。獲得span的位置有兩點需要注意。一是canvas的baseline要設定成top。而是span要規定行高。建議和字型一致。
		cxt.textBaseline = 'top';//基線設定為向上對齊 重點!!!
		cxt.textAlign = 'left';
		left = parseFloat($('#textAdd').css("left"))//需要注意的是span元素應設定行高和字型大小一致。否則位置會有偏差。
		top = parseFloat($('#textAdd').css("top"))
		cxt.fillText(text,left,top);

整體的效果圖和程式碼如下:
在這裡插入圖片描述

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無標題文件</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<style type="text/css">
	#textAdd:hover:after{
	  content:'';
	  display: inline-block;
      width:40px;
      height:40px;
	  border-radius:20px;/**控制形狀**/
	  background: url("./delete.png") no-repeat center;
	  position: absolute;
	  top: 0px;
	}
</style>
</head>

<body>
	<button id="addBtn">增加</button>
	<div id="parent" style="position:relative" >
		<canvas id='myCanvas' ></canvas>
		<span id="textAdd" contenteditable="true"></span>
	</div>
	
<script type="text/javascript">
$(function(){
	
	var img = new Image();
	img.src = './500.jpg';
	img.onload=function(){//圖片載入完成,才可處理
		getImg();
	}; 
	var left = 20,top = 20,text = "請輸入內容", fontSize = 80;
	var c = document.getElementById("myCanvas");
	$("#addBtn").click(function(){
		spanObj = document.getElementById("textAdd");
		spanObj.style = "color: red;position:absolute;left:20px;top:20px;line-height:80px;"; 
		addText();
	})
	function addText(){
		spanObj = document.getElementById("textAdd");
		spanObj.innerHTML = text;
		$('#textAdd').css("font-size",fontSize + "px")
		$('#textAdd').css("line-height",fontSize + "px")
		var cxt = c.getContext("2d");
		c.width=img.width;
		c.height=img.height;
		var cxt = c.getContext("2d");
		cxt.fillStyle = "rgba(255, 255, 255, 0)";
		cxt.fillRect(0, 0, c.width, c.height);
		cxt.drawImage(img,0,0);
		cxt.save();
		cxt.fillStyle = "red"
		cxt.font = fontSize + "px Arial";
		cxt.textBaseline = 'top';//更改字號後,必須重置對齊方式,否則居中麻煩。設定文字的垂直對齊方式
		cxt.textAlign = 'left';
		left = parseFloat($('#textAdd').css("left"))
		top = parseFloat($('#textAdd').css("top"))
		cxt.fillText(text,left,top);
		
	}
	function getImg(){
		c.width=img.width;
		c.height=img.height;
		var cxt = c.getContext("2d");
		cxt.fillStyle = "rgba(255, 255, 255, 0)";
		cxt.fillRect(0, 0, c.width, c.height);
		cxt.drawImage(img,0,0);
	}
	$('#textAdd').draggable({
		containment: "#myCanvas",
		stop: function(event) {
			addText()
	}}).click(function (e){  
		//判斷是不是點選的刪除按鈕
		if(e.offsetX > $(this).width()){
			spanObj = document.getElementById("textAdd");
			spanObj.innerHTML = "";
			getImg();
			return;
		}
		$(this).draggable({ disabled: false });  
		$(this).css('backgroundColor', 'transparent');  
	}).dblclick(function (){  
		$(this).draggable({ disabled: true });  
		$(this).css('backgroundColor', '#FFFF6F');  
		getImg();
	});
	
	//失去焦點 判斷文字有無改變
	$('#textAdd').focusout(function() {
		text = $('#textAdd').text();
		addText();
	});

	
	$('#textAdd').on("mousewheel",function(event,delta){
		console.log(event.wheelDelta,event.originalEvent.wheelDelta);
		if(event.originalEvent.wheelDelta>0){
			fontSize += 2;
		}else{
			fontSize -= 2;
		}
		event.stopPropagation();
		event.preventDefault();
		addText();
	})
	
})
</script>
</body>
</html>