前言
今天我们要介绍的是一个基于Canvas的动态手电筒。这个手电筒可以通过鼠标的移动来模拟手电筒光圈,实现一个真实的手电筒体验。代码比较简单,让我们一起来看看如何实现。
首先让我们来看看这个手电筒的页面代码。我们可以看到这个页面主要由一个canvas元素构成,canvas是HTML5提供的用于绘图的标签。
<!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>
</head>
<body>
<canvas></canvas>
</body>
</html>
接下来我们来看看HTML中的style部分。首先对内外边距进行样式重置并且我们设置了整个body元素的样式,使其铺满整个屏幕。
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: url(https://pic2.zhimg.com/v2-4d0f3e43e75bb67646215e259fc2e9ad_r.jpg) no-repeat;
background-size: cover;
background-position: center;
}
其中,background属性指定了页面的背景图片,并设置了图片的尺寸和位置。
接下来我们来看canvas元素的样式:
canvas {
position: fixed;
left: 0;
top: 0;
z-index: 999;
pointer-events: none;
}
这里我们将canvas的位置设置为定位(position: fixed),并将其置于屏幕最上方(z-index: 999)。pointer-events属性设置为none,这意味着我们可以忽略canvas元素的鼠标事件,让鼠标事件穿透并传递到下面的元素上。
接下来是JavaScript代码的部分。
我们首先获取了canvas元素和它的上下文(context)。然后声明了一个position对象,用于记录鼠标位置以及光圈的半径。
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const position = {
x: 0,
y: 0,
r: 50
}
接下来是两个关键的函数:init和render。在init函数中,我们初始化了canvas元素并绘制了初始的黑色背景。而在render函数中,我们通过鼠标的位置来动态渲染光圈的大小,并在canvas上创建一个放射渐变效果,来模拟真实的手电筒光源。
function render() {
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
ctx.beginPath();
ctx.clearRect(0,0,canvas.width,canvas.height)
var radial = ctx.createRadialGradient(position.x,position.y,position.r,position.x,position.y,position.r*3)
radial.addColorStop(0,'rgba(255,255,255,0)');
radial.addColorStop(1,'rgba(0,0,0,0.9)');
ctx.fillStyle = radial;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
function init() {
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
ctx.beginPath();
ctx.clearRect(0,0,canvas.width,canvas.height)
var radial = ctx.createRadialGradient(position.x,position.y,position.r,position.x,position.y,position.r*3)
radial.addColorStop(1,'rgba(0,0,0,0.9)');
ctx.fillStyle = radial;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
其中,createRadialGradient函数可以创建一个放射渐变效果,其参数分别是光源的位置和大小。
最后,我们通过给document对象添加鼠标事件监听器来实现鼠标位置的实时更新。当鼠标移动时,我们便可以动态地渲染光圈的大小和位置了。
document.onmousemove = e => {
position.x = e.clientX;
position.y = e.clientY;
render();
}
window.onload=function() {
init()
}
现在,我们已经可以鼠标在页面上的移动来模拟手电筒的光线了!
结语
以上便可以通过简短易懂的代码来实现一个有趣的效果动画,