在EaselJs中创建橡皮擦 - 下一步是什么

时间:2015-08-06 10:53:55

标签: javascript html5 canvas easeljs

我想在easelJS上编写位图擦除器。我想,我已经走了一半的路要走......

这是演示: http://jsfiddle.net/bordeux/g2Lwvsuv/2/

和我的代码:

var example = function() {
    this.constructor.apply(this, arguments);
};

example.prototype.constructor  = function() {
    this.$canvas = $("canvas");
    this.container = {};
    this.objects = {};
    this.resizeEvents = [];
    this.prepareCanvas();
    this.refreshSize();
    this.bindEvents();
};

example.prototype.bindEvents = function() {
    var self = this;
    $(window).resize(function(){
        self.refreshSize();
    });
};

example.prototype.refreshSize = function() {
    this.stage.canvas.width = window.innerWidth;
    this.stage.canvas.height = window.innerHeight;

    this.resizeEvents.forEach(function(item) {
        item();
    });
};

example.prototype.getObject = function(name) {
    return this.objects[name];
};

example.prototype.setObject = function(name, obj) {
    this.objects[name] = obj;
    return obj;
};

example.prototype.addResizeEvent = function(foo) {
    this.resizeEvents.push(foo);
    return this;
};

example.prototype.initCursor = function() {
    var self = this;
    var size = 50;

    /**
     * Circle cursor
     */
    var circle = new createjs.Shape();
    circle.graphics.setStrokeStyle(2).beginStroke("#171717").drawCircle(0, 0, size);

    /**
     * Hit area
     */
    var hit = new createjs.Shape();
    hit.graphics.beginFill("#000").drawCircle(0, 0, size);
    circle.hitArea = hit;

    var container = this.getContainer("cursor");
    container.addChild(circle);

    this.stage.on("stagemousemove", function(evt) {
        circle.setTransform(evt.stageX, evt.stageY);
        this.setChildIndex( container, this.getNumChildren()-1);
    });

    var drawing = this.setObject("image.mask", new createjs.Shape());
    drawing.visible = false;
    var lastPoint = new createjs.Point();

    container.addChild(drawing);

    circle.on("mousedown", function(event) {
        lastPoint.x = event.stageX;
        lastPoint.y = event.stageY;
    });

    circle.on("pressmove", function(event) {
        drawing.graphics
            .setStrokeStyle(100, "round", "round")
            .beginStroke("rgba(255, 255, 255, 0.2)")
            .beginRadialGradientFill(
            ["rgba(0,0,0,0)", "rgba(0,0,0,1)"],
            [0.1, 1],
            50, 50, 0,
            50, 50, 50
        )
            .moveTo(lastPoint.x, lastPoint.y)
            .lt(event.stageX, event.stageY);

        lastPoint.x = event.stageX;
        lastPoint.y = event.stageY;
        self.updateCache();
    });

    circle.on("pressup", function(event) {
        self.updateCache();
    });
};

example.prototype.updateCache = function(update) {
    (update === undefined) && (update = false);

    var drawingCanvas = this.getObject("image.mask");
    var image = this.getObject("image");

    if (update) {
        drawingCanvas.updateCache();
    } else {
        drawingCanvas.cache(0, 0, image.image.naturalWidth, image.image.naturalHeight);
    }

    image.filters = [
        new createjs.AlphaMaskFilter(drawingCanvas.cacheCanvas)
    ];

    if (update) {
        image.updateCache(0, 0, image.image.naturalWidth, image.image.naturalHeight);
    } else {
        image.cache(0, 0, image.image.naturalWidth, image.image.naturalHeight);
    }
};

example.prototype.prepareCanvas = function() {
    this.stage = new createjs.Stage(this.$canvas[0]);
    createjs.Ticker.setFPS(60);
    createjs.Ticker.addEventListener("tick", this.stage);

    this.initCursor();
    this.loadImage();
};

/**
 * Get container. If not exist, this function create new one
 * @param {String} name
 * @returns {createjs.Container}
 */
example.prototype.getContainer = function(name) {
    if(this.container[name]){
        return this.container[name];
    }
    this.container[name] = new createjs.Container();
    this.stage.addChild(this.container[name]);

    return this.container[name];
};

example.prototype.loadImage = function() {
    var self = this;
    var url = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Logo_Google_2013_Official.svg/1280px-Logo_Google_2013_Official.svg.png";

    var background = this.setObject("image.background", new createjs.Shape());
    this.getContainer("image").addChild(background);

    var image = null;
    return utils.image(url).then(function(img){
        image = img;
        self.getContainer("image").addChild(self.setObject(
            "image",
            new createjs.Bitmap(img)
        ));
        self.updateCache(false);
        return utils.image("http://i.imgur.com/JKaeYwv.png");
    }).then(function(imgBackground){
        background
            .graphics
            .beginBitmapFill(imgBackground,'repeat')
            .drawRect(0,0, image.naturalWidth, image.naturalHeight);
    });
};

utils = {};
utils.image = function(url){
    var deferred = Q.defer();
    //deferred.resolve(text);
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.onload = function(){
        deferred.resolve(this);
    };

    img.onerror = function(){
        deferred.reject(arguments);
    };

    img.src = url;
    return deferred.promise;
};

$(function(){
    var test =  new example();
});

但是当我在画布上画一些东西时,我的绘画路径显示了面具背后的图像......这是我想要的反对结果。

我想删除部分图像(如Photoshop中的橡皮擦)。我不知道接下来该做什么......

由于

1 个答案:

答案 0 :(得分:4)

您可以将compositeOperation与图层结合使用或缓存到" erase"内容。例如,如果使用updateCache("source-over"),则会在现有缓存​​上绘制当前可视内容(正常合成)。但是,如果您使用updateCache("destination-out"),那么基本上会从现有缓存中打出当前内容,从而为您提供橡皮擦效果。

以下是一个简单的示例:http://jsfiddle.net/17xec9y5/4