Страхотен ресурс за canvas 2d е CanvasRenderingContext2D на MDN
Анимации с помощта на канава.
Ще ви е необходим цикъл за рендиране, ако искате да анимирате съдържание на платно.
Цикълът за изобразяване се извиква 60 пъти в секунда, ако е възможно, рисуване твърде много и скоростта ще падне под 60 кадъра в секунда.
Основният цикъл изчиства платното, след това рисува анимираното съдържание, след което изисква следващия кадър.
requestAnimationFrame(mainLoop); // request the first frame to start the animation
function mainLoop() {
ctx.globalAlpha = 1; // default to 1 in case there is other content drawn
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear the canvas
drawContent(); // render the content.
requestAnimationFrame(mainLoop); // request the next frame (in 1/60th second)
}
Функция за рисуване на кръг. Можете да премахнете алфата от цвета и да използвате globalAlpha
за да настроите прозрачността.
Math.TAU = Math.PI * 2; // set up 2 PI
function drawCircle(x, y, radius, color, alpha = 1) {
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.strokeStyle = "#000";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.TAU);
ctx.fill();
ctx.stroke();
}
Създайте обект, който да съдържа описанието на кръг и масив, в който да ги поставите
const circles = [];
function circle(x,y,r = 10, col = "#FFF", alpha = 1) {
return {x, y, r, col, alpha, alphaTarget: alpha};
}
След това във функцията drawContent
начертайте кръговете един по един
function drawContent() {
for (const circle of circles) {
if(circle.alpha !== circle.alphaTarget) {
const aStep = circle.alphaTarget - circle.alpha;
const dir = Math.sign(aStep);
circle.alpha += Math.min(Math.abs(aStep), dir * 0.02)) * dir;
}
drawCircle(circle.x, circle.y, circle.r, circle.col, circle.alpha);
}
}
Демонстрация
Демото рисува 100 кръга, всеки със собствен цвят и алфа. Алфата се избира на случаен принцип, за да изчезне и след това да се върне обратно.
Ще ви е необходим цикъл за рендиране, ако искате да анимирате съдържание на платно.
Премествам кръга, така че ако дадено устройство бавно изобразява съдържанието, тогава ще бъде по-лесно да се види ниската скорост на кадрите.
Math.TAU = Math.PI * 2; // set up 2 PI
Math.rand = (val) => Math.random() * val;
Math.randI = (val) => Math.random() * val | 0;
requestAnimationFrame(mainLoop);
const ctx = canvas.getContext("2d");
const W = canvas.width = innerWidth; // size canvas to page
const H = canvas.height = innerHeight; // size canvas to page
const circleCount = 100;
const circleFadeRate = 0.01; // per 60th second
const circles = [];
const circle = (x,y,r = 10, col = "#FFF", alpha = 1) => ({x, y, r, col, alpha, alphaTarget: alpha});
createCircles();
function createCircles() {
var i = circleCount;
while (i--) {
circles.push(circle(Math.rand(W), Math.rand(H), Math.rand(10) + 10, "#" + Math.randI(0xFFF).toString(16).padStart(3,"0"), 1));
}
circles.sort((a,b) => a.r - b.r); // big drawn last
}
function mainLoop() {
ctx.globalAlpha = 1;
ctx.clearRect(0, 0, W, H);
drawContent();
requestAnimationFrame(mainLoop);
}
function drawCircle(x, y, radius, color, alpha = 1) {
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.strokeStyle = "#000";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.TAU);
ctx.fill();
ctx.stroke();
}
function drawContent() {
for (const circle of circles) {
if(circle.alpha !== circle.alphaTarget) {
const aStep = circle.alphaTarget - circle.alpha;
const dir = Math.sign(aStep);
circle.alpha += Math.min(Math.abs(aStep), 0.02) * dir;
} else if(Math.random() < 0.01) {
circle.alphaTarget = circle.alpha < 0.7 ? 1 : Math.random() * 0.4;
}
circle.y += (circle.r - 10) / 5;
circle.y = circle.y > H + circle.r + 2 ? -(circle.r + 2) : circle.y;
drawCircle(circle.x, circle.y, circle.r, circle.col, circle.alpha);
}
}
body {
padding: 0px;
}
canvas {
position: absolute;
top: 0px;
left: 0px;
}
<canvas id="canvas"></canvas>
За повече информация относно API за 2D платно вижте връзката в горната част на този отговор.
person
Blindman67
schedule
31.12.2019