get position of canvas element after drag relative to canvas - javascript

I double click on a canvas to create an element, and the user can do this n times. Each element is draggable.
For each element, if I drag it to within a certain rectangle of x/y coordinates, I want to then clearRect() within that rectangle, effectively deleting the dragged element.
How implement this?
Current:
var stage = new Kinetic.Stage({
container: 'container',
width: 662,
height: 983
});
var layer = new Kinetic.Layer();
stage.add(layer);
$(stage.getContent()).on('dblclick', function (event) {
var pos = stage.getMousePosition();
var mouseX = parseInt(pos.x);
var mouseY = parseInt(pos.y);
var text = new Kinetic.Text({
x: mouseX,
y: mouseY,
text: cc,
fill: "blue",
draggable: true,
});
layer.add(text);
layer.draw();
}

You can use yourElement.on("dragend",handler) to test if the element is inside the deletion rectangle.
If it is inside you can use yourElement.destroy() to destroy that element.
Example code and a Demo: http://jsfiddle.net/m1erickson/jqPhe/
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// define the boundaries of the deletion box
var dx=200;
var dy=40;
var dw=100;
var dh=100;
// create the deletion box
var deleteMe=new Kinetic.Rect({
x:dx,
y:dy,
width:dw,
height:dh,
stroke:"red"
});
layer.add(deleteMe);
var label=new Kinetic.Text({
x:dx,
y:10,
text:"Drag here to delete\n(Must be fully inside)",
fill:"black"
});
layer.add(label);
// create a circle element for testing purposes
var circle1 = new Kinetic.Circle({
x:100,
y:100,
radius: 30,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
// on dragend: test if this circle is inside the deletion rectangle. If yes, delete this circle.
circle1.on("dragend",function(){
var x=this.getX();
var y=this.getY();
if(x>=dx && x<=dx+dw && y>=dy && y<=dy+dh){
this.destroy();
layer.draw();
}
});
layer.add(circle1);
layer.draw();

Related

Konva JS. Change Image position, rotate

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>

Kineticjs 'mouseover' tween is working but 'mouseout' tween is not

I am currently trying to make it so a grid of triangles will expand and move to the 'top' layer when you mouse over them, but then shrink back down to original size and move back to the original layer when you mouse out of them. However right now only the mouse over function is working correctly.
Here is the current code Im working with:
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
var secondLayer = new Kinetic.Layer();
var tri = new Kinetic.RegularPolygon({
x: stage.width()/2,
y: stage.height()/2,
sides: 3,
radius: 30,
fill: '#111111',
closed: true,
shadowColor: '#5febff',
shadowBlur: 5,
shadowOpacity: 0.18,
});
layer.add(tri);
stage.add(layer);
stage.add(secondLayer);
// bind stage handlers
layer.on('mouseover', function(evt) {
var shape = evt.targetNode;
shape.moveTo(secondLayer);
stage.draw()
var tween = new Kinetic.Tween({
node: shape,
duration: 0.05,
scaleX: 1.5,
scaleY: 1.5
});
tween.play()
});
secondLayer.on('mouseout', function(evt) {
var shape = evt.targetNode;
var tween = new Kinetic.Tween({
node: shape,
duration: 0.05,
scaleX: 1.5,
scaleY: 1.5
});
tween.reverse()
shape.moveTo(layer);
stage.draw();
});
And here is a jsfiddle: http://jsfiddle.net/y2C3Z/1/
You can use tween.reverse() only after tween.play(). So you can just change scale attributes to original values.
Don't move shape between layers while shape under a tween. You can move shape after tween is done.
http://jsfiddle.net/y2C3Z/3/

KineticJS Arrow drawing rotating misaligned

I'm making an interactive diagram website and I'm trying to easily draw arrows in kineticJS relative to the stagesize, i've got the following:
http://jsfiddle.net/K5Zhg/17/
But as you can see the rotated arrow is not matching the intended start and ending point. I tried offset, but that messes up the correct (not rotated) arrow. Also don't know why jsfiddle show's my arrows this messy (missing bottom line), on my own machine it seems to be working fine (using v5.1.0), see also here http://tomzooi.com/dump/ip/ (using kineticjs and binding bootstrap to it, working nice so far)
code:
var stage = new Kinetic.Stage({
container: 'container',
width: 1140,
height: 500
});
var layer = new Kinetic.Layer();
var border = new Kinetic.Rect( {
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
stroke: ' red',
strokeWidth: 1
});
layer.add(border);
var dot = new Kinetic.Circle({
x: 0.1*stage.getWidth(),
y: 0.1*stage.getHeight(),
radius: 10,
fill: 'red'
});
var dot2 = new Kinetic.Circle({
x: 0.5*stage.getWidth(),
y: 0.1*stage.getHeight(),
radius: 10,
fill: 'red'
});
var dot3 = new Kinetic.Circle({
x: 0.5*stage.getWidth(),
y: 0.5*stage.getHeight(),
radius: 10,
fill: 'red'
});
layer.add(dot);
layer.add(dot2);
layer.add(dot3);
var arrow1 = arrow(0.1,0.1,0.5,0.1,10);
var arrow2 = arrow(0.1,0.2,0.5,0.5,10);
layer.add(arrow1);
layer.add(arrow2);
// add the layer to the stage
stage.add(layer);
function arrow(psx, psy, pex, pey, pw) {
var w = stage.getWidth();
var h = stage.getHeight();
var sx = psx*w;
var ex = pex*w;
var sy = psy*h;
var ey = pey*h;
var pr = (Math.atan2(ey-sy, ex-sx)/(Math.PI/180));
var pl = Math.sqrt(Math.pow((ex-sx),2)+Math.pow((ey-sy),2));
ex = sx+pl;
ey = sy;
var poly = new Kinetic.Line({
points: [sx,sy+pw, sx,sy-pw, ex-3*pw,ey-pw, ex-3*pw,ey-2*pw, ex,ey, ex-3*pw,ey+2*pw, ex-3*pw, sy+pw],
fill: '#EDECEB',
stroke: '#AFACA9',
strokeWidth: 2,
closed: true,
rotation: pr,
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: {x:2,y:2},
shadowOpacity: 0.5
});
return poly;
}
Here is a solution: http://jsfiddle.net/K5Zhg/20/
The problem was that when you rotate the arrow shape, it rotates around x=0 and y=0. However your point was drawn on x=sx and y=sy (in your example case x=60 and y=50).
To fix this draw the points around x=0 and y=0 (and translating the other points in the array using the correct variables) and then setting the x and y property of the Kinetic.Line to sx and sy in order set the position back to its intended location. I.e.
function arrow(psx, psy, pex, pey, pw) {
var w = stage.getWidth();
var h = stage.getHeight();
var sx = psx*w;
var ex = pex*w;
var sy = psy*h;
var ey = pey*h;
// console.log(sx);
var pr = (Math.atan2(ey-sy, ex-sx)/(Math.PI/180));
var pl = Math.sqrt(Math.pow((ex-sx),2)+Math.pow((ey-sy),2));
ex = sx+pl;
ey = sy;
var poly = new Kinetic.Line({
points: [0,0+pw,
0,0-pw, ex-sx-3*pw,ey-sy-pw, ex-sx-3*pw,ey-sy-2*pw, ex-sx,ey-sy, ex-sx-3*pw,ey-sy+2*pw, ex-sx-3*pw, 0+pw],
fill: 'blue',
stroke: 'black',
strokeWidth: 2,
closed: true,
rotation: pr,
x: sx,
y: sy,
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: {x:2,y:2},
shadowOpacity: 0.5
});
return poly;
}
I also changed the y value to 0.1 instead of the 0.2 such that the start of the second arrow connects with the red dot.
Oh and I updated the Fiddle to uses v5.0.1.

Displaying value on KineticJs Text()

I want to change the text in my container for kinetic js using keyup event in jquery but it doesn't display. I tried getting the value then display it on a span element and it works fine.
Here's my code:
var stage = new Kinetic.Stage({
container: 'canvasContainer',
width: 800,
height: 800
});
var layer = new Kinetic.Layer();
var message = '';
$(function(){
$('#txtArea').change(function(){
message = $(this).val();
$('.output').text(message);
var simpleText = new Kinetic.Text({
x: 0,
y: 10,
text: message,
fontSize: 30,
fontFamily: 'Calibri',
fill: 'blue'
});
layer.add(simpleText);
}).keyup(function(){
$(this).change();
});
});
stage.add(layer);
After you add or change a Kinetic object, be sure you call layer.draw() to cause the drawing to be visible.
BTW, instead of adding a new simpleText with each change, you might want to just change the text in the existing text object
// declare simpleText before .change()
var simpleText = new Kinetic.Text({
x: 0,
y: 10,
text: "",
fontSize: 30,
fontFamily: 'Calibri',
fill: 'blue'
});
layer.add(simpleText);
// then inside .change()
simpleText.setText(message);
layer.draw();

moving more than two arrow lines on canvas

This is my code using kinetic.js
I draw three lines and move using mouse.
$(document).ready(function(){
var y1=50;
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var group=new Kinetic.Group({
draggable: true,
dragConstraint : 'horizontal'
});
var lineme =function(pts){
var line1 = new Kinetic.Line({
points: pts,
stroke: "black",
strokeWidth: 4,
lineCap: 'round',
lineJoin: 'round',
});
group.add(line1);
}
for(a=0;a<=2;a++)
{
var points1 = [{
x: 73,
y: y1
}, {
x: 300,
y: y1
}];
lineme(points1);
y1=y1+50;
}
group.on("mouseover", function(){
document.body.style.cursor = "pointer";
});
group.on("mouseout", function() {
document.body.style.cursor = "default";
});
// add the shape to the layer
layer.add(group);
// add the layer to the stage
stage.add(layer);
});
I want to draw arrow line I tried more time but I cant find out the proper solution. Is their any arrow function in kinetic js can anyone help me
You have to create a group and add both lines to the group.
Check the following example:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-a-group-with-kineticjs/
Hope it helps!
var line2 = .....
// add another line to the layer before adding it to the stage
layer.add(line2);
surely?

Categories