js实现动感线条曲线动画效果代码

代码语言:html

所属分类:动画

代码描述:js实现动感线条曲线动画效果代码

代码标签: 线条 曲线 动画 效果

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

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>

    <style>
        canvas.drawer {
        	position:fixed;
        	top:0px;
        	left:0px;
        	width:100vw;
        	height:100vh;
        }
    </style>

</head>

<body>

    <div></div>

    <script>
        'use strict';
        
        var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
        
        function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
        
        function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
        
        function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
        
        var initialise = function initialise() {
          var application = new Application();
          // application.scaleFactor = 2;
          application.clearOnRedraw = Application.FADE;
          application.fadeColour = 'rgba(0,0,0,.03)';
          application.fillColour = 'rgba(30,30,30,1)';
          application.onResize();
          var vfield = new VectorField();
          vfield.scale = 300;
          vfield.amplitude = 40;
          // vfield.debug = true;
        
          application.addActor(vfield);
        
          var maxNum = 1000;
          var num = 0;
        
          var addTracer = function addTracer(position, colour) {
            if (num > maxNum) return;
        
            num++;
        
            var tracer = new BranchTracer(position.x, position.y);
            tracer.field = vfield;
            var momentum = new Vector(Math.random(), Math.random());
            momentum.length = Math.random() * 2;
            tracer.momentum = momentum;
            tracer.friction = 0.97;
        
            if (colour) {
              tracer.colour = colour;
            } else {
              tracer.colour = 'RGBA(' + Math.round(Math.random() * 255) + ',' + 100 + Math.round(Math.random() * 155) + ',255,0.2)';
            }
        
            application.addActor(tracer);
            return tracer;
          };
          var seed = addTracer(new Vector(window.innerWidth / 2, window.innerHeight / 2), 'RGBA(255, 100, 100, 0.8)');
          seed.branchChance = 5;
          seed.friction = 0.985;
          seed.onBranch = addTracer;
        
          setInterval(function () {
            vfield.z = Math.random() * 10000;
          }, 10000);
        
          var stage = application.stage;
          document.body.appendChild(stage);
          application.onPointerMove({ clientX: window.innerWidth / 2, clientY: window.innerHeight / 2 });
          application.render();
          application.animating = true;
        
          // application.runFor(60 * 120);
        
          return;
        };
        
        var Application = function () {
          function Application() {
            _classCallCheck(this, Application);
        
            this.stage = document.createElement('canvas');
        
            this.animate = this.animate.bind(this);
        
            this.onResize = this.onResize.bind(this);
            this.onPointerDown = this.onPointerDown.bind(this);
            this.onPointerup = this.onPointerup.bind(this);
            this.onPointerMove = this.onPointerMove.bind(this);
        
            this.initialiseEvents();
          }
        
          Application.prototype.initialiseEvents = function initialiseEvents() {
            window.addEventListener('resize', this.onResize, false);
            document.addEventListener('pointerdown', this.onPointerDown, false);
            document.addEventListener('pointerup', this.onPointerup, false);
            document.addEventListener('pointermove', this.onPointerMove, false);
          };
        
          Application.prototype.deInitialiseEvents = function deInitialiseEvents() {
            window.removeEventListener('resize', this.onResize, false);
            document.removeEventListener('pointerdown', this.onPointerDown, false);
            document.removeEventListener('pointerup', this.onPointerup, false);
            document.removeEventListener('pointermove', this.onPointerMove, false);
          };
        
          Application.prototype.addActor = function addActor(actor) {
            if (actor instanceof Actor) {
              this.actors.push(actor);
            }
          };
        
          Application.prototype.runFor = function runFor(ticks) {
            var interval = 1 / 60;
            var i = 0;
        
            for (i; i < ticks; i++) {
              this.triggerEvent('application-animate', { now: this.now, then: this.then, interval: interval, application: this });
        
              this.render();
            }
          };
        
          Application.prototype.animate = function animate() {
            this.now = Date.now();
            var interval = this.now - this.then;
        
            this.triggerEvent('application-animate', { now: this.now, then: this.then, interval: interval, application: this });
        
            this.render();
        
            this.then = this.now;
        
            if (this.animating) {
              requestAnimationFrame(this.animate);
            }
          };
        
          Application.prototype.render = function render() {
            var _this = this;
        
            var dims = this.dimensions;
        
            if (this.clearOnRedraw == Application.CLEAR) {
              this.context.clearRect(0, 0, dims.width, dims.height);
            } else if (this.clearOnRedraw == Application.FADE) {
              this.context.fillStyle = this.fadeColour;
              this.context.fillRect(0, 0, dims.width, dims.height);
            }
        
            this.actors.forEach(function (actor) {
              actor.render(_this);
            });
          };
        
          Application.prototype.onResize = function onResize(e) {
            console.log('resize');
            this.dimensions = new Vector(window.innerWidth, window.innerHeight);
          };
        
          Application.prototype.onPointerDown = function onPointerDown(e) {};
        
          Application.prototype.onPointerup = function onPointerup(e) {};
        
          Application.prototype.onPointerMove = function onPointerMove(e) {
            var pointer = new Vector(e.clientX, e.clientY);
            this.triggerEvent('application-pointermove', { pointer: pointer });
          };
        
          Application.prototype.triggerEvent = function triggerEvent(event, data) {
            if (window.CustomEvent) {
              var event = new CustomEvent(event, { detail: data });
            } else {
              var event = document.createEvent('CustomEvent');
              event.initCustomEvent(event, true, true, data);
            }
        
            document.dispatchEvent(event);
          };
        
          _createClass(Application, [{
            key: 'actors',
            get: function get() {
              if (!this._actors) this._actors = [];
        
              return this._actors;
            }
          }, {
            key: 'scaleFactor',
            set: function set(value) {
              if (value >= 1) {
                this._scaleFactor = value;
                this.onResize();
              }
            },
            get: function get() {
              return this._scaleFactor || 1;
            }
          }, {
            key: 'dimensions',
            set: function set(value) {
              if (value instanceof Vector) {
                value.scale(this.scaleFactor);
                this.stage.width = value.width;
                this.stage.height = value.height;
                this.context.fillStyle = this.fillColour;
                this.context.fillRect(0, 0, this.dimensions.width, this.dimensions.height);
                this._dimensions = value;
              }
            },
            get: function get() {
              return this._dimensions || new Vector(0, 0);
            }
          }, {
            key: 'stage',
            set: function set(value) {
              if (value instanceof HTMLCanvasElement) {
                value.className = this.className;
                this._stage = value;
                this.context = this.stage.getContext('2d');
                this.context.fillStyle = this.fillColour;
                this.context.fillRect(0, 0, this.dimensions.width, this.dimensions.height);
                this.onResize();
              }
            },
            get: function get() {
              return this._stage || null;
            }
          }, {
            key: 'now',
            set: function set(value) {
              if (!isNaN(value)) this._now = value;
            },
            get: function get() {
              return this._now || 0;
            }
          }, {
            key: 'then',
            set: function set(value) {
              if (!isNaN(value)) this._then = value;
            },
            get: function get() {
              return this._then || 0;
            }
          }, {
            key: 'animating',
            set: function set(value) {
              if (value === true && this.animating !== true) {
                this._animating = true;
        
                this.now = Date.now();
                this.then = this.now;
        
                requestAnimationFrame(this.animate);
              }
            },
            get: function get() {
              return this._animating === true;
            }
          }, {
            key: 'fadeColour',
            set: function set(value) {
              this._fadeColour = value;
            },
            get: function get() {
              return this._fadeColour || 'rgba(255,255,255,.5)';
            }
          }, {
            key: 'fillColour',
            set: function set(value) {
              this._fillColour = value;
            },
            get: function get() {
              return this._fillColour || 'rgba(255,255,255,1)';
            }
          }, {
            key: 'clearOnRedraw',
            set: function set(value) {
              if ([Application.NOCLEAR, Application.CLEAR, Application.FADE].indexOf(value) > -1) {
                this._clearOnRedraw = value;
              }
            },
            get: function get() {
              return this._clearOnRedraw || Application.NOCLEAR;
            }
          }, {
            key: 'className',
            get: function get() {
              return 'drawer';
            }
          }]);
        
          return Application;
        }();
        
        Application.NOCLEAR = 0;
        Application.CLEAR = 1;
        Application.FADE = 2;
        
        var Actor = function () {
          function Actor(x, y, w, h) {
            _classCallCheck(this, Actor);
        
            this.dimensions = new Vector(w, h);
            this.position = new Vector(x, y);
          }
        
          Actor.prototype.render = function render() {};
        
          _createClass(Actor, [{
            key: 'dimensions',
            set: function set(value) {
              if (value instanceof Vector) this._dimensions = value;
            },
            get: function get() {
              return this._dimensions || new Vector(0, 0);
            }
          }, {
            key: 'position',
            set: function set(value) {
              if (value instanceof Vector) this._position = value;
            },
            get: function get() {
              return this._position || new Vector(0, 0);
            }
          }]);
        
          return Actor;
        }();
        
        var VectorField = function (_Actor) {
          _inherits(VectorField, _Actor);
        
          function VectorField() {
            var x = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
            var y = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
            var w = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2];
            var h = arguments.length <= 3 || arguments[3] === undefined ? 0 : arguments[3];
        
            _classCallCheck(this, VectorField);
        
            var _this2 = _possibleConstructorReturn(this, _Actor.call(this, x, y, w, h));
        
            _this2.noise = new Noise();
        
            _this2.helpers = [];
        
            _this2.mousepos = new Vector(0, 0);
        
            _this2.onResize = _this2.onResize.bind(_this2);
            _this2.onPointerMove = _this2.onPointerMove.bind(_this2);
        
            // document.addEventListener('application-pointermove', this.onPointerMove, false);
            window.addEventListener('resize', _this2.onResize);
            _this2.onResize();
            return _this2;
          }
        
          VectorField.prototype.render = function render(application) {
            this.helpers.forEach(function (helper) {
              helper.render(application);
            });
          };
        
          VectorField.prototype.preDraw = function preDraw() {};
        
          VectorField.prototype.postDraw = function postDraw() {};
        
          VectorField.prototype.solveForPosition = function solveForPosition(v) {
            if (!v instanceof Vector) return;
        
            v = v.clone();
            v.x -= window.innerWidth / 2;
            v.y -= window.innerHeight / 2;
        
            var scale = this.scale;
            var amp = this.amplitude;
        
            //     let waveform = new Vector(Math.cos(v.x / scale) * amp, Math.sin(v.y / scale) * amp);
            //     return new Vector(waveform.y - waveform.x, -waveform.x - waveform.y);
        
            var envelope = this.amplitude;
        
            var noise = this.noise.noise(v.x / scale, v.y / scale, this.z) * scale;
            if (noise > envelope) noise = envelope;
            if (noise < -envelope) noise = -envelope;
            var noise1 = this.noise.noise(v.y / scale, v.x / scale, this.z / scale);
            var transV = new Vector(1, 0);
            transV.length = noise;
            transV.angle = noise1 * 10;
            return transV;
        
            var transv = v.subtractNew(this.mousepos);
            transv = new Vector(transv.y - transv.x, -transv.x - transv.y);
        
            transv.length *= 0.03;
            if (transv.length > 50) {
              transv.length = 50;
            }
            transv.length -= 50;
            transv.length *= -1;
        
            return transv;
          };
        
          VectorField.prototype.onPointerMove = function onPointerMove(e) {
            var _this3 = this;
        
            this.mousepos = e.detail.pointer;
        
            this.helpers.forEach(function (helper) {
              helper.vector = _this3.solveForPosition(helper.position);
            });
          };
        
          VectorField.prototype.onResize = function onResize(e) {
            if (!this.debug) return;
        
            this.helpers.forEach(function (helper) {
              helper.destroy();
            });
            this.helpers = [];
        
            var w = this.sampleWidth;
            var curpos = new Vector(0, 0);
        
            while (curpos.y < window.innerHeight + w) {
              curpos.x = 0;
              while (curpos.x < window.innerWidth + w) {
                this.helpers.push(new Arrow(curpos.x, curpos.y, 10, 10, this.solveForPosition(curpos)));
                curpos.x += w;
              }
              curpos.y += w;
            }
          };
        
          _createClass(VectorField, [{
            key: 'scale',
            set: function set(value) {
              if (value > 0) {
                this._scale = value;
              }
            },
            get: function get() {
              return this._scale || 500;
            }
          }, {
            key: 'amplitude',
            set: function set(value) {
              if (value > 0) {
                this._amplitude = value;
              }
            },
            get: function get() {
              return this._amplitude || 10;
            }
          }, {
            key: 'sampleWidth',
            set: function set(value) {
              if (value > 0) this._sampleWidth = value;
            },
            get: function get() {
              return this._sampleWidth || 30;
            }
          }, {
            key: 'z',
            set: function set(value) {
              if (value > 0) this._z = value;
            },
            get: function get() {
              return this._z || 30;
            }
          }, {
            key: 'mousepos',
            set: function set(value) {
              if (value instanceof Vector) this._mousepos = value;
            },
            get: function get() {
              return this._mousepos || new Vector(0, 0);
            }
          }, {
            key: 'debug',
            set: function set(value) {
              this._debug = value === true;
            },
            get: function get() {
              return this._debug === true;
            }
          }, {
            key: 'strokeStyle',
            get: function get() {
              return 'black';
            }
          }, {
            key: 'strokeWidth',
            get: function get() {
              return 0;
            }
          }]);
        
          return VectorField;
        }(Actor);
        
        var Tracer = function (_Actor2) {
          _inherits(Tracer, _Actor2);
        
          function Tracer() {
            var x = arguments.length <= 0 || arguments[0] === undefined ? 200 : arguments[0];
            var y = arguments.length <= 1 || arguments[1] === undefined ? 200 : arguments[1];
            var w = arguments.length <= 2 || arguments[2] === undefined ? 40 : arguments[2];
            var h = arguments.length <= 3 || arguments[3] === undefined ? 20 : arguments[3];
        
            _classCallCheck(this, Tracer);
        
            var _this4 = _possibleConstructorReturn(this, _Actor2.call(this, x, y, w, h));
        
            _this4.onAnimate = _this4.onAnimate.bind(_this4);
        
            document.addEventListener('application-animate', _this4.onAnimate, false);
        
            _this4.friction = 0.99;
            _this4.momentum = new Vector(1, 0);
            return _this4;
          }
        
          Tracer.prototype.onAnimate = function onAnimate(e) {
            var force = this.field.solveForPosition(this.position).multiplyScalar(0.01);
            var app = e.detail.application;
            var oldPosition = this.position.clone();
            var draw = true;
        
            this.momentum.add(force);
            this.momentum.multiplyScalar(this.friction);
            if (this.momentum.length < 1) this.momentum.length = 1;
            if (this.momentum.length > 20) this.momentum.length = 20;
            this.position.add(this.momentum);
        
            if (this.position.x < -this.dimensions.width) {
              this.position.x = app.dimensions.width + this.dimensions.width;
              draw = false;
            } else if (this.position.x > app.dimensions.width + this.dimensions.width) {
              this.position.x = -this.dimensions.width;
              draw = false;
            }
            if (this.position.y < -this.dimensions.height) {
              this.position.y = app.dimensions.height + this.dimensions.height;
              draw = false;
            } else if (this.position.y > app.dimensions.height + this.dimensions.height) {
              this.position.y = -this.dimensions.height;
              draw = false;
            }
        
            if (draw) {
              var context = app.context;
              var opacity = Math.abs((this.momentum.length - 10) / 20);
              // console.log(opacity, this.momentum.length);
              // console.log(oldPosition, this.position);
        
              context.beginPath();
              context.lineWidth = this.momentum.length / 2;
              context.strokeStyle = this.colour;
              context.moveTo(oldPosition.x, oldPosition.y);
              context.lineTo(this.position.x, this.position.y);
              context.stroke();
            }
          };
        
          _createClass(Tracer, [{
            key: 'colour',
            set: function set(value) {
              this._colour = value;
            },
            get: function get() {
              return this._colour || 'RGBA(255,255,255,0.1)';
            }
          }]);
        
          return Tracer;
        }(Actor);
        
        var BranchTracer = function (_Tracer) {
          _inherits(BranchTracer, _Tracer);
        
          function BranchTracer() {
            _classCallCheck(this, BranchTracer);
        
            return _possibleConstructorReturn(this, _Tracer.apply(this, arguments));
          }
        
          BranchTracer.prototype.onAnimate = function onAnimate(e) {
            _Tracer.prototype.onAnimate.call(this, e);
        
            if (Math.random() * 100 < this.branchChance) {
              this.onBranch(this.position);
            }
          };
        
          _createClass(BranchTracer, [{
            key: 'onBranch',
            set: function set(value) {
              if (typeof value == 'function') this._onBranch = value.bind(this);
            },
            get: function get() {
              return this._onBranch || function () {};
            }
          }, {
            key: 'branchChance',
            set: function set(value) {
              if (value > 0 && value <= 100) this._branchChance = value;
            },
            get: function get() {
              return this._branchChance || 0.2;
            }
          }]);
        
          return BranchTracer;
        }(Tracer);
        
        var Noise = function () {
          function Noise(r) {
            _classCallCheck(this, Noise);
        
            if (r == undefined) r = Math;
            this.grad3 = [[1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0], [1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1], [0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1]];
            this.p = [];
            for (var i = 0; i < 256; i++) {
              this.p[i] = Math.floor(r.random() * 256);
            }
            // To remove the need for index wrapping, double the permutation table length
            this.perm = [];
            for (var i = 0; i < 512; i++) {
              this.perm[i] = this.p[i & 255];
            }
          }
        
          Noise.prototype.dot = function dot(g, x, y, z) {
            return g[0] * x + g[1] * y + g[2] * z;
          };
        
          Noise.prototype.mix = function mix(a, b, t) {
            return (1.0 - t) * a + t * b;
          };
        
          Noise.prototype.fade = function fade(t) {
            return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
          };
        
          Noise.prototype.noise = function noise(x, y, z) {
            // Find unit grid cell containing point
            var X = Math.floor(x);
            var Y = Math.floor(y);
            var Z = Math.floor(z);
        
            // Get relative xyz coordinates of point within that cell
            x = x - X;
            y = y - Y;
            z = z - Z;
        
            // Wrap the integer cells at 255 (smaller integer period can be introduced here)
            X = X & 255;
            Y = Y & 255;
            Z = Z & 255;
        
            // Calculate a set of eight hashed gradient indices
            var gi000 = this.perm[X + this.perm[Y + this.perm[Z]]] % 12;
            .........完整代码请登录后点击上方下载按钮下载查看

网友评论0