js模拟重力拖拽动画效果代码

代码语言:html

所属分类:拖放

代码描述:js模拟重力拖拽动画效果代码,按住1实现慢镜头、按住2实现零重力,按住3实现反重力。

代码标签: 拖拽 动画 效果

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

<html>

<head>
    <meta charset="UTF-8">
    <style>
        * {
          margin: 0;
        }
         
        body {
          font-family: Helvetica, sans-serif;
          background:#1f1f1f;
        }
        
        #info {
          font-size: 22px;
          color: #ccc;
          position: absolute;
          z-index: -1;
          display: flex;
          flex-direction: column;
          width: 100vw;
          height: 100vh;
          justify-content: center;
          align-items: center;
          animation: fadeOut 1s forwards 3s;
        }
        
        #info > div {
          margin-top: -3em;
        }
        
        #info > div > div {
          margin-bottom: 0.4em;
        }
        
        code {
          color: #bbb;
          background: rgba(0, 0, 0, 0.07);
          padding: 0em 0.2em;
        }
    </style>

</head>

<body>
    <div id="info">
        <div>
            <div>用鼠标拖动</div>
            <div>按住
                <code>1</code>慢镜头.</div>
            <div>按住
                <code>2</code>零重力.</div>
            <div>按住
                <code>3</code> 反重力.</div>
        </div>
    </div>
    <canvas width="1047" height="646"></canvas>
    <script>
        const SPACING = 14;
        const ITERATIONS = 14;
        const MOUSE = SPACING * 5;
        let GRAVITY = 0.05;
        let SPEED = 1;
        
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');
        
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        
        const mouse = {
          x: 0,
          y: 0,
          px: 0,
          py: 0,
          points: [],
        };
        
        const clamp = function (val, min, max) {
          return Math.min(Math.max(val, min), max);
        };
        
        class Vector {
          constructor (x = 0, y = 0) {
            this.x = x;
            this.y = y;
          }
        
          get length () {
            return Math.sqrt(this.x * this.x + this.y * this.y);
          }
        
          add (v) {
            const p = v instanceof Vector;
            this.x += p ? v.x : v;
            this.y += p ? v.y : v;
            return this;
          }
        
          sub (v) {
            const p = v instanceof Vector;
            this.x -= p ? v.x : v;
            this.y -= p ? v.y : v;
            return this;
          }
        
          mul (v) {
            const p = v instanceof Vector;
            this.x *= p ? v.x : v;
            this.y *= p ? v.y : v;
            return this;
          }
        
          scale (x) {
            this.x *= x;
            this.y *= x;
            return this;
          }
        
          normalize () {
            const len = this.length;
            if (len > 0) {
              this.x /= len;
              this.y /= len;
            }
        
            return this;
          }
        
          distance (v) {
            const x = this.x - v.x;
            const y = this.y - v.y;
            return Math.sqrt(x * x + y * y);
          }
        
          static add (v1, v2) {
            const v = v2 instanceof Vector;
            return new Vector(
              v1.x + (v ? v2.x : v2),
              v1.y + (v ? v2.y : v2)
            );
          }
        
          static sub (v1, v2) {
            const v = v2 instanceof Vector;
            return new Vector(
              v1.x - (v ? v2.x : v2),
              v1.y - (v ? v2.y : v2)
            );
          }
        
          static mul (v1, v2) {
            const v = v2 instanceof Vector;
            return new Vector(
              v1.x * (v ? v2.x : v2),
              v1.y * (v ? v2.y : v2)
            );
          }
        
          static dot (v1, v2) {
            return v1.x * v2.x + v1.y * v2.y;
          }
        }
        
        const reactor = function (a, b, p) {
          const refA = Vector.add(a.toWorld(p), a.pos);
          const refB = Vector.add(b.toWorld(Vector.mul(p, -1)), b.pos);
        
          const diff = Vector.sub(refB, refA);
          const mid = Vector.add(refA, Vector.mul(diff, 0.5));
        
          const t = clamp(b.p - a.p, -Math.PI, Math.PI);
          a.torque += t;
          b.torque -= t;
        
          const mfc = 0.04;
          const tfc = 0.02;
          const mf = Vector.mul(diff, mfc);
          const tf = Vector.mul(diff, tfc);
          const dm = Vector.sub(b.vat(mid), a.vat(mid));
          mf.add(Vector.mul(dm, mfc));
          tf.add(Vector.mul(dm, tfc));
        
          a.addForce(mf, mid);
          b.addForce(Vector.mul(mf, -1), mid);
          a.addTorque(tf, mid);
          b.addTorque(Vector.mul(tf, -1), mid);
        };
        
        const allContraints = [];
        
        class Point {
          constructor (pos, square) {
            this.pos = pos;
            this.velocity = new Vector();
            this.force = new Vector();
        
            this.p = 0;
            this.w = 0;
            this.torque = 0;
            this.square = square;
          }
        
          update () {
            this.velocity.add(Vector.mul(this.force, SPEED));
        
            this.force = new Vector(0, GRAVITY / ITERATIONS);
        
            this.pos.add(Vector.mul(this.velocity, SPEED));
        
            const qPI = Math.PI / 4;
            this.w += this.torque / ((SPACING / 2) ** 2 / 2);
            this.w = clamp(this.w * SPEED, -qPI, qPI);
        
            this.p += this.w;
            this.torque = 0;
        
            mouse.points.includes(this) &&
              this.moveTo(mouse, this.mouseDiff);
          }
        
          toWorld (input) {
            return new Vector(
              -input.y * Math.sin(this.p) + input.x * Math.cos(this.p),
              input.y * Math.cos(this.p) + input.x * Math.sin(this.p)
            );
          }
        
          vat (R) {
            const dr = Vector.sub(R, this.pos);
            const vdr = this.w * dr.length;
        
            dr.normalize();
        
            return Vector.add(
              this.velocity,
              new Vector(vdr * -dr.y, vdr * dr.x)
            );
          }
        
          addForce (F) {
            this.force.add(F);
          }
        
          addTorque (F, R) {
            const arm = Vector.sub(R, this.pos);
            const torque = F.y * arm.x - F.x * arm.y;
            this.torque += torque;
          }
        
          moveTo (v, offset) {
            const targetX = v.x + offset.x;
            const targetY = v.y + offset.y;
            const strength = 0.001;
            t.........完整代码请登录后点击上方下载按钮下载查看

网友评论0