2010-07-23 125 views
12

我一直在關注Mozilla網站上關於透明度和漸變的課程:https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors,但我一直未能弄清楚這一點。是否可以使用畫布製作漸變透明/圖層蒙版圖像?

我知道我可以用PNG圖像來實現這些效果;然而,在我正在研究的程序中,漸變將根據圖像移動的位置不斷變化。

下面是我正在尋找的效果示例。 http://home.insightbb.com/~epyonxl1/gradientex.jpg

回答

6

我已經在這裏添加了一些代碼http://code.google.com/p/canvasimagegradient/,它爲CanvasRenderingContext2D添加了一個drawImageGradient函數。您可以使用線性或徑向漸變繪製圖像。由於缺乏getImageData/putImageData支持,它在IE中不起作用,即使使用excanvas也是如此。

例如下面的代碼將繪製具有徑向梯度的圖像(上下文檢索和圖像負荷未示出):

var radGrad = ctx.createRadialGradient(
    img.width/2, img.height/2, 10, 
    img.width/2, img.height/2, img.width/2); 
radGrad.addColorStop(0, "transparent"); 
radGrad.addColorStop(1, "#000"); 

ctx.drawImageGradient(img, 112.5, 130, radGrad); 

代碼工作如下:

  1. 創建畫布元件動態地繪製圖像。
  2. 檢索此新畫布的imageData。
  3. 檢索要繪製圖像的畫布上位置的imageData。
  4. 遍歷目標圖像數據並更新每個像素,將圖像和目標像素值的百分比(從梯度透明度值導出)相加。
  5. 最後將更新後的圖像數據放回到目標畫布上。

顯然性能是圖像變大的一個問題。 http://code.google.com/p/canvasimagegradient/上的圖像需要大約6-10ms才能繪製。一個1024x768的圖像需要大約100ms-250ms才能繪製。儘管只要你沒有動畫,仍然可以使用。

+0

啊,我知道後,我忘了已經指定我知道如何創建一個漸變,如https://developer.mozilla.org/samples/canvas-tutorial/4_9_canvas_lineargradient.html,我會得到這個答案。不幸的是,這些僅適用於特定顏色。如果它的圖像(非純色)另一方面這種方法根本不起作用。 – mjrevel 2010-07-24 03:43:11

+0

我回去看看圖片,看看你現在想要什麼。好問題。我想如果你在一個單獨的畫布中取出圖像並檢索圖像數據,你可以對它應用漸變效果,然後覆蓋它在原始畫布上。我會玩一玩,看看我能想出什麼。 – Castrohenge 2010-07-24 11:38:52

+0

聽起來不錯,週末不需要太多時間來處理它,但我會看到我想到的。讓我張貼在任何你想出來的東西上。我絕對想要解決這個問題。 – mjrevel 2010-07-25 03:18:18

14

它可能使用上下文。globalCompositeOperation使面膜

context.drawImage(img, 0, 0, img.width, img.height, 0,0, img.width, img.height); 
context.globalCompositeOperation = "destination-out"; 
gradient = context.createLinearGradient(0, 0, 0, img.height); 
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)"); 
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)"); 
context.fillStyle = gradient; 
context.fillRect(0, 0, img.width, img.height); 

這不每個像素處理做的,應該是更快

+1

我同意這應該更快,可能是正確的答案。 – calipoop 2014-03-15 18:09:54

+0

據我所見,這不是正確答案的原因是您只使用漸變來影響純色矩形。 OP詢問使用漸變來影響圖像。 – Nathan 2015-02-25 16:21:07

+0

@Nathan你錯了 - 這個效果很好 – Alnitak 2015-02-25 16:52:16

8

要使用透明面罩它的第一個必要採取兩個圖像中的一個,並把它正確合併兩個圖像到關閉屏幕帆布,並添加使用context.globalCompositeOperation = destination-out每@ Tommyka的回答

var offscreen = document.createElement('canvas'); // detached from DOM 
var context = offscreen.getContext('2d'); 
context.drawImage(image1, 0, 0, image1.width, image1.height); 

var gradient = context.createLinearGradient(0, 0, 0, img.height); 
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)"); 
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)"); 
context.globalCompositeOperation = "destination-out"; 
context.fillStyle = gradient; 
context.fillRect(0, 0, image1.width, image1.height); 

然後,爲了真正合並兩個圖像,你個所需的透明面具恩需要將其他圖像繪製到另一個畫布,然後簡單地畫阿爾法複合屏幕外的畫布上,最重要的是:

var onscreen = document.getElementById('mycanvas'); 
var context2 = onscreen.getContext('2d'); 
context2.drawImage(image2, 0, 0, image2.width, image2.height); 
context2.drawImage(offscreen, 0, 0, onscreen.width, onscreen.height); 

演示在http://jsfiddle.net/alnitak/rfdjoh31/4/

+2

這應該是被接受的答案。它的工作原理和@Castrohenge的解決方案一樣好,但不需要(慢)逐像素操作。謝謝! – Nathan 2015-02-28 14:06:24

相關問題