当前位置:首页 > 点赞特效(二)这个点赞效果不需要使用图片,而是使用极坐标方程

点赞特效(二)这个点赞效果不需要使用图片,而是使用极坐标方程

发布于 2019-01-31 阅读 1920 次 CSS Canvas Javascript ES6

效果预览


这个点赞效果不需要使用图片,而是使用极坐标方程

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. </head>
  7. <body>
  8. <canvas></canvas>
  9. <div id="show" style="width:60px;height:40px;background:#000;margin-left:60px;position:relative;z-index:9;margin-top:-40px;"></div>
  10. <script type="text/javascript">
  11. const canvas = document.querySelector('canvas');
  12. const show = document.querySelector('#show');
  13. canvas.width = 200;
  14. canvas.height = 400;
  15. var total = 0;
  16. class Heart{
  17. constructor(canvas, color){
  18. this.ctx = canvas.getContext('2d');
  19. this.color = color || ['#ed4d57','#3c86f4','#f4793c','#f058e0','#ff71a1','#40f9ee']
  20. this.heartData = [];
  21. }
  22. draw(dx=0, dy=0, color){
  23. this.ctx.strokeStyle = color;
  24. this.ctx.lineWidth = 1;
  25. this.ctx.beginPath();
  26. this.ctx.save();
  27. this.ctx.globalAlpha = 1-(canvas.height-dy)/canvas.height+0.3;
  28. this.ctx.globalAlpha = this.ctx.globalAlpha >=1?1:this.ctx.globalAlpha;
  29. //这里一定要先平移再旋转
  30. this.ctx.translate(dx, dy);
  31. //绘制的坐标系是从左上角到右下角
  32. this.ctx.rotate(Math.PI);
  33. this.drawheart();
  34. this.ctx.stroke();
  35. this.ctx.fillStyle = color;
  36. this.ctx.fill();
  37. this.ctx.restore();
  38. }
  39. drawheart(){
  40. const part = 2 * Math.PI / 500;
  41. let t = 0;
  42. for(let i=0; i<500; i++) {
  43. t += part;
  44. const x=16*Math.pow(Math.sin(t), 3);
  45. const y=13*Math.cos(t)-5*Math.cos(2*t)-2*Math.cos(3*t)-Math.cos(4*t)
  46. this.ctx.lineTo(x,y);
  47. }
  48. }
  49. pushHearts(){
  50. var dir;
  51. if(total%2 == 0){
  52. dir=1;
  53. }else{
  54. dir=-1;
  55. }
  56. this.heartData.push({
  57. dx: this.getRandom(80,canvas.width/2),
  58. dy: canvas.height-20,
  59. dir: dir,
  60. speed: 1,
  61. color: this.color[this.getRandom(0, this.color.length-1)],
  62. minX: this.getRandom(0,canvas.width/2),
  63. maxX: this.getRandom(canvas.width/2,canvas.width-20),
  64. });
  65. total++;
  66. }
  67. drawhearts(){
  68. this.clearCanvas();
  69. for(let i=0;i<this.heartData.length;i++){
  70. this.draw(this.heartData[i].dx, this.heartData[i].dy,this.heartData[i].color);
  71. if(this.heartData[i].dx<=this.heartData[i].minX){
  72. this.heartData[i].dir = 1;
  73. }
  74. if(this.heartData[i].dx>=this.heartData[i].maxX){
  75. this.heartData[i].dir = -1
  76. }
  77. this.heartData[i].dx = this.heartData[i].dx+this.heartData[i].dir*this.heartData[i].speed;
  78. this.heartData[i].dy = this.heartData[i].dy - 2;
  79. }
  80. if(this.heartData[0] && this.heartData[0].dy && this.heartData[0].dy<=-30){
  81. this.heartData.shift();
  82. }
  83. // loop
  84. requestAnimationFrame(function(){
  85. heart.drawhearts()
  86. });
  87. }
  88. clearCanvas(){
  89. this.ctx.clearRect(0,0,canvas.width,canvas.height);
  90. }
  91. getRandom(min, max){
  92. return Math.floor(Math.random()*(max-min+1)+min);
  93. }
  94. }
  95. const ctx = canvas.getContext("2d");
  96. const heart = new Heart(canvas);
  97. show.onclick = (e)=>{
  98. heart.pushHearts();
  99. }
  100. heart.drawhearts()
  101. </script>
  102. </body>
  103. </html>