HTML-холст отображает только один цвет - PullRequest
0 голосов
/ 13 сентября 2018

У меня проблемы с Градиент холста , он показывает только последний цвет, который я установил для метода gradient.__addColorStop__(offset,color).

Например, вот фрагмент моего кода, чтобы лучше понять:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");
let circle1 = new Circle(300, 250, 50, gradient);
circle1.draw(ctx);

Этот код рисует только красный круг и делает то же самое с любой формой, заполненной градиентом. Если я прокомментирую эту строку gradient.addColorStop(1/1,"red");, тогда холст нарисует желтый круг, прочитав только последний цвет.Я попробовал тот же код на jsfiddle.net и работает отлично, я не знаю, почему мой скрипт не работает.

PD: Circle - это объект js, который я определил и работает отлично

Извините за мойанглийский, если пост не понимает, пожалуйста, скажите мне, это мой первый пост на StackOverflow.Спасибо!

1 Ответ

0 голосов
/ 13 сентября 2018

CanvasGradients относятся к матрице преобразования контекста, а не к форме, которой вы ее заполните.

Итак, в вашем примере, поскольку вы рисуете горизонтальный градиент, вы устанавливаете этот градиент только в области, которая идет от x: 10 до x: 200. Пиксели до x: 10 будут иметь значение с индексом 0, а после x: 200 - значение с индексом 1.
Поскольку вы рисуете свой круг на 300 150 с радиусом 50, минимальная позиция х, которую ваш круг достигнет, равна 250, то есть после индекса градиента: 1 и, следовательно, сплошного красного цвета.

Вот визуальная демонстрация того, что происходит:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

// draw a full rectangle to see how the gradient is actually rendered
ctx.fillStyle = gradient;
ctx.fillRect(0,0,canvas.width,canvas.height);

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
ctx.strokeStyle = 'white';
ctx.stroke();
<canvas id="canvas" width="500" height="300"></canvas>

Чтобы обойти это, у вас есть два пути:

  • создайте свой CanvasGradient в правильных координатах:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// x1 & x2 are set to match the circle's position
let gradient = ctx.createLinearGradient(250, 90, 350, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

ctx.fillStyle = gradient;

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
ctx.fill();
<canvas id="canvas" width="500" height="300"></canvas>
  • изменить матрицу преобразования контекста, чтобы переместить ваш CanvasGradient:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

ctx.fillStyle = gradient;

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
// our arc has been defined at the correct position
// we can now translate the context matrix so that only the fillStyle be moved
ctx.translate(230, 0);
ctx.fill();

// reset the default tranform matrix
ctx.setTransform(1,0,0,1,0,0);
<canvas id="canvas" width="500" height="300"></canvas>
...