Put text Inside Kinetic.Circle - text

I'm trying to put text inside a circle from Kinetic.Circle but i can't find the right answer. I have the following code:
var circle = new Kinetic.Circle({
x: 30,
y: stage.getHeight() / 2,
radius: 20,
fill: 'red',
stroke: 'black',
strokeWidth: 2,
});
var text = new Kinetic.Text({
text: 'A',
fontSize: 10,
fontFamily: 'Calibri',
width: 5,
fill: '#000'
});
layer.add(circle);
layer.add(texto);
stage.add(layer);
Any ideas how to accomplish this please?

You can position the text like this so that you dont have to provide the x & y coordinates.
text.setX( circle.getX() - text.getWidth()/2 );
text.setY( circle.getY() - text.getHeight()/2 );

Related

Create a clipping mask using an object in Fabric.js

I'm trying to create a T-Shirt editor using Fabric. I set a shirt as a background image on the canvas. Now I'm trying to get an area in the middle of the T-shirt that will act as a clipping mask. I only want objects that are inside this area to be visible.
Here's my code: http://jsfiddle.net/mtb2p3Lx/4/
var canvas = new fabric.Canvas('c');
// set background
fabric.Image.fromURL('https://qstomizr.s3.amazonaws.com/11102-9LDAQLKA1585254870.5083.jpg', (img) => {
canvas.setBackgroundImage(img, null, {
originX: 'center',
originY: 'center',
top: canvas.getCenter().top,
left: canvas.getCenter().left,
stroke: 'black',
strokeWidth: 1,
});
canvas.renderAll();
});
// set masking area
var area = new fabric.Rect({
originX: 'center',
originY: 'center',
top: this.canvas.getCenter().top,
left: this.canvas.getCenter().left + 10,
width: 250,
height: 300,
selectable: false,
fill: 'transparent',
stroke: 'black',
strokeWidth: 2,
});
canvas.add(area)
// set example rect
var rect = new fabric.Rect({
originX: 'center',
originY: 'center',
top: this.canvas.getCenter().top + 50,
left: this.canvas.getCenter().left + 150,
height: 100,
width: 100,
fill: 'pink',
});
canvas.add(rect)
I tried adding a clip path to the area rect, also tried playing around with globalCompositeOperation, but I couldn't get anything to work without having to sacrifice the background image.
Is there a way to get the transparent area rect to act as a clipping mask for the other objects in the canvas?
As you can see on this site https://printio.ru/tees/new_v2. For implementing background image was used img tag without setBackgroundImage. And I make an example for you here
https://jsfiddle.net/RamanNikitsenka/4suna7yo/1/

How to make Fabric.js IText font NOT bold?

In this jsfiddle I have an IText with fontWeight: 'normal', still the font is displayed with bold letters. How to make this text NOT bold?
Javascript:
var canvas = new fabric.Canvas('c');
var text = new fabric.IText('This is the text',{
left: 20,
top: 20,
fontFamily: 'Arial',
fontWeight: 'normal',
fontSize: 18,
stroke: 'black',
fill: 'black'
});
canvas.add(text);
The stroke effect makes it appear bold.
The text itself has the normal standard weight, here is a comparison without the stroke effect.
var text = new fabric.IText('This is the text',{
left: 20,
top: 20,
fontFamily: 'Arial',
fontWeight: 'normal',
fontSize: 18,
fill: 'black'
});
This is just because of stroke, if you remove the stroke then you will get fontweight:'Normal', please find the fiddle https://jsfiddle.net/Gauravkakkar25/ruoa19r7/1/

Fabric.js accessing to group in a function

Hello guy and thanks so much for your help.
I am a newbie in fabric.js and I have a basic question.
I create a group of 3 objects in a function.
I want to change property of an object of this group in another function.
And more generally it will be really useful if someone can explain to me how to access to another object of a group?
I don't know how to do that.
function groupit() //Works {
var circle1 = new fabric.Circle({
radius: 50,
fill: 'red',
left: 0
});
var circle2 = new fabric.Circle({
radius: 50,
fill: 'green',
left: 100
});
var circle3 = new fabric.Circle({
radius: 50,
fill: 'blue',
left: 200
});
var group = new fabric.Group([ circle1, circle2, circle3 ], {
left: 200,
top: 100
});
canvas.add(group);
}
function groupchg() //Does not work {
canvas.setActiveGroup(group);
group.add(new fabric.Rect({
left: 100,
top: 100,
originX: 'center',
originY: 'center'
}));
}
Because you call canvas.setActiveGroup(group); in your function groupchg(), and property group is probably null. Can fix if define group property out of function groupit().
Ok found solution.
To access to specific object of a group i use this code :
function groupchg() {
//console.log(canvas.getActiveGroup());
canvas.setActiveObject(canvas._objects[0]._objects[1]);
var activeObj = canvas.getActiveObject();
activeObj.setFill('red');
activeObj.set({left: 30,top:150});
canvas.renderAll();
}

