// 探照灯
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>探照灯</title>
<style>
div {
position: relative;
width: 497px;
height: 351px;
margin: auto;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div>
<img id ='img' src="https://img1.baidu.com/it/u=1148520648,1390077994&fm=26&fmt=auto&gp=0.jpg" alt="">
<canvas width="497" height="351" id='myCanvas'></canvas>
</div>
</body>
<script>
var c = document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// 初始状态
let X = c.width /2 ,Y = c.height /2;
function draw (x,y){
// 保存了最开始的canvas状态(上面的ctx.fillRect(0,0,c.width,c.height))
ctx.save();
// 清空上一次的画布
ctx.clearRect(0,0,c.width,c.height);
// 绘制新的画布
ctx.fillRect(0,0,c.width,c.height);
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
// ctx.arc(x, y, 80, 0,2 * Math.PI, false);
// 上面这样的圆比较不美观,如果需要灯光的效果可以用createRadialGradient()实现
var grd = ctx.createRadialGradient(X,Y,40,X,Y,80);
grd.addColorStop(0, 'rgba(0, 0, 0, 1)');
grd.addColorStop(.5, 'rgba(0, 0, 0, 1)');
grd.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = grd;
ctx.arc(x, y, 80, 0,2 * Math.PI, false);
ctx.fill();
// 退回到之前保存的canvas状态(ctx.fillRect(0,0,c.width,c.height)),然后在此基础上进行下一次绘制
ctx.restore();
}
c.onmousemove = function(e){
X = e.offsetX;
Y = e.offsetY;
draw(X,Y)
}
// 默认在canvas的中间
draw(X,Y)
</script>
</html>
用到的主要知识:
- canvas的globalCompositeOperation合成(如果想要仔细了解这个globalCompositeOperation,欢迎看我的另一篇文章)
- canvas的getImageData获取canvas上面的像素信息
- 获取鼠标相对于容器边框的坐标offsetX,offsetY(对于坐标不太熟悉的朋友,可以移步获取鼠标坐标常用方法和获取元素宽高以及距离定位父元素距离)
- 通过createRadialGradient绘制渐变的圆形
- canvas的save和restore方法,如果需要详细学习,请移步canvas中的save和restore
对于比较基础的知识,这里我就不赘述了,如果想要学习的,那么可以看html5 canvas
探照灯效果如下: