#javascript #canvas #html5-canvas #mouseevent
#javascript #холст #html5-canvas #mouseevent
Вопрос:
Если вы увидите фрагмент кода run, который у меня есть, вы увидите этот html-рисунок на холсте, который сегментирован, чтобы раскрасить дуги градиентом.
Я пытаюсь выяснить, как постепенно очищать контекст от старых «дуг» в конце рисунка, аналогично эффекту «след мыши», возможно, аналогично этому:https://imgur.com/a/2Lr9IYq
Я думаю, возможно, что каким-то образом, как только total
счетчик превысит segment
значение count, он очистится сам, но я не совсем уверен, как это сделать.
Благодарен, если кто-нибудь может указать мне правильное направление!
var c = document.querySelector("canvas"),
ctx = c.getContext("2d"),
colors = [
{r: 0, g: 0, b: 0, a:1},
{r: 255, g: 255, b: 255, a:1},
],
cIndex = 0, maxColors = colors.length,
total = 0, segment = 1000,
isDown = false, px, py;
setSize();
c.onmousedown = c.ontouchstart = function(e) {
isDown = true;
var pos = getPos(e);
px = pos.x;
py = pos.y;
};
c.onmousemove = c.ontouchmove = function(e) {if (isDown) plot(e)};
c.onmouseup = c.ontouchend = function(e) {
e.preventDefault();
isDown = false
};
function getPos(e) {
// e.preventDefault();
if (e.touches) e = e.touches[0];
var r = c.getBoundingClientRect();
return {
x: e.clientX - r.left,
y: e.clientY - r.top
}
}
function plot(e) {
var pos = getPos(e);
plotLine(ctx, px, py, pos.x, pos.y);
px = pos.x;
py = pos.y;
}
function plotLine(ctx, x1, y1, x2, y2) {
var diffX = Math.abs(x2 - x1),
diffY = Math.abs(y2 - y1),
dist = Math.sqrt(diffX * diffX diffY * diffY),
step = dist / 50,
i = 0,
t, b, x, y;
while (i < dist) {
t = Math.min(1, i / dist);
x = x1 (x2 - x1) * t;
y = y1 (y2 - y1) * t;
// ctx.shadowBlur = 500;
// ctx.shadowOffsetX = 0;
// ctx.shadowOffsetY = 0;
// ctx.shadowColor = getColor();
// console.log(getColor())
ctx.fillStyle = getColor();
ctx.beginPath();
ctx.arc(x, y, 25, 0, Math.PI*2);
ctx.fill();
i = step;
}
function getColor() {
var r, g, b, a, t, c1, c2;
c1 = colors[cIndex];
c2 = colors[(cIndex 1) % maxColors];
t = Math.min(1, total / segment);
if ( total > segment) {
total = 0;
if ( cIndex >= maxColors) cIndex = 0;
}
r = c1.r (c2.r - c1.r) * t;
g = c1.g (c2.g - c1.g) * t;
b = c1.b (c2.b - c1.b) * t;
a = c1.a (c2.a - c1.a) * t;
return "rgb(" (r|0) "," (g|0) "," (b|0) "," (a) ")";
}
}
window.onresize = setSize;
function setSize() {
c.width = window.innerWidth;
c.height = window.innerHeight;
}
html, body {
margin:0;
padding:0;
}
body {
padding: 0px;
}
<canvas id="myCanvas" ></canvas>
Комментарии:
1. Холст не хранит ранее нарисованные контуры, только текущий цвет пикселей. Если вы хотите впоследствии изменить свой путь, способ сделать это — стереть холст и перерисовать части пути, которые вы хотите сохранить. Если вы сохраняете координаты пути в массиве, помещая новые координаты путей в конец массива и сдвигая старые координаты с начала массива. Вы можете повторно отобразить элементы в массиве после очистки canvas для достижения желаемого эффекта.
2. Простым способом сделать это было бы использовать это
ctx.fillStyle = "rgba(255,255,255,.2)"; ctx.fillRect(0,0,c.width,c.height)
в началеplotLine
. Объяснение: если вы используете этоrgb(255,255,255)
вместоrgba(255,255,255,.2)
, это очистит холст, поскольку вы закрываете все предыдущие рисунки белым прямоугольником размером с холст. Если вы используете полупрозрачный белый цвет, предыдущий рисунок будет постепенно закрываться, в результате чего холст, по-видимому , постепенно очистится.3. круто! да, это в некоторой степени делает то, чего я пытался достичь
4. Проблема с методом, который предоставляет @enxaneta, заключается в том, что
alpha(0.2) alpha(0.2) alpha(0.2) ...
никогда не доходит доalpha(1)
. У вас всегда будет призрак ваших предыдущих рисунков.5. @Kaiido да, я тоже это понял. у вас есть предложения?