`How to get the relative position of the sub item contained in 'activeselection' in fabricjs'? - fabricjs

Fabricjs version: v4.6.0
const selection = new fabric.ActiveSelection(objs, { canvas })
const childs = selection.getObjects()
console.log('first child position:', childs[0].left, childs[1].top) // -120, -243.5
The 'left' or 'top' I get is negative, which seems to be wrong

Related

How do I a multiselect programatically in fabric.js?

I'm trying to select a few fabric.js objects so I can manipulate them together.
First I load an SVG file as a fabric group.
Second I click on the button to filter objects and "select" objects that I want to make the 'active selection out of.
In this example, you can see the bounding box is not where you'd expect it to be. This is causing some issues in my app.
I've seen in the 'gotchas' about setCoords() and I'm not sure if this is related to that or how it would apply here since I haven't moved anything in the group x,y.
This example codepen an attempt to show a simple example.
https://codepen.io/bencbaumann/pen/PodoeXq?editors=1010
html
<button id="multiselect">Multi Select</button>
<canvas id="canvas">
js
const canvas = new fabric.Canvas("canvas", {
height: 500,
width: 500
});
var url = "https://assets.codepen.io/496640/dots3.svg";
fabric.loadSVGFromURL(url, function (objects, options) {
const svgObj = fabric.util.groupSVGElements(objects, options);
canvas.add(svgObj);
canvas.renderAll();
});
function selectObjectsByIds({ canvas, ids }) {
console.log("ids", ids); // show [ids] that we are trying to select
const objects = canvas.getObjects(); // get objects in canvas
console.log("objects.length:", objects.length);
console.log("objs:", objects);
const objectsWithId = objects.filter((o) => o.id);
const objectsWithChildren = objects.filter((o) => o._objects);
const childrenWithId = objectsWithChildren
.map((o) => o._objects)
.flat()
.filter((o) => o.id);
const selected_ids = [...objectsWithId, ...childrenWithId];
console.log(selected_ids)
const selectedObjects = selected_ids.filter((o) => ids.includes(o.id));
canvas.discardActiveObject();
console.log('selectedObjects: ', selectedObjects)
var sel = new fabric.ActiveSelection(selectedObjects, {
canvas: canvas,
});
canvas.setActiveObject(sel);
canvas.requestRenderAll();
}
var $ = function(id){return document.getElementById(id)};
var multiselect = $('multiselect')
multiselect.onclick = () => selectObjectsByIds({canvas, ids: ['dot']})
the bounding box is not where it should be. I expect the bounding box to be around the objects in my selection.
The 3 green dots have the id of 'dot'

Render svg from svg.js inside pixi.js

Hi just testing to see if I can render an SVG created using svg.js inside a PIXI application. Codpen here
import * as PIXI from 'https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.5.4/browser/pixi.min.mjs'
const draw = SVG().addTo('body').attr({
viewBox: '0 0 100 100',
width: '100',
height: '100',
"enable-background":"new 0 0 64 64",
style: 'display: block'
})
draw.circle(100).x(50).fill('red')
console.log(draw.node)
const app = new PIXI.Application({
resolution: window.deviceAspectRatio || 1,
resizeTo: window
})
document.body.appendChild(app.view)
const {width,height} = app.renderer.view
console.log(width,height)
PIXI.Loader.shared.onProgress.add(loadProgressHandler)
PIXI.Loader.shared.add("svg",draw.node).load(setup)
function loadProgressHandler(){
console.log('loading')
}
function setup(){
console.log("setup")
const svgCanvas = new PIXI.Sprite(PIXI.Loader.shared.resources.svg.texture)
console.log(svgCanvas)
const container = new PIXI.Container()
container.addChild(svgCanvas)
app.stage.addChild(container)
}
Not getting any errors but also not rendering svg on canvas. Thanks in advance.

KonvaJS, positioning editable text inputs

I need to position text inputs at various places on a KonvaJS layer. I found the following code at https://konvajs.github.io/docs/sandbox/Editable_Text.html and I'm trying to understand the textPosition, stageBox, and areaPosition vars in this code. I want my stage centered in the browser window, but when I do that, the textarea (activated on dblclick) pops up way off to the left. I can't get a console readout of the x/y coordinates, so I can't visualize how the positioning works &, thus, how to change it. Can anyone explain, or point me in the right direction?
var text_overlay = new Konva.Layer();
stage.add(text_overlay);
var textNode = new Konva.Text({
text: 'Some text here',
x: 20,
y: 50,
fontSize: 20
});
text_overlay.add(textNode);
text_overlay.draw();
textNode.on('dblclick', () => {
// create textarea over canvas with absolute position
// first we need to find its position
var textPosition = textNode.getAbsolutePosition();
var stageBox = stage.getContainer().getBoundingClientRect();
var areaPosition = {
x: textPosition.x + stageBox.left,
y: textPosition.y + stageBox.top
};
// create textarea and style it
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.value = textNode.text();
textarea.style.position = 'absolute';
textarea.style.top = areaPosition.y + 'px';
textarea.style.left = areaPosition.x + 'px';
textarea.style.width = textNode.width();
textarea.focus();
textarea.addEventListener('keydown', function (e) {
// hide on enter
if (e.keyCode === 13) {
textNode.text(textarea.value);
text_overlay.draw();
document.body.removeChild(textarea);
}
});
})
// add the layer to the stage
stage.add(text_overlay);
UPDATE: I solved part of the problem--the textarea showing up way out of position. You need to use 2 divs in the HTML file instead of one, like so:
<div id="containerWrapper" align="center"><div id="container"></div></div>
Thanks to Frens' answer on Draw border edges of the Konvajs container Stage in html for that one!

Cut text to another line inside joint js element

I am doing a diagram in jointjs and I have a rect with a text inside, but that text is so long that does not fit inside the rectangle. How can I cut lines inside it so it all fits at the same size of the rectangle ??
((escape by itself does not work))
You can use a utility that joint js has called breaktext, assigning the result to a var :
var wraptext = joint.util.breakText('yourtext|escapejs', {
width: 300
});
Then, set that var as text attr of the rect:
var rectname = new joint.shapes.custom.Rect({
size: { width: 680, height: 75 },
attrs: {
text: {
text: wraptext,
}
}
});
Width in this case would be the parameter that determines the long of each text break
Hope it helps !!

Is there a way to crop only the design from a the canvas and ignoring all the white/transparent space?

I have a canvas built using fabricJS with the dimension of 600x500. I have added an image to this canvas which is of size 200x300 and also a text element just below it.
$canvasObj.toDataURL();
exports the whole canvas area including the white spaces surrounding the design on the canvas.
Is there a way to get the cropped output of the design on the canvas alone instead of all the whitespace?
This can be done by cloning objects to a group, getting the group boundingRect, and then passing the boundingRect parameters to toDataUrl() function (see fiddle).
e.g.
// make a new group
var myGroup = new fabric.Group();
canvas.add(myGroup);
// ensure originX/Y 'center' is being used, as text uses left/top by default.
myGroup.set({ originX: 'center', originY: 'center' });
// put canvas things in new group
var i = canvas.getObjects().length;
while (i--) {
var objType = canvas.item(i).get('type');
if (objType==="image" || objType==="text" || objType==="itext" || objType==="rect") {
var clone = fabric.util.object.clone(canvas.item(i));
myGroup.addWithUpdate(clone).setCoords();
// remove original lone object
canvas.remove(canvas.item(i));
}
}
canvas.renderAll();
// get bounding rect for new group
var i = canvas.getObjects().length;
while (i--) {
var objType = canvas.item(i).get('type');
if (objType==="group") {
var br = canvas.item(i).getBoundingRect();
}
}
fabric.log('cropped png dataURL: ', canvas.toDataURL({
format: 'png',
left: br.left,
top: br.top,
width: br.width,
height: br.height
}));
p.s. I should probably mention that i've not worked with image types, so i just guessed that it's called 'image'..

Resources