简体   繁体   English

如何用dynamicjs制作橡皮

[英]How to make an eraser with kineticjs

I was messing around with kineticjs and I was trying to build a mouse tool that lets you erase things on a single layer. 我搞砸了dynamicjs,并试图构建一个鼠标工具,该工具可让您在单个层上擦除内容。 I know I can make white lines if my background is white to give an "eraser" effect, but my problem is that my background is an image (they wont be erasing the background image), so drawing white lines simply wont erase it. 我知道如果我的背景是白色可以产生“橡皮擦”效果,但是我可以画白线,但是我的问题是我的背景是图像(它们不会擦除背景图像),因此绘制白线根本不会擦除它。 I need to be able to actually erase parts of the line by mouse coordinates. 我需要能够通过鼠标坐标实际擦除线的一部分。 Is there anyone that has done this or knows how 有没有做过或知道如何做的人

Yes, you can both draw freehand lines and use a freehand eraser in KineticJS. 是的,您既可以绘制手绘线,也可以在KineticJS中使用手绘橡皮擦。

However, the solution is modestly complex. 但是,该解决方案非常复杂。

Prerequisite: 先决条件:

I'm assuming during your messing around you've learned how to listen to mouse events and save those mouseXY's in order to let the user "drag-draw" a polyline. 我假设在您四处逛逛的过程中,您已经学会了如何侦听鼠标事件并保存这些mouseXY,以便用户“拖动”多段线。

The solution: 解决方案:

The solution involves using a custom Kinetic.Shape which gives you more flexibility than the pre-defined Kinetic objects. 解决方案包括使用自定义的Kinetic.Shape,它比预定义的Kinetic对象具有更大的灵活性。

A Kinetic.Shape gives you a full canvas context to work with. Kinetic.Shape为您提供了完整的画布环境。

You can use context.moveTo and multiple context.lineTo to let the user drag-draw freehand lines. 您可以使用context.moveTo和多个context.lineTo来让用户拖动手绘线。

With a full context, you also can use compositing. 在完整的上下文中,您也可以使用合成。

Specifically, you can use “destination-out” compositing which causes any new line drawn to act as an eraser. 具体来说,您可以使用“目标输出”合成,这会使绘制的任何新线都充当橡皮擦。

With "destination-out" ... any previously drawn lines are “erased” by the new line. 使用“目标输出” ...,新行将“擦除”任何先前绘制的线。

An outline of your solution: 解决方案概述:

  • Have the user drag-draw a polyline on the canvas by capturing all the individual points as they drag. 让用户在拖动时捕获所有单个点,从而在画布上拖动多段线。
  • Capture whether the user was in “draw” or “erase” mode when dragging that line. 拖动该行时捕获用户是处于“绘制”还是“擦除”模式。
  • Use a custom Kinetic.Shape to either draw a line or use compositing to erase line. 使用自定义的Kinetic.Shape绘制线条或使用合成擦除线条。
  • In “draw” mode, set context.globalCompositeOperation=”source-over” and draw that line. 在“绘制”模式下,设置context.globalCompositeOperation =“ source-over”并绘制该线。
  • In “erase” mode, set context.globalCompositeOperation=”destination-out” drag an eraser. 在“擦除”模式下,设置context.globalCompositeOperation =“ destination-out”拖动橡皮擦。

One complication is that the context Kinetic.Shape gives you is a wrapper around a true canvas context. 一种复杂的情况是,Kinetic.Shape上下文为您提供了围绕真实画布上下文的包装。

It limits you to one context.beginPath and you can only use 1 composite mode per context.beginPath. 它将您限制为一个context.beginPath,并且每个context.beginPath您只能使用1个复合模式。 Since you need to have multiple compositing modes (drawing vs eraser), you need to know how to get a true context canvas instead of Kinetic.Shapes wrapped context. 由于需要多种合成模式(绘图与橡皮擦),因此需要了解如何获取真实的上下文画布,而不是Kinetic.Shapes包裹的上下文。

Here's how: 这是如何做:

var sketchpad = new Kinetic.Shape({

    drawFunc: function(context) {

        // get a true canvas context, not a "wrapped" context
        context=this.getContext()._context;

        // save the context state
        context.save();

        // then you can use multiple beginPath's 
        // and therefore have multiple composites.

        context.beginPath();
        context.globalCompositeOperation="source-over";
        // draw a polyline using your saved line-points
        context.stroke();

        context.beginPath();
        context.globalCompositeOperation="destination-out";
        // draw a polyline which acts like an eraser
        context.stroke();


        // restore the context state
        context.restore();

    },
    stroke: 'black',
    strokeWidth: 4
});

"Is there anyone that has done this" “有没有这样做的人”

I'm afraid there isnt. 恐怕没有。 The line which you have drawed is an object. 您绘制的线是一个对象。 Its simple to remove it as an whole object. 将其作为一个整体删除很简单。

If you wan't use case like eraser it would be quit difficult to divide the line to several parts which stay in drawin and that part which does not. 如果您不使用橡皮擦之类的情况,则很难将线分为留在画板中的几部分,而不留在画板中的那部分。

How ever, if your line is a group of pixels that would be much easier, but group of pixels are not a line. 但是,如果您的线是一组像素,那会容易得多,但一组像素不是线。

我知道这真的很晚,但是当我搜索橡皮擦时,我首先找到了此链接,但是我没有找到一个好的解决方案,所以我创建了一个新的解决方案,她的方法是: 如何使用dynamicjs 5.1.0制作橡皮擦在多层上表演?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM