KinetikJS Keep bounds while dragging an object - javascript

Heyhey,
while learning JS and using KineticJS I am stuck with a little problem.
As Iam not able to get my own code into a fiddle right now lets take this example:
http://jsfiddle.net/m1erickson/n5xMs/
If we make the white rect also draggable:
var white = new Kinetic.Rect({
x: 20,
y: 20,
width: 300,
height: 300,
fill: 'white',
stroke: 'black',
strokeWidth: 2,
draggable: true
});
the dragBoundFunc won´t work correctly anymore if the white rect is moved around. While debugging this with coda2, I found that when the white rect is dragged around, that the x and y attrs do not change.
Why is that so? How do I manage to make the dragBoundFunc work for moving parent-shapes?
thanks in advance for your help.

First of all:
I found that when the white rect is dragged around, that the x and y attrs do not change.
No, they don't, because they're defined statically. If you wanted changing values, you'd want to get the updated values within the dragBoundFunc. It might be as simple as calculating them the same way they are now, but inside that function.
How do I manage to make the dragBoundFunc work for moving parent-shapes?
In your example the white rectangle isn't a parent of anything, it's just a shape drawn on the same stage as the orange rectangle. What you want to do is make the white shape background and the orange rectangle both children of the same node, and drag that. The most direct way to do this here would be to make the layer itself draggable, e.g.:
var layer = new Kinetic.Layer({draggable: true});
But how you do this is arbitrary. The white and orange boxes might also be children of another Kinetic.Container, for example.

Related

(matterJS) Need to update vertices in Bodies.fromVertices without moving the position of the polygon

Im working in a videogame made with MatterJS,
Im using Bodies.fromVertices to create an irregular polygon.
This vertices of this polygon should be dynamic, so should change in time.
I already have the values of the new vertices in each frame, so I only need to set it to the polygon.
Body.setVertices didnt work for me, so the only way I founded to do that was removing the polygon and creating another one with the new vertices, in the same position, for each frame.
All is working smoothly except for the position of the polygon.
The position is generated around the center of mass, and its impossible to me to have always the same position, the polygon moves chaotically everywhere when I change the vertices.
I tryied by calculating the width/height of the polygon with the bounds.min/max/.x/.y, and move it but its now working, i think because the polygon can take any shape, you never know where will be positioned and how to compensate for that movement.
Do you know if there is another way to set the new vertices without remove/create the previous polygon, or if there is any way to get this work as it is?
This is the code where I remove the previous polygon, and I add the new one. The variable "vert" have new vertices each frame. "xPos" and "yPos" is where i want the polygon, this value never changes but the polygon is moving anyway.
Composite.remove(engine.world, groundFromVertices);
groundFromVertices = Bodies.fromVertices(xPos, yPos, vert, {isStatic : true,
render: {
fillStyle: 'red',
strokeStyle: 'white',
lineWidth: 5
}}, false, 0, 0, 0, 0);
Composite.add(engine.world, groundFromVertices);
Thank you so much in advice

Fabric JS Strange problem when handling mouse move over line object

I'm developing an object drawing canvas that uses Fabric.js and i'm encountering some strange issues when trying to deal with lines.
To make things clear, i've created a very simple jsfiddle that show what i'm seeing.
It's an event inspector that checks if the mouse is over a line, over a square or nowhere.
The objects are movable if you want, it's the same with fixed objects.
As you can see, if you try to position your mouse around the square, it only fires an event when you actually put the pointer on the square.
When you try to go near the line things change and we see a bigger area that fires this event.
Am I making some trivial mistake, its a bug or something else that i didn't think of?
Thank you all for your interest
var canvas = new fabric.Canvas('c');
var square = new fabric.Rect({
left: 200,
top: 100,
width: 20,
height: 20,
});
var line = new fabric.Line([0,0,100,100], {
stroke: 'red',
strokeWidth: 1,
});
canvas.add(square);
canvas.add(line);
canvas.on('mouse:move', (e)=>{
switch (e.target){
case line:
{
console.log("Pointer over a line");
canvas.backgroundColor="green";
break;
}
case square:
{
console.log("Pointer over a square");
canvas.backgroundColor="blue";
break;
}
default:
{
canvas.backgroundColor="white";
break;
}
}
canvas.renderAll();
});
https://jsfiddle.net/arozgkct/3/
Mouse events in FabricJS are always triggered within the bounding box of the object, which means that the bounding dimensions of your line are actually determined by the width and height of your line object. If you'd rather the events be confined to the line itself, draw the line on just one axis and then rotate it by setting an angle value of 45 degrees.
var line = new fabric.Line([0,100,100,100], {
stroke: 'red',
strokeWidth: 1,
angle: 45,
left: 50
});
https://jsfiddle.net/melchiar/puwgeb02/
In addition to what melchiar said, i learnt that there is another method to capture the event from the line only and not also from the bounding box around it.
I document it here if anyone else need in the future.
You just have to add these two lines after adding the line to the canvas
line.perPixelTargetFind = true;
line.targetFindTolerance = 4;
Complete code in the updated jsfiddle
https://jsfiddle.net/gmto0h58/

