问题
After I draw polygon i would like to change opacity of canvas out of polygon i just drawn. I think it might have something to do with clipping but im not sure. Polygon and lines inside should have 100% opacity but everything else (background and lines outside polygon should have 50% opacity)
prototypefabric.polygon = {
drawPolygon: function () {
canvas.on('mouse:down', function (options) {
if (options.target && options.target.id == pointArray[0].id) {
prototypefabric.polygon.generatePolygon(pointArray);
}
if (polygonMode) {
prototypefabric.polygon.addPoint(options);
}
});
canvas.on('mouse:up', function (options) {
});
canvas.on('mouse:move', function (options) {
if (activeLine && activeLine.class == "line") {
var pointer = canvas.getPointer(options.e);
activeLine.set({x2: pointer.x, y2: pointer.y});
var points = activeShape.get("points");
points[pointArray.length] = {
x: pointer.x,
y: pointer.y
};
activeShape.set({
points: points
});
canvas.renderAll();
}
canvas.renderAll();
});
polygonMode = true;
pointArray = new Array();
lineArray = new Array();
activeLine;
},
addPoint: function (options) {
var random = Math.floor(Math.random() * (max - min + 1)) + min;
var id = new Date().getTime() + random;
var circle = new fabric.Circle({
radius: 5,
fill: '#ffffff',
stroke: '#333333',
strokeWidth: 0.5,
left: (options.e.layerX / canvas.getZoom()),
top: (options.e.layerY / canvas.getZoom()),
selectable: false,
hasBorders: false,
hasControls: false,
originX: 'center',
originY: 'center',
id: id
});
if (pointArray.length == 0) {
circle.set({
fill: '#BB2026'
})
}
var points = [(options.e.layerX / canvas.getZoom()), (options.e.layerY / canvas.getZoom()), (options.e.layerX / canvas.getZoom()), (options.e.layerY / canvas.getZoom())];
line = new fabric.Line(points, {
strokeWidth: 2,
fill: '#999999',
stroke: 'green',
class: 'line',
originX: 'center',
originY: 'center',
selectable: false,
hasBorders: false,
hasControls: false,
evented: false
});
if (activeShape) {
var pos = canvas.getPointer(options.e);
var points = activeShape.get("points");
points.push({
x: pos.x,
y: pos.y
});
var polygon = new fabric.Polygon(points, {
stroke: '#333333',
strokeWidth: 1,
fill: '#cccccc',
opacity: 0.3,
selectable: false,
hasBorders: false,
hasControls: false,
evented: false,
});
canvas.remove(activeShape);
canvas.add(polygon);
activeShape = polygon;
canvas.renderAll();
console.log(points);
} else {
var polyPoint = [{x: (options.e.layerX / canvas.getZoom()), y: (options.e.layerY / canvas.getZoom())}];
var polygon = new fabric.Polygon(polyPoint, {
stroke: '#333333',
strokeWidth: 1,
fill: '#cccccc',
opacity: 0.3,
selectable: false,
hasBorders: false,
hasControls: false,
evented: false,
});
activeShape = polygon;
canvas.add(polygon);
}
activeLine = line;
pointArray.push(circle);
lineArray.push(line);
canvas.add(line);
canvas.add(circle);
canvas.selection = false;
},
generatePolygon: function (pointArray) {
var points = new Array();
$.each(pointArray, function (index, point) {
points.push({
x: point.left,
y: point.top,
});
canvas.remove(point);
});
$.each(lineArray, function (index, line) {
canvas.remove(line);
});
canvas.remove(activeShape).remove(activeLine);
var polygon = new fabric.Polygon(points, {
stroke: '#333333',
strokeWidth: 0.5,
fill: 'rgb(255, 255, 255, 0)',
hasBorders: false,
hasControls: false,
id: 'plotOutline'
});
canvas.add(polygon);
var overlayRect = new fabric.Rect({
width: canvas.get("width"),
height: canvas.get("height"),
selectable: false,
fill: "rgb(255, 255, 255, 0.5)"
});
var clippingPolygon = new fabric.Polygon(polygon.points, {
left: -(overlayRect.get("width") / 2) - polygon.get("left") * -1,
top: -(overlayRect.get("height") / 2) - polygon.get("top") * -1
});
var clipGroup = new fabric.Group([clippingPolygon], {
inverted: true
});
overlayRect.clipPath = clipGroup;
canvas.add(overlayRect);
console.log(JSON.stringify(polygon.points) + 'points');
if (polygon.id == 'plotOutline') {
$('#saveStepOne').prop('disabled', false);
}
activeLine = null;
activeShape = null;
polygonMode = false;
canvas.selection = true;
}
};
drawing polygon
回答1:
This is how you can obtain it the opacity of everything outside a specific polygon (that could be a previously dynamically created). I just don't know how to get the drawing line outside to also have the opacity applied:
You can also check this demo SandBox: https://codesandbox.io/s/stackoverflow-60810389-fabric-js-362-vm92q
var canvas = new fabric.Canvas("canvas", {
isDrawingMode: true
});
fabric.Image.fromURL("https://picsum.photos/500/350", function(img) {
// add background image
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
});
var originalPolygon = new fabric.Polygon(
[{ x: 0, y: 0 }, { x: 250, y: 0 }, { x: 220, y: 140 }, { x: 0, y: 140 }],
{
left: 10,
top: 10,
fill: "white",
stroke: "red",
strokeWidth: 2,
selectable: false
}
);
// An Overlay that covers the whole canvas
var overlayRect = new fabric.Rect({
width: canvas.get("width"),
height: canvas.get("height"),
selectable: false,
fill: "rgb(255, 255, 255, 0.8)"
});
// The clipPath object uses top,left,scale.... to position itself starting from the center of the object that is clipping
// For more details check https://github.com/fabricjs/api-discussion/issues/1
var clippingPolygon = new fabric.Polygon(originalPolygon.points, {
left: -(overlayRect.get("width") / 2) - originalPolygon.get("left") * -1,
top: -(overlayRect.get("height") / 2) - originalPolygon.get("top") * -1
});
var clipGroup = new fabric.Group([clippingPolygon], {
inverted: true
});
overlayRect.clipPath = clipGroup;
// Comment adding of the orgiinalPolygon to see better the clipping effect
canvas.add(originalPolygon);
canvas.add(overlayRect);
canvas.renderAll();
body {
font-family: sans-serif;
}
canvas {
border: 2px solid #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.2/fabric.min.js"></script>
<div id="app">
<canvas id="canvas" width="500" height="350"></canvas>
</div>
来源:https://stackoverflow.com/questions/60810389/setting-opacity-to-canvas-fabricjs