Skip to content

Instantly share code, notes, and snippets.

@mutoo
Created July 18, 2020 12:57
Show Gist options
  • Save mutoo/bca0c3f3de86f8079975a85fe120f31c to your computer and use it in GitHub Desktop.
Save mutoo/bca0c3f3de86f8079975a85fe120f31c to your computer and use it in GitHub Desktop.
use wander(steering behaviors) as smooth rotation
<canvas id="stage"></canvas>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
<script>
const stg = document.getElementById('stage');
const ctx = stg.getContext('2d');
stg.width = window.innerWidth;
stg.height = window.innerHeight;
const circle = (x, y, r = 10) => {
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();
}
const count = 50;
const center = [stg.width / 2, stg.height / 2];
const target = [1, 0];
const pos = [center];
for (let i = 1; i < count; i++) {
pos.push([stg.width * Math.random(), stg.height * Math.random()]);
}
const R = 50;
const r = 3;
let alpha = 0;
let theta = 0;
let ct, st, Rx, Ry;
const dist = 10;
const update = () => {
theta = Math.atan2(pos[1][1] - pos[0][1], pos[1][0] - pos[0][0]);
alpha = alpha + (Math.random() * 2 - 1) * Math.PI / 16;
const rx = Math.cos(alpha) * r + R;
const ry = Math.sin(alpha) * r;
ct = Math.cos(theta);
st = Math.sin(theta);
Rx = ct * rx - st * ry;
Ry = st * rx + ct * ry;
const dr = Math.sqrt(rx * rx, ry * ry);
target[0] = Rx / dr * dist;
target[1] = Ry / dr * dist;
const dx = target[0];
const dy = target[1];
for (let i = 1; i < count; i++) {
let [x, y] = pos[i];
const [px, py] = pos[i - 1];
const tx = px + dx
const ty = py + dy;
x = x + (tx - x) / (5 + i / 2);
y = y + (ty - y) / (5 + i / 2);
pos[i][0] = x;
pos[i][1] = y;
}
}
const render = () => {
// ctx.clearRect(0, 0, stg.width, stg.height);
ctx.fillStyle = 'rgba(255,255,255,0.1)'
ctx.fillRect(0, 0, stg.width, stg.height)
ctx.fillStyle = 'rgba(0,0,0,1)'
for (let i = 0; i < count; i++) {
const [x, y] = pos[i];
circle(x, y, 10);
}
ctx.strokeStyle = 'rgb(255,0,0)';
ctx.beginPath();
ctx.moveTo(pos[0][0], pos[0][1]);
ctx.lineTo(pos[0][0] + ct * R, pos[0][1] + st * R);
ctx.lineTo(pos[0][0] + Rx, pos[0][1] + Ry);
ctx.stroke();
}
const loop = () => {
window.requestAnimationFrame(loop);
update();
render();
}
loop();
window.addEventListener('resize', () => {
stg.width = window.innerWidth;
stg.height = window.innerHeight;
pos[0] = [stg.width / 2, stg.height / 2];
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment