酷炫一款动态背景+鼠标点击效果(HTML +js canvas)

简介: 前言之前用于装饰个人的Hexo博客背景和点击事件,于是动手弄弄顺便学习学习,现在分享出来给有需要的人。废话不多说 ,分享一款酷炫的页面动态背景 效果见( https://fivecc.cn )

前言

之前用于装饰个人的Hexo博客背景和点击事件,于是动手弄弄顺便学习学习,现在分享出来给有需要的人。

废话不多说 ,分享一款酷炫的页面动态背景 效果见(https://fivecc.cn)

动态背景

1. 效果图:

网络异常,图片无法展示
|

实例效果:

网络异常,图片无法展示
|

2. 源码:

<!--背景css--><style>* {
margin: 0;
padding: 0;
}
#canvasBg {
position: fixed;
background: #ccc;
overflow: auto;
z-index: -1;
}
</style><!--背景html--><canvasid="canvasBg"></canvas><!--背景js--><script>window.requestAnimationFrame= (function () {
return (
window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function (callback) {
window.setTimeout(callback, 1000/2);
    }
  );
})();
varmyCanvas=document.getElementById("canvasBg");
varctx=myCanvas.getContext("2d"); //getContext 设置画笔varnum;
varw, h;
varduixiang= [];
varmove= {};
functionwidthheight() {
w=myCanvas.width=window.innerWidth;
h=myCanvas.height=window.innerHeight;
num=Math.floor(w*h*0.00028); //点的数量。根据屏幕大小确定for (vari=0; i<num; i++) {
duixiang[i] = {
x: Math.random() *w,
y: Math.random() *h,
cX: Math.random() *0.6-0.3,
cY: Math.random() *0.6-0.3,
R: Math.floor(Math.random() *5) +2,
//CC:Math.floor(Math.random()*3)+2,r: Math.floor(Math.random() *254),
g: Math.floor(Math.random() *254),
b: Math.floor(Math.random() *254),
    };
// console.log(duixiang[i])Cricle(
duixiang[i].x,
duixiang[i].y,
duixiang[i].R,
duixiang[i].r,
duixiang[i].g,
duixiang[i].b    );
//Cricle(duixiang[i].x,duixiang[i].y,duixiang[i].R,duixiang[i].CC);  }
}
widthheight(); //获取浏览器的等宽度等高functionCricle(x, y, R, r, g, b) {
ctx.save(); //保存路径if (Math.random() >0.991) {
ctx.globalAlpha=0.9;
  } //ctx.fillStyle = "#CCC";}//填充的背景颜色else {
ctx.globalAlpha=0.47;
  }
ctx.fillStyle="rgb("+r+","+g+","+b+")";
ctx.beginPath(); //开始绘画ctx.arc(x, y, R, Math.PI*2, 0); //绘画圆 x y 半径(大小) 角度  一个PI 是180 * 2 = 360    真假 0/1 true/falsectx.closePath(); //结束绘画ctx.fill(); //填充背景颜色ctx.restore(); //回复路径}
Cricle();
!(functiondraw() {
ctx.clearRect(0, 0, w, h); //先清除画布上的点for (vari=0; i<num; i++) {
duixiang[i].x+=duixiang[i].cX;
duixiang[i].y+=duixiang[i].cY;
if (duixiang[i].x>w||duixiang[i].x<0) {
duixiang[i].cX=-duixiang[i].cX;
    }
if (duixiang[i].y>h||duixiang[i].y<0) {
duixiang[i].cY=-duixiang[i].cY;
    }
Cricle(
duixiang[i].x,
duixiang[i].y,
duixiang[i].R,
duixiang[i].r,
duixiang[i].g,
duixiang[i].b    );
//勾股定理判断两点是否连线for (varj=i+1; j<num; j++) {
if (
        (duixiang[i].x-duixiang[j].x) * (duixiang[i].x-duixiang[j].x) +          (duixiang[i].y-duixiang[j].y) * (duixiang[i].y-duixiang[j].y) <=55*55      ) {
line(
duixiang[i].x,
duixiang[i].y,
duixiang[j].x,
duixiang[j].y,
0,
i,
j        );
      }
if (move.x) {
if (
          (duixiang[i].x-move.x) * (duixiang[i].x-move.x) +            (duixiang[i].y-move.y) * (duixiang[i].y-move.y) <=100*100        ) {
line(duixiang[i].x, duixiang[i].y, move.x, move.y, 1, i, 1);
        }
      }
    }
  }
