I have a canvas and I add a rectangle in it. Each rectangle has its own ID. How can I get the ID by double clicking on the rectangle on the canvas? It can be either Alert or consolLog.
Example: http://fabricjs.com/manage-selection
You can add your own properties to an object. For example[1]:
var rect = new fabric.Rect({
// ...
metaData: {
id: 'myId'
}
});
Then you can get if on select for example:
rect.on('selected', e => {
console.log(canvas.getActiveObject().metaData?.id);
});
Live example:
const canvas = new fabric.Canvas('c');
// create a rectangle object
const rect = new fabric.Rect({
left: 10,
top: 10,
fill: 'red',
width: 40,
height: 40,
metaData: {
id: 'myId'
}
});
// add "selected" listener
rect.on('selected', e => {
console.log(canvas.getActiveObject().metaData?.id);
});
// "add" rectangle onto canvas
canvas.add(rect);
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.2.0/fabric.min.js" integrity="sha512-Pdu3zoEng2TLwwjnDne3O7zaeWZfEJHU5B63T+zLtME/wg1zfeSH/1wrtOzOC37u2Y1Ki8pTCdKsnbueOlFlMg==" crossorigin="anonymous"></script>
<canvas id="c" width="200" height="200"></canvas>
[1] Of course you can also add it as a direct property (without the metaData) but maybe it will be better to remind you that it's not fabris property but yours
Related
Next code create triangles on canvas, if you are not clicking over an existing triangle. And you may save all elements to JSON with clicking on "save" button.Then preview the JSON variable in console.
My problem is that after resizing of an object, height and width are not updated in Json, when clicked on save again.
To resize the triangle You have to click on it. Then grab one of the anchor rectangles and drag it from the center of triangle.
What action must I perform to have also new height and width of the object?
Next is code snippet on jsFfidle: https://jsfiddle.net/ug7p9myc/76/
var canvas = new fabric.Canvas('c5');
function some1(x1, y2) {
var c = new fabric.Triangle({
left: posX2,
top: posY2,
width: 15,
height: 25,
strokeWidth: 3,
fill: '#666',
stroke: '#666'
});
canvas.add(c);
}
var posX2, posY2;
canvas.on('mouse:down', function(e) {
var pointer = canvas.getPointer(e.e);
posX2 = pointer.x;
posY2 = pointer.y;
if (e.target) {} else {
some1(posY2, posY2);
}
});
function saveJsonF() {
var jsonToPHP = JSON.stringify(canvas.toObject());
console.log(jsonToPHP);
}
document.getElementById("saveJsonID").onclick = saveJsonF;
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<input type="button" class="Btn1" id="saveJsonID" value="Save" /></br><br>
<canvas id="c5" width="1060" height="550" style="border: 1px solid black"></canvas>
Use getScaledWidth and getScaledHeight to get the transformed values. If you scale an object, its scaleX and scaleY value changes.
I'm adding an image.
circle = new Image ();
circle.src = '/img/logo.png';
circle.onload = function () {
anyimage = new Konva.Image ({
x: 150,
y: 150,
image: circle,
width: 106,
height: 118
});
layer.add (anyimage);
stage.add (layer);
};
How to get and change the position and angle of this picture?
How to change these settings later. By events. For example, clicking on the buttons.
Method this.setX(),this.rotare(), this.x= not work for image obj.
Solution. Need use anyimage obj. Not cirle.
<script src="https://cdn.rawgit.com/konvajs/konva/1.3.0/konva.js"></script>
<button onclick='rotate_image()'>rotate_image</button>
<button onclick='setPos_image()'>rotsetPos_imageate_image</button>
<div id="container"></div>
var stage = new Konva.Stage({
container: 'container', // индификатор div контейнера
width: 500,
height: 500
});
var layer = new Konva.Layer();
circle = new Image();
circle.src = 'https://im0-tub-ru.yandex.net/i?id=caa07f7c7eb5b2788719c85cd6028d23&n=13';
circle.onload = function() {
anyimage = new Konva.Image({
x: 10,
y: 10,
image: circle,
width: 106,
height: 118
});
layer.add(anyimage);
stage.add(layer);
};
function rotate_image(){
anyimage.rotate(45);
stage.draw();
console.log('loaded');
}
function setPos_image(){
//code for change x,y coord of 'circle' obj
anyimage.setX(45);
stage.draw();
console.log('loaded');
}
The position and size are as you have set in the new Konva.Image() call. Rotation is demonstrated in this example and below in the working snippet. Basically there is a rotation point set by the 'offset' property of the shape. By default this is at the top left of the image rectangle. You apply the shape's rotate() function setting the single parameter to the amount of degrees to rotate by, with rotation happening around the shapes offset(x,y) position.
See snippet below for a playpen.
Note: I have raised a question with the author over the apparent unexpected behaviour that means when you change the offset position, intending to change the center of rotation, the shape is physically moved.
// Add a stage for the shapes
var stage = new Konva.Stage({
container: 'container',
width: 1600,
height: 400
});
// add a layer
var layer = new Konva.Layer();
stage.add(layer);
// add a rect to demonstrate rotation
var r = new Konva.Rect({
x: 60,
y: 30,
width: 50,
height: 50,
fill: 'red',
opacity: 0.5,
strokeWidth: 0})
layer.add(r);
// add a spot to mark the rotate pt
var c = new Konva.Circle({
x: 45,
y: 45,
radius: 4,
fill: 'red',
stroke: 'black',
strokeWidth: 4})
layer.add(c);
stage.draw();
// event for plus & minus buttons
$('#plus').on('click', function(evt){
evt.preventDefault()
r.rotate(10)
stage.draw();
})
$('#minus').on('click', function(evt){
evt.preventDefault()
r.rotate(-10)
stage.draw();
})
// function to set rotate point and shape
function setPos(pos){
r.setAttr('offsetX', pos.x);
r.setAttr('offsetY', pos.y);
c.position({
x: r.x(),
y: r.y()
});
c.moveToTop();
sayPos();
stage.draw();
}
$('#ctr').on('click', function(evt){
evt.preventDefault()
setPos({x:25, y:25});
})
$('#topLeft').on('click', function(evt){
evt.preventDefault()
setPos({x:0, y:0});
})
$('#topRight').on('click', function(evt){
evt.preventDefault()
setPos({x:50, y:0});
})
$('#botCtr').on('click', function(evt){
evt.preventDefault()
setPos({x:25, y:50});
})
function sayPos(){
$('#info').html('Rotate pt=' + r.offsetX() + ", " + r.offsetY());
}
// call the setPos() and sayPos() funcs on load.
setPos({x:0, y:0});
sayPos();
p
{
padding: 4px;
}
#container
{
background-color: silver;
overflow: hidden;
}
div
{
padding: 4px;
}
<div id='info1'></div>
<div id='info2'></div>
<div>Click row 1 buttons to set rotate pt and row 2 buttons to rotate by 10 degrees</div>
<div>
<button id='topLeft'>Move rotate pt to top left</button>
<button id='ctr'>Move rotate pt to center</button>
<button id='topRight'>Move rotate pt to top right</button>
<button id='botCtr'>Move rotate pt to bottom center</button>
</div>
<div>
<button id='plus'>+10</button>
<button id='minus'>-10</button>
<span id='info'>Info:</span>
</div>
<div id="container"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script type="text/javascript" src="test.js"></script>
Is there any option to add pattern with Image AND Color?
Anytime, when I apply an image as a pattern, even though the image is transparent, Fabric adds it with some kind of "gray layer".
Link to Fiddler
var canvas = window.canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
width: 256,
height: 256,
fill: 'red'
});
canvas.add(rect);
rect.center().setCoords();
fabric.util.loadImage('https://assets-cdn.github.com/images/modules/site/integrators/slackhq.png', function (img) {
rect.setPatternFill({
source: img,
repeat: 'no-repeat'
});
canvas.renderAll();
});
Any idea?
Assuming the image has transparent background, you can use fabric.StaticCanvas as fabric.Pattern's source:
var imgPath = 'https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png'
var imgColor = 'grey'
var canvas = this.__canvas = new fabric.Canvas('c')
fabric.Image.fromURL(imgPath, function(img) {
var patternSourceCanvas = new fabric.StaticCanvas()
patternSourceCanvas.add(img)
patternSourceCanvas.setBackgroundColor(imgColor, patternSourceCanvas.renderAll.bind(patternSourceCanvas))
var pattern = new fabric.Pattern({
source: function() {
return patternSourceCanvas.getElement();
},
repeat: 'repeat'
})
// create a rectangle object
var rect = new fabric.Rect({
fill: pattern,
width: 400,
height: 400
})
// "add" rectangle onto canvas
canvas.add(rect)
})
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.9/fabric.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
I want to create a group that is 300px wide and 200px high, and then load a few things inside that group. When I load images in that are larger than the group dimensions, it bleeds outside the group. I'd love to "crop" the image (similar to a CSS overflow:hidden property).
Is this possible?
To accomplish your task you should use the clipTo function on your image, the clipTo function on a group already has an open bug, btw you can work around there, by transpose the dimension and the position of your group to clipTo function:
clipTo :Function § Function that determines clipping of an object
(context is passed as a first argument) Note that context origin is at
the object's center point (not left/top corner)
Take a look to official demo, then after the clip operation on your image you can add it to a group(run below script to see an example).
var canvas = window.__canvas = new fabric.Canvas('c');
var path = 'http://fabricjs.com/lib/pug.jpg';
var _img = new Image();
_img.onload = function(img) {
var dog = new fabric.Image(_img, {
left: 100,
top: 100,
width: 300,
height: 300,
selectable: false,
clipName: 'dog',
clipTo: function(ctx) {
ctx.rect(0, 0, 50, 50);
}
});
var group = new fabric.Group([dog], {
left: 100,
top: 100,
width: 100,
height: 100,
borderColor: 'black',
});
canvas.add(group);
};
_img.src = path;
canvas.renderAll();
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.13/fabric.min.js"></script>
<canvas id="c" height="300" width="300" style="border:1px dashed #333;"></canvas>
I'm adding an object into canvas using fabricjs. After adding that object, i an centring it's position using obj.center() method of fabricjs. That object is added to the center. Then i used renderAll() method.
var canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
fill: 'red',
width: 20,
height: 20,
angle: 45
});
canvas.add(rect);
rect.center();
canvas.renderAll();
But there's one problem. I don't get the hover cursor(cursor with the hand) if i hover on that object. However, if i move my cursor to (0,0) coordinate position of the canvas, hover cursor is shown and clicking at that point selects that added object.
What am i dont wrong?
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
fill: 'red',
width: 20,
height: 20,
angle: 45
});
canvas.add(rect);
rect.center();
rect.setCoords();
canvas.renderAll();
canvas {
border: 2px dotted green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.16/fabric.min.js" charset="utf-8"></script>
<canvas id="canvas" width="400" height="400"></canvas>
after using center() you need to call setCoords().