原生JS:跟随鼠标移动洒落星星的特效

原生JS:跟随鼠标移动洒落星星的特效

在这里插入图片描述
封装成一个js文件,便捷引用

function drawStar() {//定义数组,arr存放每个小星星的信息,colour为颜色数组,存几个好看的颜色var arr = [];var colours = ["#ffff00", "#66ffff", "#3399ff", "#99ff00", "#ff9900"];var timeoutList = []; // 计时器列表-用于后续清理计时器// 创建画布const canvas = document.createElement('canvas')document.body.appendChild(canvas)var ctx = canvas.getContext("2d");// 让画布自适应窗口大小,这个复制即可function resizeCanvas() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;}resizeCanvas();// 给画布css样式,固定定位,且阻止用户的鼠标事件canvas.style.cssText = `position: fixed;z-index: 1000;top: 0;left: 0;pointer-events: none;`;// 封装绘制一个五角星函数// x是圆心横坐标,y是圆心纵坐标,其实就是鼠标位置(x ,y)// r是里面小圆半径 ,l是大圆半径// rot是初始旋转角度function star(x, y, r, l, rot) {ctx.beginPath();// 循环5次,因为5个点for (let i = 0; i < 5; i++) {//先绘制小圆上一个点ctx.lineTo(Math.cos(((18 + i * 72 - rot) * Math.PI) / 180) * r + x,-Math.sin(((18 + i * 72 - rot) * Math.PI) / 180) * r + y);//连线到大圆上一个点ctx.lineTo(Math.cos(((54 + i * 72 - rot) * Math.PI) / 180) * l + x,-Math.sin(((54 + i * 72 - rot) * Math.PI) / 180) * l + y);}ctx.closePath();}// 绘制一堆星星function draw() {//循环数组for (let i = 0; i < arr.length; i++) {let temp = arr[i];//调用绘制一个星星函数star(temp.x, temp.y, temp.r, temp.r * 3, temp.rot);//星星颜色ctx.fillStyle = temp.color;//星星边框颜色ctx.strokeStyle = temp.color;//线宽度ctx.lineWidth = 0.1;//角有弧度ctx.lineJoin = "round";// 填充ctx.fill();// 绘制路径ctx.stroke();}}//更新动画function update() {//循环数组for (let i = 0; i < arr.length; i++) {// x坐标+dx移动距离arr[i].x += arr[i].dx;// y坐标+dy移动距离arr[i].y += arr[i].dy;// 加上旋转角度arr[i].rot += arr[i].td;// 半径慢慢减小arr[i].r -= 0.015;// 当半径小于0时if (arr[i].r < 0) {//删除该星星arr.splice(i, 1);}}}// 添加当前位置星星数据function addStarts(e) {// 每移动触发一次事件给arr数组添加一个星星arr.push({// x是初始横坐标x: e.clientX,//y是初始纵坐标y: e.clientY,//r是星星里面那个小圆半径,哪来的小圆等会说r: Math.random() * 0.5 + 1.5,//运动时旋转的角度td: Math.random() * 4 - 2,// X轴移动距离dx: Math.random() * 2 - 1,// y轴移动距离dy: Math.random() * 1 + 1,// 初始的旋转角度rot: Math.random() * 90 + 90,// 颜色color: colours[Math.floor(Math.random() * colours.length)],});}// 监听屏幕变化事件window.onresize = resizeCanvas;// 监听鼠标移动事件window.addEventListener("mousemove", (e) => {// 添加星星数据addStarts(e);//设置100毫秒内效果for (let index = 0; index < 200; index++) {if (index === 0 && timeoutList.length > 0) {for (const timeoutName of timeoutList) {clearTimeout(timeoutName)}}timeoutList[index] = setTimeout(() => {//清屏ctx.clearRect(0, 0, canvas.width, canvas.height);//绘制draw();//更新update();}, index * 20);}});
}drawStar()

调用方式:

import "./drawStarts";

或者

<script src="./drawStarts.js"></script>

额外说明:

参考网络文档,发现问题。写这个动画的人canvas绘图和js功底很赞。本文在原文基础上对性能和样式,以及调用方式做了些优化。

  • 计时器一直跑,容易内存溢出,而且长时间网页很卡。setInterval时间20毫秒
  • 需要写canvas标签,通过id获取,有些麻烦
  • 样式定位后需要修改

优化后:

  • 弃用 setInterval,采用 setTimeout,防止内存溢出
  • 鼠标滑动开启4秒倒计时。自动清理之前的计时器
  • 便捷引用,动态创建canvas标签,不需要额外的标签、css等

参考文档:

使用JS实现一个跟随鼠标移动洒落的星星特效:https://www.jb51.net/article/279141.htm


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部