2 years ago
#61344

Gerd Torf
FabricJS - Object is removed if top left corner is moved out of viewport
I have a canvas. The users are able to draw rectangles in it using fabricjs. The second feature is that you are able to move around in the canvas (called panning). When I am in the drawing mode and than start to pan around, the rectangle disappears if I am moving the top left corner of the rectangle out of the canvas. If you move the viewport, so that the top left corner is in the canvas back again, the rectangle becomes visible again. If you move other corners of the rectangle out of the canvas, the rectangle stays visible.
Is there a way to prevent that behavior?
Steps to reproduce:
- use snippet below
- click the "rect" button
- hold the left mouse key and draw a new rectangle (keep the mouse key pressed) - this will create a yellow rect
- press and hold the "alt" key on your keyboard and move the mouse (the mouse key is still pressed) - you are panning around now
- move the view, so that the top left corner of the rect will be outside the canvas - the yellow rect will disappear
Goal:
The rect will stay visible even if I am moving the top left corner out of the canvas.
(function() {
var drawMode = false
var isDrawing = false
var isPanning = false
document.getElementById("rect").onclick = function() {
drawMode = !drawMode
document.getElementById("rect").style["background-color"] = drawMode ? "lightblue" : "lightgrey"
}
var canvas = new fabric.Canvas("canvas")
canvas.on("mouse:down", function(opt) {
var evt = opt.e
this.selection = false
if (drawMode) {
isDrawing = true
this.startPosX = evt.clientX
this.startPosY = evt.clientY
this.drawRect = new fabric.Rect({
left: evt.clientX,
top: evt.clientY,
fill: "yellow",
})
canvas.add(this.drawRect)
} else if (evt.altKey === true) {
isPanning = true
this.lastPosX = evt.clientX
this.lastPosY = evt.clientY
}
})
canvas.on("mouse:move", function(opt) {
var evt = opt.e
if (evt.altKey === true && isPanning) {
var vpt = this.viewportTransform
if (this.lastPosX) vpt[4] += evt.clientX - this.lastPosX
if (this.lastPosY) vpt[5] += evt.clientY - this.lastPosY
this.requestRenderAll()
this.lastPosX = evt.clientX
this.lastPosY = evt.clientY
} else if (isDrawing) {
this.drawRect.set({
width: evt.clientX - this.startPosX,
height: evt.clientY - this.startPosY,
})
canvas.renderAll()
}
})
canvas.on("mouse:up", function(opt) {
// on mouse up we want to recalculate new interaction
// for all objects, so we call setViewportTransform
var evt = opt.e
this.setViewportTransform(this.viewportTransform)
isPanning = false
this.selection = true
if (isDrawing) {
this.drawRect.set({
width: evt.clientX - this.startPosX,
height: evt.clientY - this.startPosY,
fill: "orange",
})
isDrawing = false
}
})
document.addEventListener("keydown", function(opt) {
if (opt.key === "Alt") {
if (!isPanning) isPanning = true
if (drawMode) drawMode = false
}
})
document.addEventListener("keyup", function(opt) {
if (opt.key === "Alt") {
if (isPanning) isPanning = false
}
})
})()
<html>
<body style="margin: 0">
<canvas id="canvas" width=500 height=300 style="border: 1px solid blue"></canvas>
<h3>Tools</h3>
<button id="rect" style="background-color: lightgrey">rect</button>
<h3>Features</h3>
<ul>
<li>draw rectangle (activate draw mode with above button</li>
<li>move around (need to hold alt-key)</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>
</body>
</html>
fabricjs
0 Answers
Your Answer