我有一个HTML5 Canvas。我正在使用KineticJS(KonvaJS)画布库。在空白画布上,我会打印一张图像,如下图所示。现在我想创建一个圆形,可以用来擦除图像的一部分。图像中的红色圆圈是橡皮擦。
如何在HTML5画布上删除部分图像?
答案 0 :(得分:3)
您可以使用合成来“擦除”像素。
具体来说,您使用destination-out
合成。
KineticJS不支持合成,但您仍有几个选项:
(注意:KineticJS已成为KonvaJS,我还没有检查KonvaJs是否支持合成。如果现在这样做,只需在KonvaJS中使用destination-out
合成)
选项#1:使用原生画布元素作为Kinetic.Image源
使用var c=document.createElement
创建内存中的html5画布,
将画布大小调整为图像大小,
drawImage
将您的图片放到画布上,
创建Kinetic.Image
并将其image属性设置为对本机画布的引用。 Kinetic.Image将显示绘制到原生画布上的任何内容。
var kImage=new Kinetic.Image({
...
image:c,
...
设置画布合成以使新绘图“擦除”现有像素:
c.globalCompositeOperation='destination-out';
收听圈子上的拖动事件。使用这些事件在画布上绘制一个圆圈,就像动态圆圈橡皮擦一样移动。由于画布的合成设置为“擦除”,因此画布上圆圈的新图形将擦除画布上的图像。
你的Kinetic.Image正好反映了它的画布来源(var c),所以你的Kinetic.Image也会显示正在被动画圈圈消失运动所删除的图像。
选项#2:使用Kinetic.Shape
您可以通过在单独的图层上创建Kinetic.Shape并使用以下方式获取对本机画布上下文的引用来执行与选项#1相同的操作:
var ctx = myShapeLayer.getContext()._context;
这是一个较弱的选择,因为KineticJS将重绘形状 - 导致您的删除被撤消。因此,您必须执行额外步骤,以保存所有圆圈橡皮擦的移动并重放这些移动(在drawFunc
中)以重做您的擦除。
答案 1 :(得分:3)
感谢markE的详细解答,
我试图从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();
});
}
答案 2 :(得分: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
,但我不确定你是如何用圆圈做的。