js实现canvas电流闪电放电动画效果代码

代码语言:html

所属分类:动画

代码描述:js实现canvas电流闪电放电动画效果代码,可调节闪电角度、速度、颜色、厚度及模糊度。

代码标签: canvas 闪电 放电 电流

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">





    <style>
        body {
            font-family: sans-serif;
            padding: 0;
            margin: 0;
            background-color: #222;
            overflow: hidden;
            -webkit-user-select: none;
               -moz-user-select: none;
                 -o-user-select: none;
                -ms-user-select: none;
                    user-select: none;
        }
        
        canvas {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>




</head>

<body>
    <canvas id='c'></canvas>

    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/simplex-noise.min.js"></script>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script>
    <script>
        /**
         * requestAnimationFrame
         */
        window.requestAnimationFrame = function () {
          return window.requestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.oRequestAnimationFrame ||
          window.msRequestAnimationFrame ||
          function (callback) {
            window.setTimeout(callback, 1000 / 60);
          };
        }();
        
        
        /**
         * Vector
         */
        function Vector(x, y) {
          this.x = x || 0;
          this.y = y || 0;
        }
        
        Vector.add = function (a, b) {
          return new Vector(a.x + b.x, a.y + b.y);
        };
        
        Vector.sub = function (a, b) {
          return new Vector(a.x - b.x, a.y - b.y);
        };
        
        Vector.prototype = {
          set: function (x, y) {
            if (typeof x === 'object') {
              y = x.y;
              x = x.x;
            }
            this.x = x || 0;
            this.y = y || 0;
            return this;
          },
        
          add: function (v) {
            this.x += v.x;
            this.y += v.y;
            return this;
          },
        
          sub: function (v) {
            this.x -= v.x;
            this.y -= v.y;
            return this;
          },
        
          scale: function (s) {
            this.x *= s;
            this.y *= s;
            return this;
          },
        
          length: function () {
            return Math.sqrt(this.x * this.x + this.y * this.y);
          },
        
          normalize: function () {
            var len = Math.sqrt(this.x * this.x + this.y * this.y);
            if (len) {
              this.x /= len;
              this.y /= len;
            }
            return this;
          },
        
          angle: function () {
            return Math.atan2(this.y, this.x);
          },
        
          distanceTo: function (v) {
            var dx = v.x - this.x,
            dy = v.y - this.y;
            return Math.sqrt(dx * dx + dy * dy);
          },
        
          distanceToSq: function (v) {
            var dx = v.x - this.x,
            dy = v.y - this.y;
            return dx * dx + dy * dy;
          },
        
          clone: function () {
            return new Vector(this.x, this.y);
          } };
        
        
        
        /**
         * Point
         */
        function Point(x, y, radius) {
          Vector.call(this, x, y);
        
          this.radius = radius || 7;
        
          this.vec = new Vector(random(1, -1), random(1, -1)).normalize();
          this._easeRadius = this.radius;
          this._currentRadius = this.radius;
        
        }
        
        Point.prototype = function (o) {
          var s = new Vector(0, 0),p;
          for (p in o) {
            s[p] = o[p];
          }
          return s;
        }({
          color: 'rgb(255, 255, 255)',
          dragging: false,
          _latestDrag: null,
        
          update: function (points, bounds) {
            this._currentRadius = random(this._easeRadius, this._easeRadius * 0.35);
            this._easeRadius += (this.radius - this._easeRadius) * 0.1;
        
            if (this.dragging) return;
        
            var vec = this.vec,
            i,len,p,d;
        
            for (i = 0, len = points.length; i < len; i++) {
              p = points[i];
              if (p !== this) {
                d = this.distanceToSq(p);
                if (d < 90000) {
                  vec.add(Vector.sub(this, p).normalize().scale(0.03));
                } else if (d > 250000) {
                  vec.add(Vector.sub(p, this).normalize().scale(0.015));
                }
              }
            }
        
            if (vec.length() > 3) vec.normalize().scale(3);
        
            this.add(vec);
        
            if (this.x < bounds.x) {
              this.x = bounds.x;
              if (vec.x < 0) vec.x *= -1;
        
            } else if (this.x > bounds.right) {
              this.x = bounds.right;
              if (vec.x > 0) vec.x *= -1;
            }
        
            if (this.y < bounds.y) {
              this.y = bounds.y;
              if (vec.y < 0) vec.y *= -1;
        
            } else if (this.y > bounds.bottom) {
              this.y = bounds.bottom;
              if (vec.y > 0) vec.y *= -1;
            }
          },
        
          hitTest: function (p) {
            if (this.distanceToSq(p) < 900) {
              this._easeRadius = this.radius * 2.5;
              return true;
            }
            return false;
          },
        
          startDrag: function () {
            this.dragging = true;
            this.vec.set(0, 0);
            this._latestDrag = new Vector().set(this);
          },
        
          drag: function (p) {
            this._latestDrag.set(this);
            this.set(p);
          },
        
          endDrag: function () {
            this.vec = Vector.sub(this, this._latestDrag);
            this.dragging = false;
          },
        
          draw: function (ctx) {
            ctx.save();
            ctx.fillStyle = this.color;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this._currentRadius, 0, Math.PI * 2, false);
            ctx.fill();
            ctx.shadowBlur = 20;
            ctx.shadowColor = this.color;
            ctx.fillStyle = 'rgba(0, 0, 0, 1)';
            ctx.globalCompositeOperation = 'lighter';
            ctx.beginPath();
            ctx.arc(this.x, this.y, this._currentRadius, 0, Math.PI * 2, false);
            ctx.fill();
            ctx.restore();
          } });
        
        
        
        /**
         * Lightning
         */
        function Lightning(startPoint, endPoint, step) {
          this.startPoint = startPoint || new Vector();
          this.endPoint = endPoint || new Vector();
          this.step = step || 45;
        
          this.children = [];
        }
        
        Lightning.prototype = {
          color: 'rgba(255, 255, 255, 1)',
          speed: 0.025,
          amplitude: 1,
          lineWidth: 5,
          blur: 50,
          blurColor: 'rgba(255, 255, 255, 0.5)',
          points: null,
          off: 0,
          _simplexNoise: new SimplexNoise(),
          // Case by child
          parent: null,
          startStep: 0,
          endStep: 0,
        
          length: function () {
            return this.startPoint.distanceTo(this.endPoint);
          },
        
          getChildNum: function () {
            return children.length;
          },
        
          setChildNum: function (num) {
            var children = this.children,child,
            i,len;
        
            len = this.children.length;
        
            if (len > num) {
              for (i = num; i < len; i++) {
                children[i].dispose();
              }
              children.splice(num, len - num);
        
            } else {
              for (i = len; i < num; i++) {
                child = new Lightning();
                child._setAsChild(this);
                children.push(child);
              }
            }
          },
        
          update: function () {
            var startPoint = this.startPoint,
            endPoint = this.endPoint,
            length,normal,radian,sinv,cosv,
            points,off,waveWidth,n,av,ax,ay,bv,bx,by,m,x,y,
            children,child,
            i,len;
        
            if (this.parent) {
              if (this.endStep > this.parent.step) {
                this._updateStepsByParent();
              }
        
              startPoint.set(this.parent.points[this.startStep]);
              endPoint.set(this.parent.points[this.endStep]);
            }
        
            length = this.length();
            normal = Vector.sub(endPoint, startPoint).normalize().scale(length / this.step);
            radian = normal.angle();
            sinv = Math.sin(radian);
            cosv = Math.cos(radian);
        
            points = this.points = [];
            off = this.off += random(this.speed, this.speed * 0.2);
            waveWidth = (this.parent ? length * 1.5 : length) * this.amplitude;
            if (waveWidth > 750) waveWidth = 750;
        
            for (i = 0, len = this.step + 1; i < len; i++) {
              n = i / 60;
              av = waveWidth * this._noise(n - off, 0) * 0.5;
              ax = sinv * av;
              ay = cosv * av;
        
              bv = waveWidth * this._noise(n + off, 0) * 0.5;
             .........完整代码请登录后点击上方下载按钮下载查看

网友评论0