How can I manage to move object between various layers?

I need to move object between layers, actually I have a main working area (say shape of square) and inside this working area I have a similar shape (bleed shape) same of the outer one but smaller in size, something like this :
https://jsfiddle.net/p0hszz22/24/ [see circle, square, rectangle shapes]
//# add main square
function addSquare() {
clearThisCanvas();
var square = new fabric.Rect({});
canvas.add(square);
addSquare1(); //call bleedline square
}
//# add bleedline square
function addSquare1() {
var square = new fabric.Rect({});
canvas.add(square);
centreOnCanvas(square);
}
So I got two objects on canvas, now my requirement is when I add any image and move that image(or any object) inside the working area the dotted line(bleed shape) should always be on above of my image, so that it shows the user hint that images or anything outside the bleed region will be ignored (present case : does not happened at all )
What I have tried :
I tried to change the order of these two shapes,and when I did the bleed shape hides itself when main shape(outer one) is selected.
I thought of making these shapes into a group but again no success.
How can I achieve this? all I need is to show the user as soon anything crosses the bleed line, it will not be considered.
Any link to study or keywords that I can again look for or any suggestion or any example will be helpful.
Thanks
PS: sorry for code in fiddle actually it was just to setup things quickly.
Try using an overlay image for the bleeding shape, maybe that fit your needs.
That image will always be on top of the other objects inside the canvas
canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png',
canvas.renderAll.bind(canvas), {
opacity: 0.5,
width : 400, // your width
height : 400, // your height
originX: 'center',
originY: 'center'
});

how to make rectangle scale vertically animation in Raphael JS

The Raphael Js website is down so I can't find any documentation or anything on how to do this. I want to create a rectangle with initial vertical size of 0 and make it animate so that it gets vertically larger and larger when I click another object. Thanks!
so i've got a rectangle
var water = paper.rect( 0, 300, 600, 0).attr({fill:"blue"});
how do I make it animate?
In particular, check out the documentation for
Element.attribute(),
Element.animate(),
Element.click(), and
Raphael.animation().
The following snippet demonstrates a simple animation like the one you are looking for. Click the red square to make the water "fill". It may not work in some browsers (e.g. Chrome) possibly because the snippet is trying to access an external third-party library, i.e. Raphael.js. So, to run it, either go to this SO question/answer page on Firefox or copy the code and run it on your own computer.
Note that, to make the water "fill" in the up direction, you can't just increase the height of the water rectangle...that would make the rectangle grow downwards. You also have to simultaneously raise the top of the rectangle by the identical amount. Thus you have to animate height and y simultaneously, as shown in the code.
UPDATE: provided an up-to-date link for the Raphael minified library
var paper = Raphael(0, 0, 500, 120);
var button = paper.rect( 10, 10, 40, 20).attr({fill:"red"});
var water = paper.rect( 10, 100, 400, 0).attr({fill:"blue"});
var anim = Raphael.animation({
height: 60,
y: (100 - 60)
}, 2000);
button.click(function() {water.animate(anim);});
<script src="https://raw.githubusercontent.com/DmitryBaranovskiy/raphael/master/raphael.min.js"></script>
To get the animation to start, click on the red rectangle.

KineticJS calling moveToTop() automatically after clicking over shape

I am with a little problem here but I don't know if it is a bug or a new feature since in the KineticJS change logs there is the following change:
"drag and drop operations now automatically dynamically create a temporary top layer, and place nodes there for groups and shapes to greatly improve drag and drop performance..."
I was used to use the version 4.0.0 in my test projects and I must use explicity moveToTop() when I want to move some shape to the top (I think that this is the correct way). Now (version 4.3.2) if I just click over some pic, it is automatically moved to the top against my wish. This temporary layer should be something internal, nothing visual. So is this really a bug or there is someway to turn this thing off.
Even the labs changed I think, before I think that the objects keeps the space order if you don't call the moveUp, moveToTop, etc, functions. For example in the following link there are no moveToTop() function calls, even this way if you click on the shapes, they are moved to the top.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-move-shape-to-another-container-with-kineticjs/
Thanks for the attention
While I dont think you can completely disable the layer, you can turn off moving the shapes into it. Say you have some shape like:
var shape1 = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
draggable: true
});
you need to add one parameter to this to disable moving your shape to the temporary layer on drag: 'dragOnTop' which needs to be false, so make your shapes something like:
var shape1 = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
draggable: true,
dragOnTop: false //<-- add this line so that this shape doesn't use the drag layer.
});

Categories

Resources