Moving three circles to another position slowing down movement (KineticJS)

I am trying to move three circles, after they gradually fade in, to the top left of the page so that they overlap on a box. At the moment, I set a timeout, but it only works for the first circle and the movement is really fast. How can I move them all as a group and slow down the movement?
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
background-color: #CCCCCC;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></head>
<body>
<div id="container"></div>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.1-beta2.js">
</script>
<script>
var fadeIn = function(shape) {
var o = shape.getOpacity();
o = o + 0.05 >=0.5 ? 0.5 : o + 0.05;
shape.setOpacity(o);
shape.getLayer().draw();
if(o !== 0.4) {
setTimeout(function() {
fadeIn(shape).delay(3000*3);
}, 720);
}
};
var stage = new Kinetic.Stage({
container: 'container',
width: 800,
height: 700
//width: 578,
//height: 200
});
var layer = new Kinetic.Layer();
var circle = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: '#CCCCCC',
stroke: 'yellow',
strokeWidth: 8,
opacity: 0.1
});
circle.hide();
setTimeout(function() {
circle.show();
fadeIn(circle).delay(3000*3);
}, 1720);
layer.add(circle);
var circle2 = new Kinetic.Circle({
x: stage.getWidth() / 2.1,
y: stage.getHeight() / 2.1,
radius: 70,
fill: '#CCCCCC',
stroke: 'yellow',
strokeWidth: 8,
opacity: 0.1
});
circle2.hide();
setTimeout(function() {
circle2.show();
fadeIn(circle2).delay(3000*3);
}, 5600);
// add the shape to the layer
layer.add(circle2);
var circle3 = new Kinetic.Circle({
x: stage.getWidth() / 2.2,
y: stage.getHeight() / 2.2,
radius: 70,
fill: '#CCCCCC',
stroke: 'yellow',
strokeWidth: 8,
opacity: 0.1
});
circle3.hide();
setTimeout(function() {
circle3.show();
fadeIn(circle3).delay(3000*3);
}, 12000);
// add the shape to the layer
layer.add(circle3);
// var boxGroup = new Kinetic.Group({
//x: 10,
//y: 10,
//draggable: true
//});
var boxGroup = new Kinetic.Group({
x: -250,
y: -250,
draggable: true
});
var box = new Kinetic.Rect({
x: 10,
y: 10,
width: 100,
height: 100,
fill: '#CCCCCC',
stroke: 'black'
});
boxGroup.add(box);
layer.add(box);
layer.add(boxGroup);
// add the layer to the stage
stage.add(layer);
setTimeout(function() {
circle.moveTo(boxGroup).delay(5000*3);
circle2.moveTo(boxGroup).delay(5000*3);
circle3.moveTo(boxGroup).delay(5000*3);
}, 24000);
</script>
</body>
http://jsfiddle.net/SAnFM/9/
KineticJS has a great transitionTo() function which you can call. It can animate any numerical property, like position or opacity. I created a fiddle to show this, as setTimeout is a bit of an ancient function compared to what is built into the browsers nowadays with RequestAnimationFrame (all major browsers implement this nowadays and KineticJS has a built in fallback like most other libraries do)
I cleaned up your code a little, removing comments and added an extra circle, for fun.
but really all you need is:
myShape.transitionTo({shape configuration, duration});
For example:
circle.transitionTo({
x: box.getX(), //coordinates to transition to
y: box.getY(),
opacity: 1,
duration: 1 // length of time for this animation in seconds, REQUIRED for animation to work
});

kinetic js zindex

Can't quite figure out how to layer these objects with kenetic js, I want circle to be on top of circle2. Am I writing 'circle.setZIndex();' improperly? This is breaking the script.
jsfiddle with .setZIndex lines commented out: http://jsfiddle.net/ZfuDs/
function writeMessage(messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var shapesLayer = new Kinetic.Layer();
var messageLayer = new Kinetic.Layer();
var circle2 = new Kinetic.Circle({
x: 360,
y: stage.getHeight() / 2,
radius: 90,
fill: 'orange',
stroke: 'black',
strokeWidth: 4
});
circle2.setZIndex(3);
var circle = new Kinetic.Circle({
x: 380,
y: stage.getHeight() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
circle.setZIndex(2);
shapesLayer.add(circle);
shapesLayer.add(circle2);
stage.add(shapesLayer);
stage.add(messageLayer);
You can try to add circle2 shape first and then add circle shape second
shapesLayer.add(circle2);
shapesLayer.add(circle);
instead of
shapesLayer.add(circle);
shapesLayer.add(circle2);
Try this one http://jsfiddle.net/ZfuDs/1/
it appears that you can't call the z-index functions before the object is added to a layer I get:
TypeError: this.parent is undefined
this.parent.children.splice(index, 1);
I don't get an error anymore, but the setZIndex() method doesn't seem to work even so, but
circle.moveToTop() does work, check http://jsfiddle.net/ZfuDs/3

Resources