window.requestAnimationFrame(draw);
})();
//绘制线条functionline(x1, y1, x2, y2, flag, i, j) {
if (flag) {
varcolor=ctx.createLinearGradient(x1, y1, x2, y2);
ctx.globalAlpha=0.5;
color.addColorStop(
0,
"rgb("+duixiang[i].r+","+duixiang[i].g+","+duixiang[i].b+")"    );
color.addColorStop(0.8, "#019ee5");
  } else {
varcolor=ctx.createLinearGradient(x1, y1, x2, y2);
ctx.globalAlpha=0.9;
color.addColorStop(
0,
"rgb("+duixiang[i].r+","+duixiang[i].g+","+duixiang[i].b+")"    );
color.addColorStop(
1,
"rgb("+duixiang[j].r+","+duixiang[j].g+","+duixiang[j].b+")"    );
  }
ctx.save();
ctx.strokeStyle=color;
ctx.lineWidth=0.5;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
//ctx.restore();}
//document.onmousemove = function(e){//   move.x = e.clientX;//  move.y = e.clientY;//}//console.log(move)//去掉注释 ,可以与背景互动window.onresize=function () {
location.reload();
};
</script>

鼠标点击特效

1.鼠标点击效果

网络异常,图片无法展示
|

2.鼠标点击效果

<!--鼠标点击css--><style>#canvasEvent {
position: fixed;
pointer-events: none;
width: 100%;
height: 100%;
overflow: auto;
z-index: 999;
}
</style><!--鼠标点击html--><canvasid="canvasEvent"style="whdth: 100%;height: 100%"></canvas><!--鼠标点击html--><script>var_createClass= (function () {
functiondefineProperties(target, props) {
for (vari=0; i<props.length; i++) {
vardescriptor=props[i];
descriptor.enumerable=descriptor.enumerable||false;
descriptor.configurable=true;
if ("value"indescriptor) descriptor.writable=true;
Object.defineProperty(target, descriptor.key, descriptor);
    }
  }
returnfunction (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
returnConstructor;
  };
})();
function_classCallCheck(instance, Constructor) {
if (!(instanceinstanceofConstructor)) {
thrownewTypeError("Cannot call a class as a function");
  }
}
vargetRandom=functiongetRandom(min, max) {
returnMath.random() * (max-min) +min;
};
vargetRandomInt=functiongetRandomInt(min, max) {
returnMath.floor(Math.random() * (max-min)) +min;
};
vargetRandomColor=functiongetRandomColor() {
varcolors= [
"rgba(231, 76, 60, 1)", // 红"rgba(241, 196, 15, 1)", // 黄"rgba(46, 204, 113, 1)", // 绿"rgba(52, 152, 219, 1)", // 蓝"rgba(155, 89, 182, 1)", // 紫色  ];
returncolors[getRandomInt(0, colors.length)];
};
// Particle//粒子模块varParticle= (function () {
functionParticle(system, x, y) {
_classCallCheck(this, Particle);
this.system=system;
this.universe=this.system.world.universe;
this.x=x;
this.y=y;
this.color=getRandomColor();
this.life=1;
this.aging=getRandom(0.99, 0.999); // 0.99, 0.999 || 0.999, 0.9999this.r=getRandomInt(12, 16); //初始粒子半径范围this.speed=getRandom(18, 18.5); //粒子爆炸速度范围this.velocity= [
getRandom(-this.speed, this.speed),
getRandom(-this.speed, this.speed),
    ];
  }
