簡體   English   中英

HTML5 canvas 三角形每個頂點的漸變

[英]Gradients at each vertex of a triangle with HTML5 canvas

如何在給定每個頂點顏色的情況下使用從頂點開始的漸變填充三角形?

我正在嘗試重現這樣的內容:

三角形

我正在使用 HTML5 canvas Context2D 中的內置fill function。 我試圖避免必須根據它們到頂點的距離來處理逐像素插值。 我擔心它不會像內置fill function (?) 那樣高性能。 我現在也不能處理 WebGL。

我已經使用徑向漸變做了一個技巧,但是,我的幼稚方法存在一些問題:

  • colors 似乎融合得不好
  • 最后應用的漸變會覆蓋其他漸變
  • radius變量中使用的值是任意的

OBS:我不知道它是否相關,但我正在構建一個三角形帶(實際上是索引幾何)。

 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>

  • colors 似乎融合得不好

為此,您可以將 2D 上下文的globalCompositeOperation屬性用於其混合模式之一,即使在您的情況下,具有黑色背景的"lighter"合成模式似乎會產生最接近 model 的結果。

  • 最后應用的漸變會覆蓋其他漸變

由於前面的要點,情況不再如此。

  • 半徑變量中使用的值是任意的

在我看來不是這樣,它確實對應於等邊三角形的每個點與其中心之間的距離,這很有意義。

 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM