#javascript #html #animation #canvas
#javascript #HTML #Анимация #холст
Вопрос:
Я написал код для своей задачи по набору персонала — он должен вызывать поворот слева направо. Когда он попадает в правую границу, он должен изменить свой размер на 100 пикселей, левая граница равна 50 пикселям. После каждых 20 пикселей он меняет свой цвет. Как я могу гарантировать, что это изменение выполняется один раз через каждые 20 пикселей? Код на самом деле работает правильно, но я не могу найти в Интернете какое-либо решение, которое помогло бы мне повторить эту конкретную анимацию кода. Он перемещается слева направо, а затем снова влево, и reck скрывается, как будто движется бесконечно влево.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width>, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CANVAS animacje</title>
<style>
body{
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 500;
let cw = canvas.width;
let ch = canvas.height;
let canvasX = 0;
let canvasY = 0;
let rectX = 0;
let rectY = ch/2;
let rectSize = 50;
let rectSizeRight = 100;
let rectSpeed = 10;
function field(){
ctx.fillStyle = '#ddd';
ctx.fillRect(canvasX, canvasY, cw, ch);
window.requestAnimationFrame(field);
}
function randomColors(){
let r = Math.floor(Math.random()*255);
let g = Math.floor(Math.random()*255);
let b = Math.floor(Math.random()*255);
return 'rgb(' r ',' g ',' b ')';
window.requestAnimationFrame(randomColors);
}
function rect(){
ctx.fillStyle = randomColors()
ctx.fillRect(rectX,rectY,rectSize,rectSize);
rectX =rectSpeed;
if(rectX rectSize == 0){
rectSize = rectSize;
rectSpeed=rectSpeed;
} else if(rectX rectSizeRight == cw){
rectSize=rectSizeRight;
rectSpeed = -rectSpeed;
} ;
window.requestAnimationFrame(rect);
// if(rectX rectSizeRight == cw){
// rectSize=rectSizeRight;
// rectSpeed = -rectSpeed
// }
// if (rectX rectSize <= 0){
// rectSize = rectSize;
// rectSpeed = -rectSpeed;
// }
// if(rectX rectSizeRight>=cw){
// rectSize=rectSizeRight;
// rectSpeed = -rectSpeed;
// }
}
function animate(){
field();
rect();
randomColors();
}
window.requestAnimationFrame(animate);
</script>
</body>
</html>
Ответ №1:
Короче говоря:
- удалите избыточные вызовы функций, которые отображают объекты на экране
- сохраните последние выбранные цвета, чтобы ссылаться на них после того, как фон canvas переопределит прямоугольник
- меняйте цвета только тогда, когда координаты x кратны 20 (используйте оператор modulo, чтобы проверить это)
- код после
return
не будет выполнен
Вот обновленный код:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 500;
let cw = canvas.width;
let ch = canvas.height;
let canvasX = 0;
let canvasY = 0;
let rectX = 0;
let rectY = ch/2;
let rectSize = 50;
let rectSizeRight = 100;
let rectSpeed = 1;
// my change
let currentColors = randomColors();
function field(){
ctx.fillStyle = '#ddd';
ctx.fillRect(canvasX, canvasY, cw, ch);
window.requestAnimationFrame(field);
}
function randomColors() {
let r = Math.floor(Math.random()*255);
let g = Math.floor(Math.random()*255);
let b = Math.floor(Math.random()*255);
return 'rgb(' r ',' g ',' b ')';
}
function rect(){
// my change
if (rectX % 20 === 0) {
currentColors = randomColors();
}
// my change
ctx.fillStyle = currentColors;
ctx.fillRect(rectX,rectY,rectSize,rectSize);
rectX =rectSpeed;
if(rectX rectSize == 0){
rectSize = rectSize;
rectSpeed=rectSpeed;
} else if(rectX rectSizeRight == cw){
rectSize=rectSizeRight;
rectSpeed = -rectSpeed;
} ;
window.requestAnimationFrame(rect);
// if(rectX rectSizeRight == cw){
// rectSize=rectSizeRight;
// rectSpeed = -rectSpeed
// }
// if (rectX rectSize <= 0){
// rectSize = rectSize;
// rectSpeed = -rectSpeed;
// }
// if(rectX rectSizeRight>=cw){
// rectSize=rectSizeRight;
// rectSpeed = -rectSpeed;
// }
}
function animate(){
// my change
field();
rect();
}
window.requestAnimationFrame(animate);
Кроме того, код немного запутан, но это уже другая история.
Комментарии:
1. Большое вам спасибо, это мне очень помогло, теперь я понял это.
Ответ №2:
Попробуйте это
https://stackblitz.com/edit/typescript-kk42qx?embed=1amp;file=index.ts
// Import stylesheets
import './style.css';
// Write TypeScript code!
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<h1>TypeScript Starter</h1>`;
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 500;
let cw = canvas.width;
let ch = canvas.height;
let canvasX = 0;
let canvasY = 0;
let rectX = 0;
let rectY = ch/2;
let rectSize = 50;
let rectSizeRight = 100;
let rectSpeed = 10;
function field(){
ctx.fillStyle = '#ddd';
ctx.fillRect(canvasX, canvasY, cw, ch);
window.requestAnimationFrame(field);
}
function randomColors(){
let r = Math.floor(Math.random()*255);
let g = Math.floor(Math.random()*255);
let b = Math.floor(Math.random()*255);
return 'rgb(' r ',' g ',' b ')';
window.requestAnimationFrame(randomColors);
}
let a = 0; <==== Initialize a variable outside the loop
function rect(){
a ; <===
ctx.fillStyle = randomColors()
ctx.fillRect(rectX,rectY,rectSize,rectSize);
// ==========================
if (a % 50 === 0) {
rectX = a;
}
// ==========================
if(rectX rectSize == 0){
rectSize = rectSize;
rectSpeed = rectSpeed;
} else if(rectX rectSizeRight === cw){
rectSize = rectSizeRight;
rectSpeed = -rectSpeed;
} else if (1) {
}
window.requestAnimationFrame(rect);
// console.log(rectX)
}
function animate(){
field();
rect();
randomColors();
}
window.requestAnimationFrame(animate);