英文:
Alternating ctx.strokeStyle while using requestAnimationFrame()
问题
以下是您要翻译的内容:
"I'm trying to draw simple random motion as my landing page's background canvas, and I'm having a hard time getting the lines to have unique colors.
I've tried changing it after the moveTo as well, but didn't have success (just appeared to be a mix of the colors).
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
//ctx.canvas.width = window.innerWidth;
//ctx.canvas.height = window.innerHeight*4;
const numSteps = ctx.canvas.width / 2 + 10;
const stepSize = 10;
const startX = 0;
const startY = canvas.height / 2;
const timeInterval = 15;
var Point = function(color_inp){
this.x = startX;
this.y = startY;
this.color = color_inp;
}
const colors = [
'#FF1493', // Pink
'#FF00FF', // Magenta
'#800080', // Purple
'#4B0082', // Indigo
'#0000FF', // Blue
'#00FFFF', // Cyan
'#00FF00', // Green
'#FFFF00', // Yellow
'#FF7F00', // Orange
'#8B4513' // Saddle Brown
];
function drawRandomWalk(stPoint, steps) {
ctx.globalAlpha = 0.01;
let stepCount = 0;
ctx.beginPath();
ctx.strokeStyle = stPoint.color;
ctx.moveTo(stPoint.x, stPoint.y);
setTimeout(drawStep, 10);
function drawStep() {
if (stepCount >= steps) {
return;
}
ctx.moveTo(stPoint.x, stPoint.y);
const direction = Math.random() < 0.5 ? -1 : 1;
stPoint.y += stepSize * direction;
stPoint.x = startX + stepCount * 2;
ctx.lineTo(stPoint.x, stPoint.y);
ctx.lineWidth = 1;
ctx.stroke();
stepCount++;
requestAnimationFrame(drawStep);
}
}
for(const color of colors)
{
const startPoint = new Point(color);
drawRandomWalk(startPoint, numSteps);
}
<canvas id="myCanvas" width="600" height="600"></canvas>
"
英文:
I'm trying to draw simple random motion as my landing page's background canvas, and I'm having a hard time getting the lines to have unique colors.
I've tried changing it after the moveTo as well, but didnt have success (just appeared to be a mix of the colors).
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
//ctx.canvas.width = window.innerWidth;
//ctx.canvas.height = window.innerHeight*4;
const numSteps = ctx.canvas.width / 2 + 10;
const stepSize = 10;
const startX = 0;
const startY = canvas.height / 2;
const timeInterval = 15;
var Point = function(color_inp){
this.x = startX;
this.y = startY;
this.color = color_inp;
}
const colors = [
'#FF1493', // Pink
'#FF00FF', // Magenta
'#800080', // Purple
'#4B0082', // Indigo
'#0000FF', // Blue
'#00FFFF', // Cyan
'#00FF00', // Green
'#FFFF00', // Yellow
'#FF7F00', // Orange
'#8B4513' // Saddle Brown
];
function drawRandomWalk(stPoint, steps) {
ctx.globalAlpha = 0.01;
let stepCount = 0;
ctx.beginPath();
ctx.strokeStyle = stPoint.color;
ctx.moveTo(stPoint.x, stPoint.y);
setTimeout(drawStep, 10);
function drawStep() {
if (stepCount >= steps) {
return;
}
ctx.moveTo(stPoint.x, stPoint.y);
const direction = Math.random() < 0.5 ? -1 : 1;
stPoint.y += stepSize * direction;
stPoint.x = startX + stepCount * 2;
ctx.lineTo(stPoint.x, stPoint.y);
ctx.lineWidth = 1;
ctx.stroke();
stepCount++;
requestAnimationFrame(drawStep);
}
}
for(const color of colors)
{
const startPoint = new Point(color);
drawRandomWalk(startPoint, numSteps);
}
<!-- language: lang-html -->
<canvas id="myCanvas" width="600" height="600"></canvas>
<!-- end snippet -->
答案1
得分: 0
问题在于每支“笔”绘制线条时都共享状态 - 你正在绘制一个由许多movetos/linetos组成的单一长路径,一次又一次地绘制它。
如果你想要globalAlpha
淡入效果(它依赖于能够一次又一次地绘制线条),你需要分别跟踪每支笔所绘制的路径,并像下面这样绘制它。
我去掉了Point
结构,因为它实际上不是必需的。
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const numSteps = ctx.canvas.width / 2 + 10;
const stepSize = 10;
const startX = 0;
const startY = canvas.height / 2;
const timeInterval = 15;
const colors = [
'#FF1493', // Pink
'#FF00FF', // Magenta
'#800080', // Purple
'#4B0082', // Indigo
'#0000FF', // Blue
'#00FFFF', // Cyan
'#00FF00', // Green
'#FFFF00', // Yellow
'#FF7F00', // Orange
'#8B4513' // Saddle Brown
];
function drawRandomWalk(startX, startY, color, nSteps) {
setTimeout(drawStep, 10);
const steps = [[startX, startY]];
function drawStep() {
if (steps.length >= nSteps) {
return;
}
// Draw current line
ctx.globalAlpha = 0.01;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 1;
let x = 0, y = 0;
for(let i = 0; i < steps.length; i++) {
[x, y] = steps[i];
if(i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// Compute next point
const direction = Math.random() < 0.5 ? -1 : 1;
y += stepSize * direction;
x = startX + steps.length * 2;
steps.push([x, y]);
requestAnimationFrame(drawStep);
}
}
for(const color of colors)
{
drawRandomWalk(startX, startY, color, numSteps);
}
<canvas id="myCanvas" width="600" height="600"></canvas>
你只需要复制上述的代码,然后粘贴到你的项目中即可。
英文:
The issue is each of the "pens" drawing the lines are sharing state – you're drawing a single long path that consists of many movetos/linetos over and over and again.
If you want the globalAlpha
fade effect (which relies on being able to draw the line over and over again), you'll need to separately keep track of the trail drawn by each pen, and draw it, like below.
I got rid of the Point
structure, since it's not really needed.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const numSteps = ctx.canvas.width / 2 + 10;
const stepSize = 10;
const startX = 0;
const startY = canvas.height / 2;
const timeInterval = 15;
const colors = [
'#FF1493', // Pink
'#FF00FF', // Magenta
'#800080', // Purple
'#4B0082', // Indigo
'#0000FF', // Blue
'#00FFFF', // Cyan
'#00FF00', // Green
'#FFFF00', // Yellow
'#FF7F00', // Orange
'#8B4513' // Saddle Brown
];
function drawRandomWalk(startX, startY, color, nSteps) {
setTimeout(drawStep, 10);
const steps = [[startX, startY]];
function drawStep() {
if (steps.length >= nSteps) {
return;
}
// Draw current line
ctx.globalAlpha = 0.01;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 1;
let x = 0, y = 0;
for(let i = 0; i < steps.length; i++) {
[x, y] = steps[i];
if(i === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
// Compute next point
const direction = Math.random() < 0.5 ? -1 : 1;
y += stepSize * direction;
x = startX + steps.length * 2;
steps.push([x, y]);
requestAnimationFrame(drawStep);
}
}
for(const color of colors)
{
drawRandomWalk(startX, startY, color, numSteps);
}
<!-- language: lang-html -->
<canvas id="myCanvas" width="600" height="600"></canvas>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论