text over imported svg with fabricjs - svg

I'm importing several svgs that are all created from the same image and layered on top of each other. I would like to add text centered over a certain svg/textarea path. And then scale textarea to fit the text provided with a min size. And ive confused myself. I have no idea anymore? I deleted everything and started over direction would be very helpful. Heres what i got.
var canvas = new fabric.Canvas('canvas');
fabric.loadSVGFromURL('/1-man.svg', function(objects, options) {
var obj = fabric.util.groupSVGElements(objects, options);
canvas.add(obj).renderAll();
});
fabric.loadSVGFromURL('/1-man-cutout.svg', function(objects, options)
{
var obj = fabric.util.groupSVGElements(objects, options);
canvas.add(obj).renderAll();
});
fabric.loadSVGFromURL('/textarea.svg', function(objects, options) {
var obj2 = fabric.util.groupSVGElements(objects, options);
canvas.add(obj2).renderAll();
});
var text = new fabric.Text("Hello", {
fontFamily: 'ubuntu',
fontSize: 300,
textAlign: "center",
});
canvas.add(text);

Brain was dead i suppose.... took about a min this morning.. Ill keep it for a lesson on sleeping on it.
text.set('left', (objects[0].width - text.width)/2);
text.set('top', objects[0].top + 5);
canvas.add(obj2, text).renderAll();

Related

Polygon rendering with pixijs

I'm trying to display more than 6000 Polygons on a mobile device.
Currently, I'm doing this with SVG paths in Android WebView using the d3.js library.
It works but I have to deal with performance issues, my map becomes very laggy when I drag my map or zoom.
My Idea now is to try the same with pixijs. My data comes originally from ESRI Shapefiles. I'm convert these Shapefiles to GeoJSON and then to SVG. My array of vertices looks like this, which I'm trying to pass to the drawPolygon function
0: 994.9867684400124
1: 22.308409862458518
2: 1042.2789743912592
3: 61.07148769269074
But when I try to render these polygon nothing being displayed. This is my code:
var renderer = PIXI.autoDetectRenderer(1800, 1800, { backgroundColor: 0x000000, antialias: true });
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
var graphics = new PIXI.Graphics();
var totalShapes = feat.features.length;
for (var i = 1; i <= totalShapes -1; i++) {
var shape = feat.features[i];
var geometry = shape.geometry.bbox;
graphics.beginFill(0xe74c3c);
graphics.drawPolygon([ geometry]);
graphics.endFill();
stage.addChild(graphics);
renderer.render(stage);
}
Can someone help me or could suggest me a different way?
I have not seen that way of initializing a pixie project.
Usually you add the application to the html document like:
var app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x2c3e50
});
document.body.appendChild(app.view);
If you do this you can add your draw calls to the setup of the application:
app.loader.load(startup);
function startup()
{
var g = new PIXI.Graphics();
g.beginFill(0x5d0015);
g.drawPolygon(
10, 10, 120, 100, 120, 200, 70, 200
);
g.endFill();
app.stage.addChild(g);
}
This will render the polygon once.

Can't load SVG from URL

I want to load different shapes in FabricJS based Canvas using loadSVGFromURL(), but can't. Documentation is also not complete on this. I just want a complete example. I can load it from string, but string creates spaces which creates problems when rendering. Here is my code:
var canvas = new fabric.Canvas('canvas');
fabric.loadSVGFromURL('BlueFlower.svg', function (objects) {
var SVG = fabric.util.groupSVGElements(objects, options);
canvas.add(SVG).centerObject(SVG).renderAll();
SVG.setCoords();
});
I have done an example on jsfiddle, that I create two objects and I load an svg image from url, you can take a look.
Here is an example
The snippet for load svg is this:
var site_url = 'http://fabricjs.com/assets/1.svg';
fabric.loadSVGFromURL(site_url, function(objects) {
var group = new fabric.PathGroup(objects, {
left: 165,
top: 100,
width: 295,
height: 211
});
canvas.add(group);
canvas.renderAll();
});

Fabricjs: entering IText with click on canvas

The objective of this jsfiddle is the following:
User clicks on canvas
A cursor shows up where the user clicked
User can enter text
I tried to use IText enterEditing method right after the user clicks on the canvas, but the cursor does not show up, so the user don't know they can enter text. In addition, in Chrome and Firefox the user cannot enter text at all. Any ideas?
Javascript
var canvas = new fabric.Canvas('c');
canvas.on('mouse:down', function(options) {
if (options.target == null)
addText(options.e);
});
function addText(e) {
var text = new fabric.IText('',{
left: e.offsetX,
top: e.offsetY
});
canvas.add(text);
text.enterEditing();
}
Try the following code, you need to set your text object as active object in canvas.
var text = new fabric.IText('',{
left: e.offsetX,
top: e.offsetY
});
canvas.add(text).setActiveObject(text);
text.enterEditing();
Try this fiddle i upaded using this code,Hope it can help you somewhat
var canvas = new fabric.Canvas('c');
canvas.on('mouse:down', function(options) {
if (options.target == null)
addText(options.e);
});
function addText(e) {
var custontxt=new fabric.IText('Tap and Type', {
fontFamily: 'helvetica',
fontSize:30,
fontWeight:400,
fill:'red',
fontStyle: 'normal',
top:250,
cursorDuration:500,
left:250,
});
canvas.add(custontxt);
}
http://jsfiddle.net/hsLwjtbx/16/

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'..

Ontouchstart is not working for svg element

I am creating a circle using SVG
var gauge = mapSvg.circle(center['x'], center['y'], 85).attr({'stroke-width': 3, 'stroke': 'black', 'fill': 'white'});
It is in for loop, this circle created three times. I have added ontouchstart on its click
gauge.node.ontouchstart = function () { alert("hi>>>>>") }
but this alert is not showing.
This should work...
var r = Raphael("blah",200,200);
var c = r.circle(100,100,100).attr({fill: 'red' }).touchstart( function() { alert('hi') });
jsfiddle http://jsfiddle.net/7c56E/

Resources