_createClass(Particle, [
    {
key: "update",
value: functionupdate(dt) {
this.life*=this.aging;
if (
this.r<0.1||this.life===0||this.x+this.r<0||this.x-this.r>this.universe.width||this.y+this.r<0||this.y-this.r>this.universe.height        ) {
this.system.removeObject(this);
        }
this.r*=this.life;
this.x+=this.velocity[0];
this.y+=this.velocity[1];
      },
    },
    {
key: "render",
value: functionrender(ctx) {
// Main circle //亮圈模块ctx.fillStyle=this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r*1.2, 0, 2*Math.PI, false);
ctx.fill();
ctx.closePath();
varr=this.color.match(/([0-9]+)/g)[0];
varg=this.color.match(/([0-9]+)/g)[1];
varb=this.color.match(/([0-9]+)/g)[2];
// Gradient//梯度变化曲线varspread=1.5;
vargradient=ctx.createRadialGradient(
this.x,
this.y,
this.r,
this.x,
this.y,
this.r*spread        );
gradient.addColorStop(0, "rgba("+r+", "+g+", "+b+", 0.5)");
gradient.addColorStop(1, "rgba("+r+", "+g+", "+b+", 0)");
ctx.globalCompositeOperation="lighter";
ctx.fillStyle=gradient;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r*spread, 0, 2*Math.PI, false);
ctx.fill();
ctx.closePath();
ctx.globalCompositeOperation="source-over";
// Aberration//偏差varoffset=this.r*0.5;
varcolor="rgba("+g+", "+b+", "+r+", 0.5)";
ctx.globalCompositeOperation="lighter";
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(
this.x+offset,
this.y+offset,
this.r,
0,
2*Math.PI,
false        );
ctx.fill();
ctx.closePath();
ctx.globalCompositeOperation="source-over";
      },
    },
  ]);
returnParticle;
})();
// Crown //水波纹圈模块varCrown= (function () {
functionCrown(system, x, y) {
_classCallCheck(this, Crown);
this.system=system;
this.x=x;
this.y=y;
this.r=getRandomInt(5, 15); // 5, 20  水波纹圈半径范围this.mod=1.1;
this.life=0.5; //水波纹线this.aging=getRandom(0.83, 0.899);
this.speed=getRandom(8, 9);
this.color= {
r: getRandomInt(236, 242),
g: getRandomInt(70, 80),
b: getRandomInt(50, 70),
    };
this.angle1=Math.PI*getRandom(0, 2);
this.angle2=this.angle1+Math.PI*getRandom(0.3, 0.4); //水波纹圈完整度  }
_createClass(Crown, [
    {
key: "update",
value: functionupdate(dt) {
this.life*=this.aging;
if (this.life<=0.0001) this.system.removeObject(this);
this.r+=Math.abs(1-this.life) *this.speed;
this.x1=this.x+this.r*Math.cos(this.angle1);
this.y1=this.y+this.r*Math.sin(this.angle1);
this.angle3=this.angle1+ (this.angle2-this.angle1) /2;
this.x2=this.x+this.r*this.mod*Math.cos(this.angle3);
this.y2=this.y+this.r*this.mod*Math.sin(this.angle3);
      },
    },
    {
key: "render",
value: functionrender(ctx) {
vargradient=ctx.createRadialGradient(
this.x,
this.y,
this.r*0.9,
this.x,
this.y,
this.r        );
gradient.addColorStop(
0,
"rgba("+this.color.r+", "+this.color.g+", "+this.color.b+", "+this.life+")"        );
gradient.addColorStop(
1,
"rgba("+this.color.r+", "+this.color.g+", "+this.color.b+", "+this.life*0.5+")"        );
ctx.fillStyle=gradient;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, this.angle1, this.angle2, false);
ctx.quadraticCurveTo(this.x2, this.y2, this.x1, this.y1);
ctx.fill();
ctx.closePath();
      },
    },
  ]);
