先看效果(完整代码在底部):
因为录屏软件的原因,动画看着有点迟钝,其实是动画很顺畅的~
https://space.bilibili.com/176586698
实现过程(可一步一步实现):
1.定义标签与基本css样式:
<h1>北极光之夜。</h1>
<canvas id="canvas"></canvas>
#canvas{
position: fixed;
top: 0;
left: 0;
/* filter: contrast(30); */
}
主要是canvas重力小球部分,h1标题文字等的css部分就不细写了,看源码即可。
2.开始js部分实现,先获取画布:
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
3. 定义变量(看注释):
// w为画布宽 ,h为画布高
var w=0,h=0;
// 存放小球颜色数组,给点好看的颜色 ╭(●`∀´●)╯
var colour = ["#00BFFF","#00FFFF","#3CB371","#FFFF00","#FF8C00","#7B68EE"];
// 存放每个小球的基本信息,位置半径等等...
var arr = [];
// 小球数量
var num = 66;
4.画布自适应屏幕大小函数,这个直接复制便可,以后做画布背景都可以用:
window.onresize=resizeCanvas;
function resizeCanvas(){
w=canvas.width = window.innerWidth;
h=canvas.height = window.innerHeight;
// 窗口大小改变时,arr数组重新初始化
arr.length = 0;
chushi();
}
resizeCanvas();
5. 定义一个函数后面用,作用是随机返回mix与max间的一个值,也直接复制:
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
Math.random() 返回0到1之间的数。
6. arr数组初始化,每个小球的初始信息:
function chushi(){
for(let i=0;i<num;i++){
arr.push({
// x为在画布水平方向位置
x:getRandomArbitrary(15,w-15),
// y为在画布垂直方向位置
y:getRandomArbitrary(-h/2,h/2),
// 小球半径
r:getRandomArbitrary(5,15),
// 小球水平方向移动距离大小
dx:getRandomArbitrary(-3,3),
// 小球垂直方向移动距离大小
dy:0.5,
// 随机颜色
color: colour[parseInt(Math.random() * (colour.length-1))]
})
}
}
parseInt()返回整数。
7.绘制画布每一帧小球 ≖‿≖✧:
function draw(){
for(let i=0;i<arr.length;i++){
let circle = arr[i];
// 开始绘制
ctx.beginPath();
// 颜色
ctx.fillStyle = circle.color;
// 画圆
ctx.arc(circle.x,circle.y,circle.r,0,Math.PI*2,false);
// 定义阴影
ctx.shadowOffsetx=0;
ctx.shadowOffsetY=0;
ctx.shadowBlur= 20;
ctx.shadowColor = circle.color;
// 填充
ctx.fill();
// 结束绘制
ctx.closePath();
}
}
8. 更新,小球信息要进行的变化:
function updates(){
// 循环数组
for(let i=0;i<arr.length;i++){
// 如果小球垂直位置+半径+dy+0.3 将要大于屏幕高度,就是小球要超出屏幕底部时
if(arr[i].y + arr[i].r + arr[i].dy + 0.3>=h){
// 垂直移动距离大小变负数,这样小球会往反方向移动
arr[i].dy = -arr[i].dy;
// 同时垂直移动距离大小×0.9,逐渐变小,不能一直动个不停
arr[i].dy *= 0.9;
// 水平方向同上
arr[i].dx *= 0.9;
}else{
// 垂直移动距离大小+0.3,这样可以有加速度效果,0.3是我觉得合适,也可以其它
arr[i].dy += 0.3;
}
// 如果小球水平位置+半径+dx 将要大于屏幕宽度,就是小球要超出屏幕左右侧部时
if(arr[i].x + arr[i].r + arr[i].dx > w || arr[i].x - arr[i].r <=0){
// 水平移动距离大小变负数,这样小球会往反方向移动
arr[i].dx = -arr[i].dx;
}
//小球位置改变
arr[i].x += arr[i].dx;
arr[i].y += arr[i].dy;
}
}
9.设置动画:
// arr初始化
chushi();
setInterval(function(){
ctx.clearRect(0, 0, w , h);
//绘制
draw();
//更新
updates();
},10)
ctx.clearRect():清除画布。
10.给body绑定点击事件,鼠标点击窗口某一位置后小球上升一段距离:
var body =document.querySelector("#body");
body.addEventListener('click',function(event){
for(let i=0;i<arr.length;i++){
// 如果arr[i].y - arr[i].r 还大于0,0就是屏幕顶部
if(arr[i].y - arr[i].r>=0){
// dy给一个随机值
arr[i].dy = getRandomArbitrary(-10,-5);
// dx给一个随机值
arr[i].dx=getRandomArbitrary(-3,3);
}
}
})
完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<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>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
body{
overflow: hidden;
background-color: rgb(5, 7, 24);
}
#canvas{
position: fixed;
top: 0;
left: 0;
/* filter: contrast(30); */
}
.yuan{
position: absolute;
width: 5px;
height: 5px;
border: 2px solid rgb(11, 147, 211);
border-radius: 50%;
animation: big 1s linear;
box-shadow:inset 0 0 200px rgb(11, 147, 211);
}
@keyframes big{
100%{
width: 1000px;
height: 1000px;
box-shadow:inset 0 0 0px rgb(11, 147, 211);
border: 2px solid transparent;
/* background-color: rgb(11, 147, 211); */
}
}
h1{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-45%,-50%);
font-size: 8vw;
color: transparent;
-webkit-background-clip: text;
background-image: url(img/star.gif);
filter: drop-shadow(0 0 60px rgb(0, 132, 255));
}
</style>
</head>
<body id="body">
<h1>北极光之夜。</h1>
<canvas id="canvas"></canvas>
<script>
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
// w为画布宽 ,h为画布高
var w=0,h=0;
// 存放小球颜色数组,给点好看的颜色 ╭(●`∀´●)╯
var colour = ["#00BFFF","#00FFFF","#3CB371","#FFFF00","#FF8C00","#7B68EE"];
// 存放每个小球的基本信息,位置半径等等...
var arr = [];
// 小球数量
var num = 66;
window.onresize=resizeCanvas;
function resizeCanvas(){
w=canvas.width = window.innerWidth;
h=canvas.height = window.innerHeight;
// 窗口大小改变时,arr数组重新初始化
arr.length = 0;
chushi();
}
resizeCanvas();
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
function chushi(){
for(let i=0;i<num;i++){
arr.push({
// x为在画布水平方向位置
x:getRandomArbitrary(15,w-15),
// y为在画布垂直方向位置
y:getRandomArbitrary(-h/2,h/2),
// 小球半径
r:getRandomArbitrary(5,15),
// 小球水平方向移动距离大小
dx:getRandomArbitrary(-3,3),
// 小球垂直方向移动距离大小
dy:0.5,
// 随机颜色
color: colour[parseInt(Math.random() * (colour.length-1))]
/* color: `rgb(${Math.random() * 255},${Math.random() * 255},${Math.random() * 255})`
*/ })
}
}
function draw(){
for(let i=0;i<arr.length;i++){
let circle = arr[i];
// 开始绘制
ctx.beginPath();
// 颜色
ctx.fillStyle = circle.color;
// 画圆
ctx.arc(circle.x,circle.y,circle.r,0,Math.PI*2,false);
// 定义阴影
ctx.shadowOffsetx=0;
ctx.shadowOffsetY=0;
ctx.shadowBlur= 20;
ctx.shadowColor = circle.color;
// 填充
ctx.fill();
// 结束绘制
ctx.closePath();
}
}
function updates(){
// 循环数组
for(let i=0;i<arr.length;i++){
// 如果小球垂直位置+半径+dy+0.3 将要大于屏幕高度,就是小球要超出屏幕底部时
if(arr[i].y + arr[i].r + arr[i].dy + 0.3>=h){
// 垂直移动距离大小变负数,这样小球会往反方向移动
arr[i].dy = -arr[i].dy;
// 同时垂直移动距离大小×0.9,逐渐变小,不能一直动个不停
arr[i].dy *= 0.9;
// 水平方向同上
arr[i].dx *= 0.9;
}else{
// 垂直移动距离大小+0.3,这样可以有加速度效果,0.3是我觉得合适,也可以其它
arr[i].dy += 0.3;
}
// 如果小球水平位置+半径+dx 将要大于屏幕宽度,就是小球要超出屏幕左右侧部时
if(arr[i].x + arr[i].r + arr[i].dx > w || arr[i].x - arr[i].r <=0){
// 水平移动距离大小变负数,这样小球会往反方向移动
arr[i].dx = -arr[i].dx;
}
//小球位置改变
arr[i].x += arr[i].dx;
arr[i].y += arr[i].dy;
}
}
chushi();
setInterval(function(){
ctx.clearRect(0, 0, w , h);
draw();
updates();
},10)
var body =document.querySelector("#body");
body.addEventListener('click',function(event){
let left = event.clientX,top = event.clientY;
console.log(left,top);
let yuan = document.createElement('div');
yuan.classList.add('yuan');
yuan.style.cssText = `left: ${left}px;top: ${top}px; transform: translate(-50%,-50%); `
body.appendChild(yuan);
setTimeout(function(){
body.removeChild(yuan);
},999);
for(let i=0;i<arr.length;i++){
if(arr[i].y - arr[i].r>=0){
arr[i].dy = getRandomArbitrary(-10,-5);
arr[i].dx=getRandomArbitrary(-3,3);
}
}
})
</script>
</body>
</html>
其它:
物转星移,花开花落,周而复始,生生不息,但今昔已非昨日,然今日花容依旧。- - -《虫师》
这是我的B站账号~:https://space.bilibili.com/176586698
敲锣打鼓~
关注一波~
会有更多有意思的东西~
大概~
╭(●`∀´●)╯╰(●’◡’●)╮