方法简介:
先绘制出所需马赛克部分矩形图片,在通过裁剪画布实现圆形图片,之后将圆形图片打上马赛克,最后在画布最底层绘制全部图片。
在图片上绘制圆形如图:
代码示例
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style>
.canvas1{
position: absolute;
left:0;
top:0;
left: 0;
background: beige;
}
.cir{
border:1px solid red;
position: absolute;
z-index: 10;
/* border-radius: 50%; */
}
</style>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<meta charset="utf-8" />
</head>
<body>
<canvas id="canvas1" class="canvas1"></canvas>
<div>Canvas Demo</div>
<div id="output"></div>
<script type="text/javascript">
var canvas1 = document.getElementById("canvas1");
var ctx1 = canvas1.getContext("2d");
var aImg = new Image();
aImg.src = '460-259.jpg';
aImg.onload = function(){
canvas1.width = aImg.width;
canvas1.height = aImg.height;
ctx1.drawImage(this,0,0,aImg.width,aImg.height);
}
/* 绘制圆形 */
$("#canvas1").mousedown(function (e) {
var e = window.event || arguments[0];
var initX = e.pageX;
var initY = e.pageY;
var targetE = e.target;
var moveX = 0,moveY = 0;
var clearX=0,clearY=0,clearW=0,clearH=0;
$("body").append('<div class="cir"></div>')
$(document).bind("mousemove",function(){
var e = window.event || arguments[0];
var x = e.pageX,y = e.pageY;
moveX = Math.abs(x - initX);
moveY = Math.abs(y - initY);
$(".cir").css({
left:initX -moveX+"px",
top:initY - moveY+"px",
width:moveX * 2-2+"px", //-2 减去的绘制圆的边框(红色圆)
height:moveY * 2-2+"px",
"border-radius":moveX+"px" + "/"+ moveY+"px"
})
}).on("mouseup",function(){
$(document).unbind('mouseup'); // 解除按下事件
$(document).unbind('mousemove'); // 解除按下事件
$(".cir").remove()
if(moveX>2 && moveY>2 ){ //有效绘制区域
ctx1.beginPath();
ctx1.clearRect(clearX,clearY,clearW,clearH)
ctx1.ellipse(initX,initY,moveX,moveY,0,0,2*Math.PI);
ctx1.stroke();
draw(aImg,initX,initY,moveX,moveY);
}
})
})
/*
x,y 圆心坐标(x,y)
r1:圆水平半径
r2:圆垂直半径
*/
function draw(obj,x,y,r1,r2){
var oriW = obj.width;
var oriH = obj.height;
ctx1.drawImage(obj,x-r1,y-r2,2*r1,2*r2,x-r1,y-r2,2*r1,2*r2); //裁剪圆大小的画面 (obj,x1,y1,w1,h1,x2,y2,w2,h2) x2 = x1/w1*w2
ctx1.globalCompositeOperation = 'destination-in'
ctx1.save();
ctx1.beginPath()
ctx1.ellipse(x, y, r1, r2,0,0, 2 * Math.PI); // 从画布上裁剪出这个圆形 圆心(x,y) 水平半径r1,垂直半径r2
ctx1.closePath()
ctx1.fill()
ctx1.clip();//裁剪
ctx1.restore()
//获取坐边图像的局部坐标的部分像素
var oImgData = ctx1.getImageData(x-r1,y-r2,2*r1,2*r2);
var w = oImgData.width;
var h = oImgData.height;
//马赛克的程度,数字越大越模糊
var num = 4;
//等分画布
var stepW = w/num;
var stepH = h/num;
//这里是循环画布的像素点
for(var i=0;i<stepH;i++){
for(var j=0;j<stepW;j++){
//获取一个小方格的随机颜色,这是小方格的随机位置获取的
var color = getXY(oImgData,j*num+Math.floor(Math.random()*num),i*num+Math.floor(Math.random()*num));
//这里是循环小方格的像素点,
for(var k=0;k<num;k++){
for(var l=0;l<num;l++){
//设置小方格的颜色
setXY(oImgData,j*num+l,i*num+k,color);
}
}
}
}
ctx1.putImageData(oImgData,x-r1,y-r2);
ctx1.globalCompositeOperation = 'destination-over'
ctx1.drawImage(obj,0,0,oriW,oriH);
}
function getXY(obj,x,y){
var w = obj.width;
var h = obj.height;
var d = obj.data;
var color = [];
color[0] = obj.data[4*(y*w+x)];
color[1] = obj.data[4*(y*w+x)+1];
color[2] = obj.data[4*(y*w+x)+2];
color[3] = obj.data[4*(y*w+x)+3];
return color;
}
function setXY(obj,x,y,color){
var w = obj.width;
var h = obj.height;
var d = obj.data;
obj.data[4*(y*w+x)] = color[0];
obj.data[4*(y*w+x)+1] = color[1];
obj.data[4*(y*w+x)+2] = color[2];
obj.data[4*(y*w+x)+3] = color[3];
}
</script>
</body>
</html>