Кривая безье через массив точек с анимацией
Кривая безье через массив точек с анимацией
by twobomb three
HTML
<button id="random">Мне повезёт!</button>
<button id="clear">Очистить</button>
<canvas id="myCanvas"></canvas>
CSS
body,html{
height:100%;
}
#random{
position:absolute;
top:20px;
}
#clear{
position:absolute;
top:40px;
}
JavaScript
var canvas = document.querySelector("#myCanvas");
var ctx = canvas.getContext("2d");
var ctxW,ctxH,currentAnimId = 0;
canvas.width = ctxW = document.body.offsetWidth;
canvas.height = ctxH =document.body.offsetHeight;
var dots = [];
document.querySelector("#clear").addEventListener("click",()=>{
dots = [];
runAnimation();
});
document.querySelector("#random").addEventListener("click",()=>{//Рандомно расставить точки
var rand = (min,max)=>{ return Math.floor(min + max *Math.random())};
var n = rand(5,10);
dots = [];
while(n--)
dots.push([rand(0,canvas.width),rand(0,canvas.height)]);
runAnimation();
});
document.querySelector("#random").dispatchEvent(new Event("click"));
canvas.addEventListener("mousedown",function(e){
dots.push([e.offsetX,e.offsetY]);
runAnimation();
});
function runAnimation(){
currentAnimId++;
let animId = currentAnimId;
var step = 0.05;//Шаг анимации, чем меньше тем плавнее линии
let iTo = 0,tTo = 0;
(function anim(){
draw(iTo,tTo,step);
tTo+=step;
if(tTo>1){
tTo = 0;
iTo++;
}
if(iTo >= dots.length - 1){
draw(dots.length - 2,1,step);
return;
}
if(currentAnimId == animId)
setTimeout(anim,1000/60);
})();
}
function draw(iTo, tTo, stepAnim){
ctx.clearRect(0,0,ctxW,ctxH);
ctx.fillText("Кликай по канвасу",10,10)
ctx.lineWidth = 2;
for(var i = 0; i < dots.length;i++){
ctx.fillStyle = i>=iTo+1 && !(iTo == dots.length-2 && tTo == 1)?"red":"blue";
ctx.beginPath();
ctx.arc(dots[i][0],dots[i][1],10,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
if(dots.length >= 2){
for(var i = 0; i <= iTo;i++){
var inxLast = i > 0?i-1:0;//Индекс предыдущей точки в массиве точек
var inxNext = i < dots.length - 2? i+2 :i+1; //Индекс следующей точки в массиве точек
//Вычисляем промежуточные точки между двумя точками
var control = calcControlPoints(dots[inxLast][0],dots[inxLast][1],
...