2015-02-10 73 views
2

我有一個HTML5畫布。我正在使用KineticJS(KonvaJS)畫布庫。在一張空白的畫布上,我打出一張圖像,如下圖所示。現在我想創建一個可以用來擦除圖像部分的圓形。圖像中的紅圈是橡皮擦。擦除HTML5畫布上的圖像部分?

enter image description here

我怎麼能擦除HTML5畫布圖像的部分?

+0

請不要「產業鏈」的其他後續問題,你原來的問題。這常常改變答案的基礎。你肯定會問這個問題。謝謝! ;-) – markE 2015-02-10 20:20:43

回答

3

您可以使用合成來「擦除」像素。

具體而言,您使用destination-out合成。

KineticJS不支持合成,但你仍然有幾個選項:

(注:KineticJS已成爲KonvaJS和我沒有檢查KonvaJs是否支持合成如果現在沒有,只是用destination-out合成內KonvaJS)

選項#1:使用原生canvas元素爲您Kinetic.Image源

  • 創建使用var c=document.createElement在內存中的HTML5畫布,

  • 調整畫布圖像尺寸,

  • drawImage圖像到畫布上,

  • 創建Kinetic.Image和圖像屬性設置爲參考本地畫布。 Kinetic.Image將顯示在本地畫布上繪製的內容。

    var kImage=new Kinetic.Image({ 
    ... 
    image:c, 
    ... 
    
  • 設置畫布合成造成新的圖紙「抹掉」現有像素:

    c.globalCompositeOperation='destination-out'; 
    
  • 傾聽你的圈子的橡皮擦拖動事件。使用這些事件在畫布上繪製一個像Kinetic circle-eraser移動一樣的圓。由於畫布的合成設置爲「擦除」,畫布上圓形的新圖形將擦除畫布上的圖像。

你Kinetic.Image恰好反映了其帆布源(VAR C),所以你Kinetic.Image也將顯示圖像響應動力學圈的橡皮擦運動被擦除。

選項#2:使用Kinetic.Shape

您可以通過一個單獨的層創建Kinetic.Shape和獲得使用本地畫布上下文的引用做同樣的操作選項#1:

var ctx = myShapeLayer.getContext()._context; 

這是一個較弱的選項,因爲KineticJS將重繪形狀 - 導致您的擦除被撤消。因此,您必須執行額外的步驟來保存所有圓形橡皮擦的動作並重播這些動作(在drawFunc中)以重新執行擦除操作。

+0

有沒有辦法改變橡皮擦的強度?類似於強度值的定義0意味着不擦除像素和1意味着像素將被擦除。儘管0和1之間的所有值都定義了橡皮擦在其擦除的像素上的強度。 – confile 2015-02-10 20:09:42

+0

我猜你在問阿爾法與合成相結合。你可以這樣做,但是你必須在一個新的問題中提出這個問題,因爲你原來的問題沒有提到alpha混合。 ;-) – markE 2015-02-10 20:19:04

+0

這裏是問題:http://stackoverflow.com/questions/28441093/how-can-i-combine-alpha-with-compositing-in-images – confile 2015-02-10 20:39:37

0

在普通的JavaScript中,這是非常簡單的。

首先讓你的畫布和繪圖方面準備:

var context=document.getElementById("your_canvas_id").getContext("2d"); 
var image=document.getElementById("your_image_id"); 

現在你要來將圖像繪製到上下文:

context.drawImage(image,0,0,image.width,image.height,0,0,image.width,image.height); 

現在,當你要刪除圖像的一部分,只是在畫布上繪製:

var x=y=radius=10;// Circle coordinates and radius. 

context.fillStyle="#ffffff";// Your eraser color (not transparent) 
context.beginPath(); 
context.arc(x,y,radius,0,Math.PI*2); 
context.fill(); 

但是,這隻能模擬擦除。如果你希望事後抹去透明,你可以看看context.clearRect,但我不確定你會怎麼做一個圓圈。

+0

[鏈接](http://stackoverflow.com/questions/10396991/clearing-circular-regions-from-html5-canvas)此鏈接描述瞭如何實際擦除畫布的圓形區域。 – Frank 2015-02-10 18:11:05

3

感謝坊間對他的詳細解答,

我試圖讓從Konva.Layer()的背景和它的工作。

var freeHandDrawingImage = new Image(); 
    freeHandDrawingImage.onload = function() { 
     var context = freeHandDrawingLayer.getContext('2d'); 
     context.drawImage(this, 0,0); 
     context.globalCompositeOperation='destination-out'; 
     freeHandDrawingLayer.draw(); 
    }; 
    freeHandDrawingImage.src = "image.png"; 

,我已經使用了Konva.Shape通過"destination-out"通過定製"source-over"抹掉並繪製免費抽獎:

freeDrawingType = 'brush'; 
isFreeDrawingMode = false; 
isPaint = false; 
lastPointerPosition = {}; 

drawFreeDrawings = function(){ 

    var freeDraw = new Konva.Shape({ 
     name: "freeDraw", 
     stroke: 'black', 
     strokeWidth: 5, 
     closed : false, 
     sceneFunc: function(context){ 
      // free draw quad 
      debugger; 
      if(isPaint){ 
       if (freeDrawingType === 'brush') { 
        context.globalCompositeOperation = 'source-over'; 
       } 
       if (freeDrawingType === 'eraser') { 
        context.globalCompositeOperation = 'destination-out'; 
       } 
       context.beginPath(); 
       context.moveTo(lastPointerPosition.x, lastPointerPosition.y); 
       var newPosition = stage.getPointerPosition(); 

       context.lineTo(newPosition.x, newPosition.y); 
       context.stroke(); 
       debugger; 
       lastPointerPosition = newPosition; 
       context.strokeShape(this); 

      } 
     } 
    }); 
    freeHandDrawingLayer.add(freeDraw); 
    // now we need to bind some events 
    // we need to start drawing on mousedown 
    // and stop drawing on mouseup 
    selectionBoxBackground.on('mousedown', function() { 
     if(isFreeDrawingMode){ 
      isPaint = true; 
      lastPointerPosition = stage.getPointerPosition(); 
      stage.draw(); 
     } 
    }); 

    selectionBoxBackground.on('mouseup', function() { 
     if(isFreeDrawingMode){ 
      isPaint = false; 
     } 
    }); 

    // and core function - drawing 
    selectionBoxBackground.on('mousemove', function() { 
      if (!isPaint) { 
       return; 
      }  
      freeHandDrawingLayer.draw(); 
    }); 
}