效果预览
这个点赞效果不需要使用图片,而是使用极坐标方程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<canvas></canvas>
<div id="show" style="width:60px;height:40px;background:#000;margin-left:60px;position:relative;z-index:9;margin-top:-40px;"></div>
<script type="text/javascript">
const canvas = document.querySelector('canvas');
const show = document.querySelector('#show');
canvas.width = 200;
canvas.height = 400;
var total = 0;
class Heart{
constructor(canvas, color){
this.ctx = canvas.getContext('2d');
this.color = color || ['#ed4d57','#3c86f4','#f4793c','#f058e0','#ff71a1','#40f9ee']
this.heartData = [];
}
draw(dx=0, dy=0, color){
this.ctx.strokeStyle = color;
this.ctx.lineWidth = 1;
this.ctx.beginPath();
this.ctx.save();
this.ctx.globalAlpha = 1-(canvas.height-dy)/canvas.height+0.3;
this.ctx.globalAlpha = this.ctx.globalAlpha >=1?1:this.ctx.globalAlpha;
//这里一定要先平移再旋转
this.ctx.translate(dx, dy);
//绘制的坐标系是从左上角到右下角
this.ctx.rotate(Math.PI);
this.drawheart();
this.ctx.stroke();
this.ctx.fillStyle = color;
this.ctx.fill();
this.ctx.restore();
}
drawheart(){
const part = 2 * Math.PI / 500;
let t = 0;
for(let i=0; i<500; i++) {
t += part;
const x=16*Math.pow(Math.sin(t), 3);
const y=13*Math.cos(t)-5*Math.cos(2*t)-2*Math.cos(3*t)-Math.cos(4*t)
this.ctx.lineTo(x,y);
}
}
pushHearts(){
var dir;
if(total%2 == 0){
dir=1;
}else{
dir=-1;
}
this.heartData.push({
dx: this.getRandom(80,canvas.width/2),
dy: canvas.height-20,
dir: dir,
speed: 1,
color: this.color[this.getRandom(0, this.color.length-1)],
minX: this.getRandom(0,canvas.width/2),
maxX: this.getRandom(canvas.width/2,canvas.width-20),
});
total++;
}
drawhearts(){
this.clearCanvas();
for(let i=0;i<this.heartData.length;i++){
this.draw(this.heartData[i].dx, this.heartData[i].dy,this.heartData[i].color);
if(this.heartData[i].dx<=this.heartData[i].minX){
this.heartData[i].dir = 1;
}
if(this.heartData[i].dx>=this.heartData[i].maxX){
this.heartData[i].dir = -1
}
this.heartData[i].dx = this.heartData[i].dx+this.heartData[i].dir*this.heartData[i].speed;
this.heartData[i].dy = this.heartData[i].dy - 2;
}
if(this.heartData[0] && this.heartData[0].dy && this.heartData[0].dy<=-30){
this.heartData.shift();
}
// loop
requestAnimationFrame(function(){
heart.drawhearts()
});
}
clearCanvas(){
this.ctx.clearRect(0,0,canvas.width,canvas.height);
}
getRandom(min, max){
return Math.floor(Math.random()*(max-min+1)+min);
}
}
const ctx = canvas.getContext("2d");
const heart = new Heart(canvas);
show.onclick = (e)=>{
heart.pushHearts();
}
heart.drawhearts()
</script>
</body>
</html>