用不止一种颜色按程序填充形状

xHo*_*uet 1 javascript canvas paperjs

我正在用node、js等制作一个应用程序。我想填充可以通过数据点或具有不同分层颜色的其他格式创建的自定义形状。例如,我有一个三角形。我想用红色填充底部 1/3,用蓝色填充中间 1/3,用绿色填充顶部 1/3。我该怎么办呢?

我正在查看 Paper.js 和基本画布,但它们似乎只有单色填充。

感谢您的任何建议!

小智 5

我知道答案已被接受,但我想为未来的读者提供一种非常简单的方法。作为奖励,它使用线性渐变自动计算每个部分的高度并且速度很快-

\n

结果将是

\n

折断

\n

代码和演示

\n

\r\n
\r\n
var ctx = document.querySelector("canvas").getContext("2d"),\n    grad = ctx.createLinearGradient(0, 0, 0, 150);\n\ngrad.addColorStop(0, "red");     // start of red\ngrad.addColorStop(1/3, "red");   // end of red at 1/3\n\ngrad.addColorStop(1/3, "gold");  // start of gold at 1/3\ngrad.addColorStop(2/3, "gold");  // end of gold at 2/3\n\ngrad.addColorStop(2/3, "blue");  // start of blue at 2/3\ngrad.addColorStop(1, "blue");    // end of blue at 3/3\n\n// Fill a triangle:\nctx.moveTo(75, 0); ctx.lineTo(150, 150); ctx.lineTo(0, 150);\nctx.fillStyle = grad;\nctx.fill();
Run Code Online (Sandbox Code Playgroud)\r\n
<canvas/>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

使用合成技术的动画版本

\n

\r\n
\r\n
var ctx = document.querySelector("canvas").getContext("2d"),\n    grad = ctx.createLinearGradient(0, 0, 0, 150),\n    step = grad.addColorStop.bind(grad), // function reference to simplify\n    dlt = -3, y = 150;\n\nstep(0, "red");     // start of red\nstep(1/3, "red");   // end of red at 1/3\nstep(1/3, "gold");  // start of gold at 1/3\nstep(2/3, "gold");  // end of gold at 2/3\nstep(2/3, "blue");  // start of blue at 2/3\nstep(1, "blue");    // end of blue at 3/3\n\n// store a triangle path - we\'ll reuse this for the demo loop\nctx.moveTo(75, 0); ctx.lineTo(150, 150); ctx.lineTo(0, 150);\n\n(function loop() {\n  ctx.globalCompositeOperation = "copy";  // will clear canvas with next draw\n\n  // Fill the previously defined triangle path with any color:\n  ctx.fillStyle = "#000";  // fill some solid color for performance\n  ctx.fill();\n  \n  // draw a rectangle to clip the top using the following comp mode:\n  ctx.globalCompositeOperation = "destination-in";\n  ctx.fillRect(0, y, 150, 150 - y);\n\n  // now that we have the shape we want, just replace it with the gradient:\n  // to do that we use a new comp. mode\n  ctx.globalCompositeOperation = "source-in";\n  ctx.fillStyle = grad;\n  ctx.fillRect(0, 0, 150, 150);\n  \n  y += dlt; if (y <= 0 || y >= 150) dlt = -dlt;  \n  requestAnimationFrame(loop);\n})();
Run Code Online (Sandbox Code Playgroud)\r\n
<canvas/>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

用于动画的缓存渐变图像(推荐)

\n

\r\n
\r\n
var ctx = document.querySelector("canvas").getContext("2d"),\n    tcanvas = document.createElement("canvas"),    // to cache triangle\n    tctx = tcanvas.getContext("2d"),\n    grad = tctx.createLinearGradient(0, 0, 0, 150),\n    step = grad.addColorStop.bind(grad), // function reference to simplify\n    dlt = -3, y = 150;\n\nstep(0, "red");     // start of red\nstep(1/3, "red");   // end of red at 1/3\nstep(1/3, "gold");  // start of gold at 1/3\nstep(2/3, "gold");  // end of gold at 2/3\nstep(2/3, "blue");  // start of blue at 2/3\nstep(1, "blue");    // end of blue at 3/3\n\n// draw triangle to off-screen canvas once.\ntctx.moveTo(75, 0); tctx.lineTo(150, 150); tctx.lineTo(0, 150);\ntctx.fillStyle = grad; tctx.fill();\n\n(function loop() {\n  ctx.clearRect(0, 0, 150, 150);\n\n  // draw clipped version of the cached triangle image\n  if (150-y) ctx.drawImage(tcanvas, 0, y, 150, 150 - y, 0, y, 150, 150 - y);\n\n  y += dlt; if (y <= 0 || y >= 150) dlt = -dlt;  \n  requestAnimationFrame(loop);\n})();
Run Code Online (Sandbox Code Playgroud)\r\n
<canvas/>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

您可以使用渐变线改变方向更改方向,渐变线决定渐变的角度。

\n
// vertical \nctx.createLinearGradient(0, 0, 0, 150); // x1, y1, x2, y2\n\n// hortizontal\nctx.createLinearGradient(0, 0, 150, 0); // x1, y1, x2, y2\n\n// 45\xc2\xb0 degrees\nctx.createLinearGradient(0, 0, 150, 150); // x1, y1, x2, y2\n
Run Code Online (Sandbox Code Playgroud)\n

ETC。

\n