替换FabricJS中的对象?

时间:2019-12-16 14:38:04

标签: javascript fabricjs

要实现撤消/重做功能,我构造了一个数组“ history”,该数组填充了基于canvas.on()事件的最新更改。

console.log转储:

History: 
(3) […]
​
0: Object { target: {…} } //first object added
​
1: Object { e: mouseup, target: {…}, transform: {…}, … } //first object modified
​
2: Object { target: {…} } //another object added
​
length: 3

要返回更改堆栈,我想使用history[step].target,它包含现阶段(step)的修改后的对象。

我现在正在寻找一种方法来覆盖fabric对象数组中的对象。

函数canvas.item(0)将对象赋予当前画布上的位置0,但如何用另一个对象(来自history[].target数组的对象)覆盖该对象?

注意:我发现的关于撤消/重做的解决方案似乎是基于将整个画布序列化为JSON并将其保存到JSON数组中的。我不想执行此操作,因为似乎总是不进行序列化/反序列化整个画布(其中包含x个对象)只是为了撤消很小的更改,并且历史记录中包含有关更改的内容和对象的许多有用信息,这似乎并不复杂。

注2:当然,我可能只能先canvas.remove(canvas.item(0))然后再canvas.add(history[x].target),但是不幸的是,当有多个对象时,这会弄乱我的对象堆栈,因为canvas.item(1)变成了{{1} },现在还原的更改将变为canvas.item(0)(或2、3 ... ect,具体取决于画布上的项目数)。然后,当我根据对象堆栈中的位置显示对象列表时,该对象将重新排列,并可能使用户感到困惑。

2 个答案:

答案 0 :(得分:2)

这是一个简单的例子。

给定2在画布上,一个函数将在这2个中间添加一个,而另一个将替换位置0处的那个。

canvas#insertAt确实可以按照@ gabriele-petroli的建议工作

var c = new fabric.Canvas('c');

c.add(new fabric.Rect({ fill: 'blue', width: 100, height: 100 }));
c.add(new fabric.Rect({ fill: 'green', left: 150, width: 100, height: 100 }));

var redRect = new fabric.Rect({ fill: 'red', left: 75, width: 100, height: 100 });
var purpleRect = new fabric.Rect({ fill: 'purple', left: 0, 
width: 100, height: 100 });

setTimeout(function() {
  c.insertAt(purpleRect, 0, true);
  c.insertAt(redRect, 1);
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.5.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500" ></canvas>

答案 1 :(得分:1)

据我所知,不可能覆盖对象。

但这可能对您的Note2有帮助:

除了Gabriele Petriolis注释,您还可以在插入后将对象放置在堆栈中:

void handlePurchase(Purchase purchase) {



BillingClient client = BillingClient.newBuilder(NewAdActivity.this)
        .enablePendingPurchases() 
        .setListener(this)
        .build();


if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
     System.out.println("item successfully purchased");


        if (!purchase.isAcknowledged()) {


                    ConsumeParams consumeParams = ConsumeParams.newBuilder()
                        .setPurchaseToken(purchase.getPurchaseToken())
                        .setDeveloperPayload(purchase.getDeveloperPayload())
                        .build();


                     ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
                    @Override
                    public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                          if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchaseToken != null) {
                              System.out.println("SUCCESSFULLY consumed PURCHASE");
                              providecontent();

                           } 
                        else { 
                              System.out.println("FAILED TO consume:”);
                            }

                    }

                };

                client.consumeAsync(consumeParams, consumeResponseListener); 



        }

    }



}

请参阅:http://fabricjs.com/docs/fabric.Canvas.html