2016-11-29 137 views
0

我想用fabric.js自由繪製形狀。例如,大綱是20px(這樣用戶可以清楚地看到它)。fabric.js:如何用筆畫製作獨特,透明的形狀?

用戶繪製完畢後,應該用與輪廓相同的顏色填充形狀。

整件事應該是半透明的。不幸的是,這會導致輪廓和填充之間的重疊變得不那麼透明,併爲該形狀繪製一個奇怪的「內部輪廓」。

有沒有辦法讓形狀獨特的半透明?

也許一個技巧是:在用戶繪製完形狀之後,將該形狀「加寬」輪廓厚度的一半並將輪廓厚度設置爲1.這樣做有可能嗎?

查看此https://jsfiddle.net/4ypdwe9o/或以下爲例。

var canvas = new fabric.Canvas('c', { 
 
    isDrawingMode: true, 
 
    
 
}); 
 
    
 
canvas.freeDrawingBrush.width = 10; 
 
canvas.freeDrawingBrush.color = 'rgb(255, 0, 0)'; 
 

 
canvas.on('mouse:up', function() { 
 

 
    canvas.getObjects().forEach(o => { 
 
    o.fill = 'rgb(255, 0, 0)'; 
 
    o.opacity = 0.5; 
 
    }); 
 
    canvas.renderAll(); 
 
})
canvas { 
 
    border: 1px solid #ccc; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script> 
 
<canvas id="c" width="600" height="600"></canvas>

回答

1

在fabric.js 1.7.3,他們有另一個實現。當我使用

fabricCanvasObject.getObjects('path').slice(-1)[0].setFill("red"); 
fabricCanvasObject.getObjects('path').slice(-1)[0].setOpacity(0.5); 

,而不是

fabricCanvasObject.getObjects('path').slice(-1)[0].fill = "red"; 
fabricCanvasObject.getObjects('path').slice(-1)[0].opacity = 0.5; 

的邊界繪製正確,無重疊。所以,Janusz的答案暫時的畫布不再需要了。對於我以前的fabric.js 1.5.0,Janusz的回答解決了這個問題。

1

Jetic,

您差不多完成了你的邏輯。除了使用「不透明度」使用RGBA的:

canvas.getObjects().forEach(o => { 
    o.fill = 'rgba(255, 0, 0, 0.5)'; 
    o.stroke = 'rgba(255, 0, 0, 0)'; 
    // o.opacity = 0.5; 
    }); 
    canvas.renderAll(); 
+0

謝謝,我認爲是一樣的,但通過這種方式,輪廓消失後形狀繪製(筆畫α0)。這看起來像形狀比用戶想要的「小」。 –

1

這是一個有點棘手,但可以使用臨時的帆布來解決。所以,你首先使用純色填充臨時畫布上繪製的路徑,然後將其複製到這樣的主畫布:

//create temporary canvas 
var tmpCanvas = document.createElement("canvas"); 
tmpCanvas.width = canvas.width; 
tmpCanvas.height = canvas.height; 
var tmpCtx = tmpCanvas.getContext("2d"); 

//remember the original render function 
var pathRender = fabric.Path.prototype.render; 

//override the Path render function 
fabric.util.object.extend(fabric.Path.prototype, { 
    render: function(ctx, noTransform) { 

    var opacity = this.opacity; 

    //render the path with solid fill on the temp canvas 
    this.opacity = 1; 
    tmpCtx.clearRect(0, 0, tmpCanvas.width, tmpCanvas.height); 
    pathRender.apply(this, [tmpCtx]); 
    this.opacity = opacity; 

    //copy the path from the temp canvas 
    ctx.globalAlpha = opacity; 
    ctx.drawImage(tmpCanvas, 0, 0); 

    } 
}); 

見plunker這裏:https://plnkr.co/edit/r1Gs2wIoWSB0nSS32SrL?p=preview

+0

非常感謝!這正是我的意思。 –