canvas动画 (二)

709 阅读1分钟

1、非弹性碰撞

非弹性碰撞指的是在物体碰撞过程中,物体运动方向(速度方向)瞬间发生改变,现实情况状态下,碰撞之后动能会发生损失,相应的速度也会变小,如果不是重力加速运动,加速度大小也会相应减少

<template>
	<div id="app">
		<canvas id="canvas"></canvas>
	</div>
</template>
<script>
	export default {
  name: "App",
  mounted() {
    const eleCvas = document.getElementById("canvas");
    const cxt = eleCvas.getContext("2d");

    //初始化数据
    //Y轴初始速度为0,重力加速度为0.2,反弹系数为-0.8
    let vy = 0;
    const gravity = 0.2;
    const bounce = -0.8;
    const r = 10;    let x = eleCvas.width/2 , y = 0;
    cxt.fillStyle = "red";
    (function drawFrame() {
      y += vy;
      //边界检测
      if (y > eleCvas.height - r) {
          y = eleCvas.height - r;
          //速度反向并且减小
          vy = vy * bounce;
          // 处理无限循环
          if (vy > -0.2) {
            return 
          }
      }
      cxt.clearRect(0, 0, eleCvas.width, eleCvas.height);
      window.requestAnimationFrame(drawFrame);
      cxt.beginPath();
      cxt.arc(x, y, r, 0, (360 * Math.PI) / 180, true);
      cxt.closePath();
      cxt.fill();
      vy += gravity;
    })();
  }
};
</script>

<style>
	#app {
		text-align: center;
	}
	canvas {
		border: 1px solid red;
	}
</style>

总结: v = -fv;a = -fa;v:速度a:加速度f:动能衰减率(0<f<1)

2、弹性碰撞

弹性碰撞指的是物体在碰撞过程中,物体运动方向(速度方向)瞬间发生改变,碰撞之后动能不会发生损失

<template>
  <div id="app">
    <canvas id="canvas"></canvas>
  </div>
</template>

<script>
  // 小球
class Ball {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.radius = 15;
  }
  draw(cxt) {
    cxt.save();
    cxt.translate(this.x, this.y);
    cxt.fillStyle = "red";
    cxt.beginPath();
    cxt.arc(0, 0, this.radius, 0, Math.PI * 2);
    cxt.fill();
    cxt.restore();
  }
}
// 弹簧
export default {
  name: "App",
  mounted() {
    const eleCvas = document.getElementById("canvas");
    const cxt = eleCvas.getContext("2d");
    const ball = new Ball();
    let vx = 3;
    let vy = 2;
    ball.x = eleCvas.width / 2;
    ball.y = eleCvas.height / 2;
    const {width, height} = eleCvas;
    (function drawFrame() {
      window.requestAnimationFrame(drawFrame);
      cxt.clearRect(0, 0, width,height);
      ball.x += vx;
      ball.y += vy;
      // 边界处理
      if (ball.x > width - ball.radius) {
        ball.x = width - ball.radius;
        vx = -vx;
      }
      if (ball.x < ball.radius) {
        ball.x = ball.radius;
        vx = -vx;
      }
      if (ball.y > height - ball.radius) {
        ball.y = height - ball.radius;
        vy = -vy;
      }
      if (ball.y < ball.radius) {
        ball.y = ball.radius;
        vy = -vy;
      }
      ball.draw(cxt);
    })();
  }
};
</script>
<style>
#app {
  text-align: center;
}
canvas {
  border: 1px solid red;
}
</style>

总结:v = -v;a = -a;v:速度a:加速度

3、胡克定律(弹簧)

胡克定律F=kX 方向沿恢复形变方向 k:劲度系数(N/m) X:形变量(m)

<template>
  <div id="app">
    <canvas id="canvas"></canvas>
  </div>
</template>
<script>
  // 小球
class Ball {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.radius = 15;
  }
  draw(cxt) {
    cxt.save();
    cxt.translate(this.x, this.y);
    cxt.fillStyle = "red";
    cxt.beginPath();
    cxt.arc(0, 0, this.radius, 0, Math.PI * 2);
    cxt.fill();
    cxt.restore();
  }
}
// 弹簧
class Spring {
  constructor(length) {
    // 弹簧底座位置坐标
    this.x = 0;
    this.y = 0;
    this.angle = 0;
    // 弹簧长度
    this.length = length;
  }
  draw(cxt) {
    cxt.save();
    cxt.translate(this.x, this.y);
    cxt.rotate(this.angle);
    cxt.strokeStyle = "green";
    cxt.beginPath();
    cxt.moveTo(0, 0);
    var n = 20; // 上下峰值总个数
    var h = 20; // 底部直线长度
    var d = (this.length - 2 * h) / n;
    cxt.lineTo(h, 0);
    for (var i = 0; i < n; i++) {
      var dir = i % 2 == 0 ? 1 : -1;
      cxt.quadraticCurveTo(h + d * (i + 0.5), 20 * dir, h + d * (i + 1), 0);
    }
    cxt.lineTo(this.length, 0);
    cxt.stroke();
    cxt.restore();
  }
}
export default {
  name: "App",
  mounted() {
    const eleCvas = document.getElementById("canvas");
    const cxt = eleCvas.getContext("2d");
    // 初始弹簧长度
    const initLength = 200;
    // 振幅
    const amplitude = 120;
    const k = 0.01;
    const spring = new Spring(initLength);
    const ball = new Ball();
    spring.x = 0;
    spring.y = eleCvas.height / 2;
    ball.x = eleCvas.width / 2;
    ball.y = eleCvas.height / 2;

    ball.x += amplitude;
    var vx = 0;
    (function drawFrame() {
      window.requestAnimationFrame(drawFrame);
      cxt.clearRect(0, 0, eleCvas.width, eleCvas.height);
      var x = ball.x - spring.x - initLength;
      // k 劲度系数 x 形变量(m) 又力为 f = ma 当m为1时 f = a; 这样力可以做为加速度使用
      var f = -k * x;
      vx += f;
      // 定义时间为1 则得到下面球的位置
      ball.x += vx;
      spring.length = ball.x - spring.x;
      spring.draw(cxt);
      ball.draw(cxt);
    })();
  }
};
</script>
<style>
#app {
  text-align: center;
}
canvas {
  border: 1px solid red;
}
</style>

总结:f = -k * x; vx += f; 这里关键是力和胡克定律公式通过 求解代数方程的方式得到代码模拟公式

相关