HTML5 canvas如何绘制酷炫能量线条效果(附代码)

 4379

本篇文章给大家介绍一下使用HTML5 canvas绘制酷炫能量线条特效的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助。


611e3bd537785.gif


上面是效果图,下面直接附js代码,希望对大家有所帮助!!

  1. // UTILconst PI = Math.PI,
  2.   TWO_PI = Math.PI * 2;const Util = {};Util.timeStamp = function() {
  3.   return window.performance.now();};Util.random = function(min, max) {
  4.   return min + Math.random() * (max - min);};Util.map = function(a, b, c, d, e) {
  5.   return (- b) / (- b) * (- d) + d;};Util.lerp = function(value1, value2, amount) {
  6.   return value1 + (value2 - value1) * amount;};Util.clamp = function(value, min, max) {
  7.   return Math.max(min, Math.min(max, value));};// Vectorclass Vector {
  8.   constructor(x, y) {
  9.     this.= x || 0;
  10.     this.= y || 0;
  11.   }
  12.   set(x, y) {
  13.     this.= x;
  14.     this.= y;
  15.   }
  16.   reset() {
  17.     this.= 0;
  18.     this.= 0;
  19.   }
  20.   fromAngle(angle) {
  21.     let x = Math.cos(angle),
  22.       y = Math.sin(angle);
  23.     return new Vector(x, y);
  24.   }
  25.   add(vector) {
  26.     this.+= vector.x;
  27.     this.+= vector.y;
  28.   }
  29.   sub(vector) {
  30.     this.-= vector.x;
  31.     this.-= vector.y;
  32.   }
  33.   mult(scalar) {
  34.     this.*= scalar;
  35.     this.*= scalar;
  36.   }
  37.   p(scalar) {
  38.     this./= scalar;
  39.     this./= scalar;
  40.   }
  41.   dot(vector) {
  42.     return vector.* this.+ vector.* this.y;
  43.   }
  44.   limit(limit_value) {
  45.     if (this.mag() > limit_value) this.setMag(limit_value);
  46.   }
  47.   mag() {
  48.     return Math.hypot(this.x, this.y);
  49.   }
  50.   setMag(new_mag) {
  51.     if (this.mag() > 0) {
  52.       this.normalize();
  53.     } else {
  54.       this.= 1;
  55.       this.= 0;
  56.     }
  57.     this.mult(new_mag);
  58.   }
  59.   normalize() {
  60.     let mag = this.mag();
  61.     if (mag > 0) {
  62.       this./= mag;
  63.       this./= mag;
  64.     }
  65.   }
  66.   heading() {
  67.     return Math.atan2(this.y, this.x);
  68.   }
  69.   setHeading(angle) {
  70.     let mag = this.mag();
  71.     this.= Math.cos(angle) * mag;
  72.     this.= Math.sin(angle) * mag;
  73.   }
  74.   dist(vector) {
  75.     return new Vector(this.- vector.x, this.- vector.y).mag();
  76.   }
  77.   angle(vector) {
  78.     return Math.atan2(vector.- this.y, vector.- this.x);
  79.   }
  80.   copy() {
  81.     return new Vector(this.x, this.y);
  82.   }}// Init canvaslet canvas = document.createElement("canvas"),
  83.   ctx = canvas.getContext("2d"),
  84.   H = (canvas.height = window.innerHeight),
  85.   W = (canvas.width = window.innerWidth);document.body.appendChild(canvas);// Mouselet mouse = {
  86.   x: W/2,
  87.   y: H/2};canvas.onmousemove = function(event) {
  88.   mouse.= event.clientX - canvas.offsetLeft;
  89.   mouse.= event.clientY - canvas.offsetTop;};document.body.onresize = function(event){
  90.   H = (canvas.height = window.innerHeight);
  91.   W = (canvas.width = window.innerWidth);}// Let's goclass Arrow {
  92.   constructor(x, y, target) {
  93.     this.position = new Vector(x, y);
  94.     this.velocity = new Vector().fromAngle(Util.random(0,TWO_PI));
  95.     this.acceleration = new Vector(0, 0);
  96.     this.target = target;
  97.     this.travelled_distance = 0;
  98.     this.min_size = 1;
  99.     this.max_size = 6;
  100.     this.size = Util.random(this.min_size, this.max_size);
  101.     this.zone = this.size * 4;
  102.     this.topSpeed = Util.map(this.size,this.min_size,this.max_size,40,10);
  103.     let tailLength = Math.floor(Util.map(this.size, this.min_size, this.max_size, 4, 16));
  104.     this.tail = [];
  105.     for (let i = 0; i < tailLength; i++) {
  106.       this.tail.push({
  107.         x: this.position.x,
  108.         y: this.position.y      });
  109.     }
  110.     this.wiggle_speed = Util.map(this.size, this.min_size, this.max_size, 2 , 1.2);
  111.     this.blink_offset = Util.random(0, 100);
  112.     this.alpha = Util.random(0.1,1)
  113.   }
  114.   render() {
  115.     this.update();
  116.     this.draw();
  117.   }
  118.   update() {
  119.     let old_position = this.position.copy();
  120.     // Focus on target
  121.     let t = new Vector(this.target.x, this.target.y),
  122.       angle = this.position.angle(t);
  123.     let d_f_target = t.dist(this.position);
  124.       let f = new Vector().fromAngle(angle);
  125.  
  126.       f.setMag(Util.map(Util.clamp(d_f_target,0,400), 0, 400, 0, this.topSpeed * 0.1));
  127.       this.addForce(f);
  128.      
  129.     // Update position and velocity
  130.     this.velocity.add(this.acceleration);
  131.     if(d_f_target < 800){
  132.        this.velocity.limit(Util.map(Util.clamp(d_f_target,0,800), 0, 800, this.topSpeed*0.4, this.topSpeed));
  133.        }else{
  134.          this.velocity.limit(this.topSpeed);
  135.        }
  136.     this.position.add(this.velocity);
  137.     // Reset acceleration for the next loop
  138.     this.acceleration.mult(0);
  139.     this.travelled_distance += old_position.dist(this.position);
  140.  
  141.       let wiggle =
  142.         Math.sin(frame * this.wiggle_speed) *
  143.         Util.map(this.velocity.mag(), 0, this.topSpeed, 0, this.size);
  144.       let w_a = this.velocity.heading() + Math.PI / 2;
  145.  
  146.       let w_x = this.position.+ Math.cos(w_a) * wiggle,
  147.         w_y = this.position.+ Math.sin(w_a) * wiggle;
  148.  
  149.       this.travelled_distance = 0;
  150.       let from = this.tail.length - 1,
  151.         to = 0;
  152.           let n = new Vector().fromAngle(Util.random(0,TWO_PI));
  153.       n.setMag(Math.random()*this.size);
  154.  
  155.      
  156.       var tail = { x: w_x+ n.x, y: w_y + n.y};
  157.       this.tail.splice(from, 1);
  158.       this.tail.splice(to, 0, tail);
  159.      
  160.   }
  161.   draw() {
  162.      
  163.         let energy = Util.map(this.velocity.mag(),0,this.topSpeed,0.1,1);
  164.  
  165.      
  166.     let color =
  167.       "hsl("+Math.sin((frame + this.blink_offset) * 0.1) * 360+",50%,"+
  168.          
  169.         Util.map(this.velocity.mag(),0,this.topSpeed,40,100) * this.alpha    
  170.     +"%)";
  171.     ctx.globalAlpha = this.alpha;
  172.  
  173.     ctx.strokeStyle = color;
  174.     for (let i = 0; i < this.tail.length - 1; i++) {
  175.       let t = this.tail[i],
  176.         next_t = this.tail[+ 1];
  177.       ctx.lineWidth = Util.map(i, 0, this.tail.length - 1, this.size, 1);
  178.       ctx.beginPath();
  179.       ctx.moveTo(t.x, t.y);
  180.       ctx.lineTo(next_t.x, next_t.y);
  181.       ctx.closePath();
  182.       ctx.stroke();
  183.     }
  184.      
  185.     let gradient_size = 140 * energy;var grd = ctx.createRadialGradient(
  186.   this.position.x,this.position., 5,
  187.   this.position.x,this.position.y, gradient_size);grd.addColorStop(0, "rgba(255,255,255,0.01)");grd.addColorStop(0.1, "rgba(255,120,200,0.02)");grd.addColorStop(0.9, "rgba(255,255,120,0)");grd.addColorStop(1, "rgba(0,0,0,0)");// Fill with gradientctx.fillStyle = grd;ctx.fillRect(this.position.x - gradient_size / 2 ,this.position.y - gradient_size / 2 , gradient_size, gradient_size); 
  188.      
  189.     ctx.globalAlpha = energy+0.2;
  190.     ctx.fillStyle = "white";
  191.     for(let i = 0; i < 4; i++){
  192.       let n = new Vector().fromAngle(Util.random(0,TWO_PI));
  193.       n.setMag(Math.random()*energy*100);
  194.       n.add(this.position);
  195.       ctx.beginPath();
  196.       ctx.arc(n.x,n.y,Math.random(),0,TWO_PI)
  197.       ctx.fill();
  198.     }
  199.      
  200.   }
  201.   addForce(vector) {
  202.     this.acceleration.add(vector);
  203.   }
  204.   avoid(others) {
  205.     others.forEach(other => {
  206.       if (other !== this) {
  207.         let dist = this.position.dist(other.position),
  208.           max_dist = this.zone + other.size;
  209.         if (max_dist - dist >= 0) {
  210.           let angle = other.position.angle(this.position);
  211.           let force = new Vector().fromAngle(angle);
  212.           force.setMag(Util.map(dist, 0, max_dist, 2, 0));
  213.           this.addForce(force);
  214.         }
  215.       }
  216.     });
  217.   }}let arrows = [];for (let i = 0; i < 100; i++) {
  218.   arrows.push(new Arrow(/ 2, H / 2, mouse));}let frame = 0;ctx.strokeStyle = "white";function loop() {
  219.   ctx.fillStyle="black";
  220.   ctx.globalCompositeOperation = "source-over";
  221.   ctx.globalAlpha = 0.2;
  222.   ctx.fillRect(0, 0, W, H);
  223.   ctx.globalAlpha = 1;
  224.   ctx.globalCompositeOperation = "lighter";
  225.   arrows.forEach(=> {
  226.     a.avoid(arrows);
  227.   });
  228.   arrows.forEach(=> {
  229.     a.render();
  230.   });
  231.   frame += 1;
  232.   requestAnimationFrame(loop);}ctx.lineCap = "round";ctx.lineJoin = "round";loop();


本文网址:https://www.zztuku.com/index.php/detail-9079.html
站长图库 - HTML5 canvas如何绘制酷炫能量线条效果(附代码)
申明:如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    PHP怎么实现加好友功能