returnCrown;
})();
// Explosion //爆炸模块varExplosion= (function () {
functionExplosion(world, x, y) {
_classCallCheck(this, Explosion);
this.world=world;
this.x=x;
this.y=y;
this.objects= [];
varparticles=getRandomInt(10, 30); // 10, 30 //爆炸 粒子数量varcrowns=particles*getRandom(0.4, 0.5);
while (crowns-->0) {
this.addCrown();
    }
while (particles-->0) {
this.addParticle();
    }
  }
_createClass(Explosion, [
    {
key: "update",
value: functionupdate(dt) {
this.objects.forEach(function (obj) {
if (obj) obj.update(dt);
        });
if (this.objects.length<=0) {
this.world.clearExplosion(this);
        }
      },
    },
    {
key: "render",
value: functionrender(ctx) {
this.objects.forEach(function (obj) {
if (obj) obj.render(ctx);
        });
      },
    },
    {
key: "addCrown",
value: functionaddCrown() {
this.objects.push(newCrown(this, this.x, this.y));
      },
    },
    {
key: "addParticle",
value: functionaddParticle() {
this.objects.push(newParticle(this, this.x, this.y));
      },
    },
    {
key: "removeObject",
value: functionremoveObject(obj) {
varindex=this.objects.indexOf(obj);
if (index!==-1) {
this.objects.splice(index, 1);
        }
      },
    },
  ]);
returnExplosion;
})();
// WorldvarConfettiWorld= (function () {
functionConfettiWorld() {
_classCallCheck(this, ConfettiWorld);
  }
_createClass(ConfettiWorld, [
    {
key: "init",
value: functioninit() {
this.objects= [];
window.addEventListener("click", this.explode.bind(this));
// Initial explosion //初始爆炸varcounter=0;
while (counter-->0) {
this.explode({
clientX: window.event.clientX, //getRandomInt(10, this.universe.width) ,          //this.universe.width / 2,clientY: window.event.clientY, //getRandomInt(10, 50) //this.universe.height / 2          });
        }
      },
    },
    {
key: "update",
value: functionupdate(dt) {
this.objects.forEach(function (obj) {
if (obj) obj.update(dt);
        });
varamount=this.objects.reduce(function (sum, explosion) {
return (sum+=explosion.objects.length);
        }, 0);
      },
    },
    {
key: "render",
value: functionrender(ctx) {
this.objects.forEach(function (obj) {
if (obj) obj.render(ctx);
        });
      },
    },
    {
key: "explode",
value: functionexplode(event) {
varx=event.clientX;
vary=event.clientY;
this.objects.push(newExplosion(this, x, y));
      },
    },
    {
key: "clearExplosion",
value: functionclearExplosion(explosion) {
varindex=this.objects.indexOf(explosion);
if (index!==-1) {
this.objects.splice(index, 1);
        }
      },
    },
  ]);
returnConfettiWorld;
})();
// TimevarTime= (function () {
functionTime() {
_classCallCheck(this, Time);
this.now=0; // 当前粒子时间this.prev=0; // 上一粒子时间this.elapsed=0; //最后粒子时间this.delta=0; // 从上次更新开始的时间this.fps=60; // 期望fpsthis.step=1/60; // 步长  }
_createClass(Time, [
    {
key: "update",
value: functionupdate(time) {
this.now=time;
this.elapsed= (this.now-this.prev) /1000;
this.prev=this.now;
this.delta+=this.elapsed;
      },
    },
    {
key: "raf",
value: functionraf(func) {
window.requestAnimationFrame(func);
      },
    },
    {
key: "hasFrames",
value: functionhasFrames() {
returnthis.delta>=this.step;
      },
    },
    {
key: "processFrame",
value: functionprocessFrame() {
this.delta-=this.step;
      },
    },
  ]);
returnTime;
})();
// CanvasvarUniverse= (function () {
functionUniverse(element) {
_classCallCheck(this, Universe);
this.el=element;
this.ctx=this.el.getContext("2d");
this.pixelRatio=window.devicePixelRatio;
this.time=newTime();
this.worlds= {};
this.world=null; // current statethis.updateSize();
window.addEventListener("resize", this.updateSize.bind(this));
this.addWorld("confetti", ConfettiWorld);
this.setWorld("confetti");
this.start();
  }
