2015-02-10 141 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(); 
    }); 
}