Градиенты в каждой вершине треугольника с холстом HTML5 - PullRequest
1 голос
/ 09 июля 2020

Как я могу заполнить треугольник градиентами, начиная с его вершин, учитывая цвет для каждой вершины?

Я пытаюсь воспроизвести что-то вроде этого:

image

var canvas = document.querySelector("canvas");

var ctx = canvas.getContext("2d");

var v1 = { x: 100, y: 0 };
var v2 = { x: 0, y: 180 };
var v3 = { x: 200, y: 180 };

var radius = 175;

var grd1 = ctx.createRadialGradient(v1.x, v1.y, 0, v1.x, v1.y, radius);
grd1.addColorStop(0, "#FF0000FF");
grd1.addColorStop(1, "#FF000000");

var grd2 = ctx.createRadialGradient(v2.x, v2.y, 0, v2.x, v2.y, radius);
grd2.addColorStop(0, "#00FF00FF");
grd2.addColorStop(1, "#00FF0000");

var grd3 = ctx.createRadialGradient(v3.x, v3.y, 0, v3.x, v3.y, radius);
grd3.addColorStop(0, "#0000FFFF");
grd3.addColorStop(1, "#0000FF00");

ctx.beginPath();

ctx.moveTo(v1.x, v1.y);
ctx.lineTo(v2.x, v2.y);
ctx.lineTo(v3.x, v3.y);

ctx.closePath();

ctx.fillStyle = "#FFFFFFFF"; // fill with white and apply the gradients on top of it
ctx.fill();

ctx.fillStyle = grd1;
ctx.fill();

ctx.fillStyle = grd2;
ctx.fill();

ctx.fillStyle = grd3;
ctx.fill();
<canvas width="200" height="180"></canvas>

1 Ответ

1 голос
/ 09 июля 2020
  • Кажется, что цвета плохо сочетаются

Для этого вы можете использовать свойство globalCompositeOperation вашего 2D-контекста в один из своих режимов наложения, даже если в вашем случае режим наложения "lighter" с черным фоном, кажется, дает результат, наиболее близкий к вашей модели.

  • Последний примененный градиент перезаписывает другие

Благодаря предыдущему пункту, это уже не так.

  • Значение, используемое в переменной радиуса, произвольно

Мне это не кажется, это действительно соответствует расстоянию между всеми точками вашего равностороннего треугольника и его центром, что имеет смысл.

var canvas = document.querySelector("canvas");

var ctx = canvas.getContext("2d");

// reordered to make the same as OP's image
var v1 = { x: 0, y: 180 };
var v2 = { x: 200, y: 180 };
var v3 = { x: 100, y: 0 };

var radius = 180;

var grd1 = ctx.createRadialGradient(v1.x, v1.y, 0, v1.x, v1.y, radius);
grd1.addColorStop(0, "#FF0000FF");
grd1.addColorStop(1, "#FF000000");

var grd2 = ctx.createRadialGradient(v2.x, v2.y, 0, v2.x, v2.y, radius);
grd2.addColorStop(0, "#00FF00FF");
grd2.addColorStop(1, "#00FF0000");

var grd3 = ctx.createRadialGradient(v3.x, v3.y, 0, v3.x, v3.y, radius);
grd3.addColorStop(0, "#0000FFFF");
grd3.addColorStop(1, "#0000FF00");

ctx.beginPath();

ctx.moveTo(v1.x, v1.y);
ctx.lineTo(v2.x, v2.y);
ctx.lineTo(v3.x, v3.y);

ctx.closePath();

// fill with black
ctx.fill();

// set blend mode
ctx.globalCompositeOperation = "lighter";

ctx.fillStyle = grd1;
ctx.fill();

ctx.fillStyle = grd2;
ctx.fill();

ctx.fillStyle = grd3;
ctx.fill();

// if you need to draw something else, don't forget to reset the gCO
ctx.globalCompositeOperation = "source-over";
<canvas width="200" height="180"></canvas>
...