2016-11-29 11 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; 

Граница окрашена правильно, без перекрытия. Итак, временный холст от ответа Януша больше не нужен. Для моей прежней fabric.js 1.5.0 ответ от Януша решил проблему.

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

Большое спасибо! Это именно то, что я имел в виду. –