利用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>