_createClass(Universe, [
    {
key: "start",
value: functionstart() {
this.time.raf(this.tick.bind(this));
      },
    },
    {
key: "tick",
value: functiontick(time) {
this.time.update(time);
if (this.time.hasFrames()) {
this.update();
this.time.processFrame();
        }
this.render();
this.time.raf(this.tick.bind(this));
      },
    },
    {
key: "update",
value: functionupdate() {
this.world.update(this.time.step);
      },
    },
    {
key: "render",
value: functionrender() {
vargradient=this.ctx.createLinearGradient(
0,
0,
this.width,
this.height        );
this.ctx.clearRect(0, 0, this.width, this.height);
this.world.render(this.ctx);
      },
// Helpers 库    },
    {
key: "updateSize",
value: functionupdateSize() {
this.width=window.innerWidth;
this.height=window.innerHeight;
this.el.width=this.width*this.pixelRatio;
this.el.height=this.height*this.pixelRatio;
this.el.style.width=window.innerWidth+"px";
this.el.style.height=window.innerHeight+"px";
this.ctx.scale(this.pixelRatio, this.pixelRatio);
      },
    },
    {
key: "addWorld",
value: functionaddWorld(worldName, World) {
this.worlds[worldName] =newWorld();
this.worlds[worldName].universe=this;
this.worlds[worldName].init();
      },
    },
    {
key: "setWorld",
value: functionsetWorld(worldName) {
this.world=this.worlds[worldName];
      },
    },
  ]);
returnUniverse;
})();
// Mainconsole.clear();
varelement=document.querySelector("#canvasEvent");
window.Canvas=newUniverse(element);
</script>

喜欢就给我点一个大大的赞是👍 外加一个关注

目录
相关文章
|
30天前
html+js+css实现的建筑方块立体数字时钟源码
html+js+css实现的建筑方块立体数字时钟源码
77 33
|
1月前
|
移动开发 前端开发 HTML5
基于HTML5+Canvas绘制的鼠标跟随三角形碎片光标动画代码
基于HTML5+Canvas绘制的鼠标跟随三角形碎片光标动画特效代码,很有意思,一团三角形碎片跟随鼠标的移动,不冗长、不笨重,反而有一种很轻盈的感觉,非常不错
59 29
|
2月前
一个好看的小时钟html+js+css源码
一个好看的小时钟html+js+css源码
116 24
|
2月前
|
Web App开发 移动开发 HTML5
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码。画面中心是悬浮于空的梅花鹿,其四周由白色线段组成了一个6边形将中心的梅花鹿包裹其中。四周漂浮的白雪随着多边形的转动而同步旋转。建议使用支持HTML5与css3效果较好的火狐(Firefox)或谷歌(Chrome)等浏览器预览本源码。
99 2
|
3月前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
217 1
|
3月前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
72 3
|
3月前
|
JavaScript
JS鼠标框选并删除HTML源码
这是一个js鼠标框选效果,可实现鼠标右击出现框选效果的功能。右击鼠标可拖拽框选元素,向下拖拽可实现删除效果,简单实用,欢迎下载
56 4
|
3月前
|
移动开发 HTML5
html5+three.js公路开车小游戏源码
html5公路开车小游戏是一款html5基于three.js制作的汽车开车小游戏源代码,在公路上开车网页小游戏源代码。
101 0
html5+three.js公路开车小游戏源码

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    Node.js 中实现多任务下载的并发控制策略
    32
  • 3
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    25
  • 4
    【JavaScript】深入理解 let、var 和 const
    48
  • 5
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    44
  • 6
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    53
  • 7
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    55
  • 8
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    71
  • 9
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    55
  • 10
    JavaWeb JavaScript ③ JS的流程控制和函数
    62