JSFiddle - React, Tailwind, and code Playground
by Sergei Sokolov
HTML
<button id="btn-clear">Стереть следы</button>
<button id="btn-new">Новая фигура</button>
<br>
<canvas id="canvas" width="400" height="400"></canvas>
CSS
canvas {
border:1px solid grey;
}
JavaScript
/**
* для вопроса https://toster.ru/q/559159
*/
const canvas = document.getElementById('canvas');
const btn_c = document.getElementById('btn-clear');
const btn_n = document.getElementById('btn-new');
const ctx = canvas.getContext('2d');
let points = getPoints(5);
console.log(points);
plot(points);
//rays(points);
btn_c.addEventListener("click", e => {
ctx.clearRect(0,0,400,400);
plot(points);
});
btn_n.addEventListener("click", e => {
ctx.clearRect(0,0,400,400);
points = getPoints(5);
plot(points);
});
canvas.addEventListener("click", e => {
let rect = canvas.getBoundingClientRect();
let x = e.clientX - rect.left;
let y = e.clientY - rect.top;
zoomOut([x,y]);
});
function zoomOut(C) {
let k = 1, delta = 0.95, trails = 0;
function draw() {
k *= delta;
plot( scale( k, C, points));
if(trails++ < 50) window.requestAnimationFrame(draw);
}
draw();
}
function scale( k, center, points) {
return points.map( p => p.map( (x, i) => center[i] + k * (x - center[i])));
}
function getPoints(n) {
const da = 2 * Math.PI / n;
const p4 = Math.PI / 4;
return Array
.apply(null, { length:n })
.map((e, i) => {
let a = -p4 + da * i + da * Math.random();
let ta = Math.tan((a + p4) % (Math.PI / 2) - p4)
let cross;
if(a > -p4 && a <= p4) { // right
cross = [400, 200 - Math.round(ta * 200)];
} else if( a > p4 && a <= 3 * p4) { // top
cross = [200 + Math.round(ta * 200), 0];
} else if( a > 3 * p4 && a <= 5 * p4) { // left
cross = [0, 200 + Math.round(ta * 200)];
} else if( a > 5 * p4 && a <= 7 * p4) { // bottom
cross = [200 + Math.round(ta * 200), 400];
} else {
console.error('bad case. a = ', a);
}
return cross.map(x => 200 + Math.random() * (x - 200));
})
;
}
function plot(points) {
ctx.beginPath();
ctx.moveTo(...points[0]);
for(let i = 1; i < points.length; i++) {
ctx.lineTo(...points[i]);
}
...