I am trying to keep text on image through kineticjs. But initially I am able to keep the text on image after dragging the image text is going under the image. Can anyone help me on this. Here is my fiddle,
JSFiddle
$(document).ready(function()
{
var startAngle = 0;
var minImgSize = 10;
function update(activeAnchor)
{
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var rotateAnchor = group.get('.rotateAnchor')[0];
var image = group.get('Image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
var imageWidth = image.getWidth();
var imageHeight = image.getHeight();
// update anchor positions
switch (activeAnchor.getName()) {
case 'rotateAnchor':
break;
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
topRight.setX(anchorX);
bottomLeft.setY(anchorY);
break;
case 'bottomLeft':
topLeft.setX(anchorX);
bottomRight.setY(anchorY);
break;
}
if (topRight.getX() < topLeft.getX() + minImgSize)
{
topRight.setX(topLeft.getX() + minImgSize);
}
if (bottomRight.getX() < topLeft.getX() + minImgSize)
{
bottomRight.setX(topLeft.getX() + minImgSize);
}
if (bottomRight.getY() < topLeft.getY() + minImgSize)
{
bottomRight.setY(topLeft.getY() + minImgSize);
}
if (bottomLeft.getY() < topLeft.getY() + minImgSize)
{
bottomLeft.setY(topLeft.getY() + minImgSize);
}
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
image.setPosition({x : topLeft.getPosition().x, y:(topLeft.getPosition().y)});
image.setWidth(width);
image.setHeight(height);
rotateAnchor.setX(width / 2 + topLeft.getX());
rotateAnchor.setY(height / 2 + topLeft.getY());
}
function addAnchor(group, x, y, name, dragBound)
{
var stage = group.getStage();
var layer = group.getLayer();
var groupPos = group.getPosition();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 6,
name: name,
draggable: true,
dragOnTop: false
});
if (dragBound == 'rotate')
{
startAngle = angle(groupPos.x, groupPos.y, x + groupPos.x, y + groupPos.y);
anchor.setAttrs({
dragBoundFunc: function (pos) {
return getRotatingAnchorBounds(pos, group);
}
});
}
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback)
{
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function radians (degrees) {return degrees * (Math.PI/180)}
function degrees (radians) {return radians * (180/Math.PI)}
function angle (cx, cy, px, py) {var x = cx - px; var y = cy - py; return Math.atan2 (-y, -x)}
function distance (p1x, p1y, p2x, p2y) {return Math.sqrt (Math.pow ((p2x - p1x), 2) + Math.pow ((p2y - p1y), 2))}
function getRotatingAnchorBounds(pos, group)
{
var groupPos = group.getPosition();
var rotation = degrees (angle (groupPos.x, groupPos.y, pos.x, pos.y) - startAngle);
var dis = distance (groupPos.x, groupPos.y, pos.x, pos.y);
console.log('x: ' + pos.x + '; y: ' + pos.y + '; rotation: ' + rotation + '; distance:' + dis);
group.setRotationDeg (rotation);
return pos;
}
function initStage(images)
{
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 400
});
var darthVaderGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true,
fill: 'black'
});
var layer = new Kinetic.Layer();
var sw = stage.getWidth();
var sh = stage.getHeight();
var text = new Kinetic.Text({
x: 100,
y: 100,
text: "Gowtham",
fontSize: 32,
fontFamily: "Arial",
fill: "black",
stroke: "white",
strokeWidth: 1,
draggable: true,
dragBoundFunc: function (pos) {
var w = this.getWidth();
var h = this.getHeight();
if (pos.x < 0) {
pos.x = 0;
}
if (pos.x + w > sw) {
pos.x = sw - w;
}
if (pos.y < 0) {
pos.y = 0;
}
if (pos.y + h > sh) {
pos.y = sh - h;
}
return {
x: pos.x,
y: pos.y
}
}
});
layer.add(darthVaderGroup);
stage.add(layer);
layer.add(text);
layer.draw();
var darthVaderImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.darthVader,
width: 200,
height: 138,
name: 'image'
});
darthVaderGroup.add(darthVaderImg);
addAnchor(darthVaderGroup, 0, 0, 'topLeft', 'none');
addAnchor(darthVaderGroup, darthVaderImg.getWidth(), 0, 'topRight', 'none');
addAnchor(darthVaderGroup, darthVaderImg.getWidth(), darthVaderImg.getHeight(), 'bottomRight', 'none');
addAnchor(darthVaderGroup, 0, darthVaderImg.getHeight(), 'bottomLeft', 'none');
addAnchor(darthVaderGroup, darthVaderImg.getWidth() / 2, darthVaderImg.getHeight() / 2, 'rotateAnchor','rotate');
darthVaderGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
var sources = {
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'
};
loadImages(sources, initStage);
});
canvas
{
border: 1px solid #aaa;
-moz-box-shadow: 3px 3px 8px #222;
-webkit-box-shadow: 3px 3px 8px #222;
box-shadow: 3px 3px 8px #222;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/kineticjs/5.2.0/kinetic.min.js"></script>
<div id="container"></div>
<button id="addImage">Add
</button>
Related
I'm using Fabric JS. Every time I press the Add Door button it creates on the upper left. I gave the values in the rectangle (left: 40, top: 40,).
However, when I press the button while I am on the area I zoomed, I want it to add it to the area I zoomed. I looked at a few examples but could not find what I wanted. How can I do that?
Video
var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('https://i.hizliresim.com/0pIPiv.jpg', canvas.renderAll.bind(canvas));
var uniqids = 0;
$("#door").on("click", function(e) {
rect = new fabric.Rect({
id:uniqid,
left: 40,
top: 40,
width: 35,
height: 50,
fill: 'blue',
stroke: 'blue',
strokeWidth: 5,
strokeUniform: false,
hasControls : true,
});
var uniqid = uniqids.toString();
var text = new fabric.Text(uniqid, {
fontSize: 30,
originX: 'center',
originY: 'right'
});
var group = new fabric.Group([ rect, text ], {
left: 0,
top: 100,
});
canvas.add(group);
uniqids++;
canvas.on('selection:cleared', c => {
console.log("empty");
});
canvas.selection = false;
});
//*****************************
// canvas.on('mouse:wheel', function(opt) {
// var delta = opt.e.deltaY;
// var zoom = canvas.getZoom();
// zoom *= 0.999 ** delta;
// if (zoom > 20) zoom = 20;
// if (zoom < 0.01) zoom = 0.01;
// canvas.setZoom(zoom);
// opt.e.preventDefault();
// opt.e.stopPropagation();
// })
$('#getid').click(function() {
var activeObject = canvas.getActiveObjects();
alert(canvas.getActiveObject().id);
});
//***************************************
$("#save").on("click", function(e) {
$(".save").html(canvas.toSVG());
});
$('#delete').click(function() {
var activeObject = canvas.getActiveObjects();
canvas.discardActiveObject();
canvas.remove(...activeObject);
});
$("#btnResetZoom").on("click", function(e) {
canvas.setViewportTransform([1,0,0,1,0,0]);
});
canvas.on('mouse:wheel', function(opt) {
var delta = opt.e.deltaY;
var zoom = canvas.getZoom();
zoom *= 0.999 ** delta;
if (zoom > 20) zoom = 20;
if (zoom < 1) zoom = 1;
canvas.zoomToPoint({x: opt.e.offsetX, y: opt.e.offsetY}, zoom);
opt.e.preventDefault();
opt.e.stopPropagation();
});
var shiftKeyDown = true;
var mouseDownPoint = null;
canvas.on('mouse:move', function(options) {
if (shiftKeyDown && mouseDownPoint) {
var pointer = canvas.getPointer(options.e, true);
var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
mouseDownPoint = mouseMovePoint;
keepPositionInBounds(canvas);
}
});
var Direction = {
LEFT: 0,
UP: 1,
RIGHT: 2,
DOWN: 3
};
var zoomLevel = 0;
var zoomLevelMin = 0;
var zoomLevelMax = 3;
var shiftKeyDown = false;
var mouseDownPoint = null;
canvas.on('mouse:down', function(options) {
var pointer = canvas.getPointer(options.e, true);
mouseDownPoint = new fabric.Point(pointer.x, pointer.y);
});
canvas.on('mouse:up', function(options) {
mouseDownPoint = null;
});
canvas.on('mouse:move', function(options) {
if (shiftKeyDown && mouseDownPoint) {
var pointer = canvas.getPointer(options.e, true);
var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
mouseDownPoint = mouseMovePoint;
keepPositionInBounds(canvas);
}
});
fabric.util.addListener(document.body, 'keydown', function(options) {
if (options.repeat) {
return;
}
var key = options.which || options.keyCode; // key detection
if (key == 16) { // handle Shift key
canvas.defaultCursor = 'move';
canvas.selection = false;
shiftKeyDown = true;
} else if (key === 37) { // handle Left key
move(Direction.LEFT);
} else if (key === 38) { // handle Up key
move(Direction.UP);
} else if (key === 39) { // handle Right key
move(Direction.RIGHT);
} else if (key === 40) { // handle Down key
move(Direction.DOWN);
}
});
fabric.util.addListener(document.body, 'keyup', function(options) {
var key = options.which || options.keyCode; // key detection
if (key == 16) { // handle Shift key
canvas.defaultCursor = 'default';
canvas.selection = true;
shiftKeyDown = false;
}
});
// jQuery('.canvas-container').on('mousewheel', function(options) {
// var delta = options.originalEvent.wheelDelta;
// if (delta != 0) {
// var pointer = canvas.getPointer(options.e, true);
// var point = new fabric.Point(pointer.x, pointer.y);
// if (delta > 0) {
// zoomIn(point);
// } else if (delta < 0) {
// zoomOut(point);
// }
// }
// });
function move(direction) {
switch (direction) {
case Direction.LEFT:
canvas.relativePan(new fabric.Point(-10 * canvas.getZoom(), 0));
break;
case Direction.UP:
canvas.relativePan(new fabric.Point(0, -10 * canvas.getZoom()));
break;
case Direction.RIGHT:
canvas.relativePan(new fabric.Point(10 * canvas.getZoom(), 0));
break;
case Direction.DOWN:
canvas.relativePan(new fabric.Point(0, 10 * canvas.getZoom()));
break;
}
keepPositionInBounds(canvas);
}
// function zoomIn(point) {
// if (zoomLevel < zoomLevelMax) {
// zoomLevel++;
// canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
// keepPositionInBounds(canvas);
// }
// }
// function zoomOut(point) {
// console.log(zoomLevel, zoomLevelMin);
// if (zoomLevel > zoomLevelMin) {
// zoomLevel--;
// canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
// keepPositionInBounds(canvas);
// }
// }
function keepPositionInBounds() {
var zoom = canvas.getZoom();
var xMin = (2 - zoom) * canvas.getWidth() / 2;
var xMax = zoom * canvas.getWidth() / 2;
var yMin = (2 - zoom) * canvas.getHeight() / 2;
var yMax = zoom * canvas.getHeight() / 2;
var point = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2);
var center = fabric.util.transformPoint(point, canvas.viewportTransform);
var clampedCenterX = clamp(center.x, xMin, xMax);
var clampedCenterY = clamp(center.y, yMin, yMax);
var diffX = clampedCenterX - center.x;
var diffY = clampedCenterY - center.y;
if (diffX != 0 || diffY != 0) {
canvas.relativePan(new fabric.Point(diffX, diffY));
}
}
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
#c {
background-color: grey;
margin-top: 10px;
}
button {
padding: 10px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<button id="door">Door</button>
<button id="delete">Delete Door</button>
<button id="save">Save</button>
<button id="getid">GET ID</button>
<button id="btnResetZoom">Reset Zoom</button>
<canvas id="c" width="800" height="800"></canvas>
<br>
<p class="save">
</p>
I think you should use the transformPoint method to translate position
$("#door").on("click", function (e) {
const points = {};
const iVpt = fabric.util.invertTransform(canvas.viewportTransform);
points.tl = fabric.util.transformPoint({x: 40, y: 40}, iVpt);
rect = new fabric.Rect({
id: uniqid,
left: points.tl.x,
top: points.tl.y,
width: 35,
height: 50,
fill: "blue",
stroke: "blue",
strokeWidth: 5,
strokeUniform: false,
hasControls: true,
});
I would like to set hyperlink on an image with this JSON: {url: 'img/enf.png', x: 1200, y: 530, offset: -0.1} in a parallax effect, so if you click on this image, you go to "news.html".
Code I currently have:
<html>
<head>
<style>
body{
margin:0;
overflow-x: hidden;
}
#pozadi{
background-image: url(img/pozadi.png);
overflow: hidden;
background-size: cover;
background-position: top;
background-repeat: no-repeat;
position: relative;
min-height: 500px;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div id="pozadi">
<div id="container"></div>
</div>
<script src="tweenmax.js"></script>
<script src="snapsvg.js"></script>
<script>
if (screen.width > 1200){
var assets = [
{url: 'img/vybuch.png', x: 0, y: 60, offset: -0.25},
{url: 'img/psi.png', x: 200, y: 80, offset: -0.2},
{url: 'img/kour.png', x: 120, y: 280, offset: -0.15},
{url: 'img/enf.png', x: 1200, y: 530, offset: -0.1},
{url: 'img/csf.png', x: -40, y: 530, offset: -0.1},
{url: 'img/nadpis.png', x: 350, y: 530, offset: 0.01},
{url: 'img/sbt.png', x: 610, y: 665, offset: 0.01},
],
layers = [],
w = screen.width,
h = screen.height,
loaded = 0,
container = document.getElementById('container'),
s = new Snap(w, h);
container.appendChild(s.node);
g = s.g();
c = s.g();
c.attr({transform: 'scale(1)'});
g.append(c);
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
/*Start my code*/
if (i==3) { //3 is your 'img/enf.png', or check the string in img.src
img.onclick = function(e){
window.location.href = 'www.debil.cz';
}
}
/*End my code*/
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
c.append(_img);
layers.push(_img);
}
function handle_load(e) {
loaded += 1;
if (loaded == assets.length) {
handle_loaded();
}
}
function handle_loaded() {
container.addEventListener('mousemove', handle_mousemove);
container.addEventListener('mouseout', handle_mouseout);
container.addEventListener('mouseover', handle_mouseover);
}
function handle_mousemove(e) {
var dx = e.offsetX - (w / 2);
var dy = e.offsetY - (h / 2);
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
var _x = dx * assets[i].offset;
var _y = dy * assets[i].offset;
TweenMax.to(l.node, 0.1, {x: _x, y: _y});
}
}
function handle_mouseout(e) {
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
TweenMax.to(l.node, 0.2, {x: 0, y: 0, ease: Quad.easeOut});
}
TweenMax.to(s.node, 0.2, {scale: 0.9, rotationY: 0, rotationX: 0, ease: Quad.easeOut});
TweenMax.to(c.node, 1, {rotationY: 0, rotationX: 0});
}
function handle_mouseover(e) {
TweenMax.to(s.node, 0.2, {scale: 1, ease: Back.easeOut});
}
function angleToPoints(angle) {
var segment = Math.floor(angle / Math.PI * 2) + 2;
var diagonal = (1/2 * segment + 1/4) * Math.PI;
var op = Math.cos(Math.abs(diagonal - angle)) * Math.sqrt(2);
var x = op * Math.cos(angle);
var y = op * Math.sin(angle);
return {
x1: x < 0 ? 1 : 0,
y1: y < 0 ? 1 : 0,
x2: x >= 0 ? x : x + 1,
y2: y >= 0 ? y : y + 1
};
}
}else if (screen.width > 600){
var assets = [
{url: 'img/vybuch_tablet.png', x: -450, y: 80, offset: -0.25},
{url: 'img/psi_tablet.png', x: -280, y: 140, offset: -0.2},
{url: 'img/kour_tablet.png', x: -220, y: 350, offset: -0.15},
{url: 'img/enf_tablet.png', x: 470, y: 830, offset: -0.1},
{url: 'img/csf_tablet.png', x: 85, y: 830, offset: -0.1},
{url: 'img/nadpis_tablet.png', x: 5, y: 610, offset: 0.01},
{url: 'img/sbt_tablet.png', x: 150, y: 740, offset: 0.01},
],
layers = [],
w = screen.width,
h = screen.height,
loaded = 0,
container = document.getElementById('container'),
s = new Snap(w, h);
container.appendChild(s.node);
g = s.g();
c = s.g();
c.attr({transform: 'scale(1)'});
g.append(c);
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
c.append(_img);
layers.push(_img);
}
function handle_load(e) {
loaded += 1;
if (loaded == assets.length) {
handle_loaded();
}
}
function handle_loaded() {
container.addEventListener('mousemove', handle_mousemove);
container.addEventListener('mouseout', handle_mouseout);
container.addEventListener('mouseover', handle_mouseover);
}
function handle_mousemove(e) {
var dx = e.offsetX - (w / 2);
var dy = e.offsetY - (h / 2);
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
var _x = dx * assets[i].offset;
var _y = dy * assets[i].offset;
TweenMax.to(l.node, 0.1, {x: _x, y: _y});
}
}
function handle_mouseout(e) {
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
TweenMax.to(l.node, 0.2, {x: 0, y: 0, ease: Quad.easeOut});
}
TweenMax.to(s.node, 0.2, {scale: 0.9, rotationY: 0, rotationX: 0, ease: Quad.easeOut});
TweenMax.to(c.node, 1, {rotationY: 0, rotationX: 0});
}
function handle_mouseover(e) {
TweenMax.to(s.node, 0.2, {scale: 1, ease: Back.easeOut});
}
function angleToPoints(angle) {
var segment = Math.floor(angle / Math.PI * 2) + 2;
var diagonal = (1/2 * segment + 1/4) * Math.PI;
var op = Math.cos(Math.abs(diagonal - angle)) * Math.sqrt(2);
var x = op * Math.cos(angle);
var y = op * Math.sin(angle);
return {
x1: x < 0 ? 1 : 0,
y1: y < 0 ? 1 : 0,
x2: x >= 0 ? x : x + 1,
y2: y >= 0 ? y : y + 1
};
}
}else{
var assets = [
{url: 'img/vybuch_phone.png', x: 0, y: 0, offset: -0.25},
{url: 'img/psi_phone.png', x: -400, y: 0, offset: -0.2},
{url: 'img/kour_phone.png', x: -300, y: 100, offset: -0.15},
{url: 'img/enf_phone.png', x: 200, y: 540, offset: -0.1},
{url: 'img/csf_phone.png', x: 20, y: 540, offset: -0.1},
{url: 'img/nadpis_phone.png', x: 30, y: 430, offset: 0.01},
{url: 'img/sbt_phone.png', x: 65, y: 495, offset: 0.01},
],
layers = [],
w = screen.width,
h = screen.height,
loaded = 0,
container = document.getElementById('container'),
s = new Snap(w, h);
container.appendChild(s.node);
g = s.g();
c = s.g();
c.attr({transform: 'scale(1)'});
g.append(c);
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
c.append(_img);
layers.push(_img);
}
function handle_load(e) {
loaded += 1;
if (loaded == assets.length) {
handle_loaded();
}
}
function handle_loaded() {
container.addEventListener('mousemove', handle_mousemove);
container.addEventListener('mouseout', handle_mouseout);
container.addEventListener('mouseover', handle_mouseover);
}
function handle_mousemove(e) {
var dx = e.offsetX - (w / 2);
var dy = e.offsetY - (h / 2);
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
var _x = dx * assets[i].offset;
var _y = dy * assets[i].offset;
TweenMax.to(l.node, 0.1, {x: _x, y: _y});
}
}
function handle_mouseout(e) {
for (var i = 0; i < layers.length; i += 1) {
var l = layers[i];
TweenMax.to(l.node, 0.2, {x: 0, y: 0, ease: Quad.easeOut});
}
TweenMax.to(s.node, 0.2, {scale: 0.9, rotationY: 0, rotationX: 0, ease: Quad.easeOut});
TweenMax.to(c.node, 1, {rotationY: 0, rotationX: 0});
}
function handle_mouseover(e) {
TweenMax.to(s.node, 0.2, {scale: 1, ease: Back.easeOut});
}
function angleToPoints(angle) {
var segment = Math.floor(angle / Math.PI * 2) + 2;
var diagonal = (1/2 * segment + 1/4) * Math.PI;
var op = Math.cos(Math.abs(diagonal - angle)) * Math.sqrt(2);
var x = op * Math.cos(angle);
var y = op * Math.sin(angle);
return {
x1: x < 0 ? 1 : 0,
y1: y < 0 ? 1 : 0,
x2: x >= 0 ? x : x + 1,
y2: y >= 0 ? y : y + 1
};
}
}
</script>
</body>
</html>
I have tried to do it with an a tag using href attribute in my html, but it totally breaks the parallax effect.
I am not the expert in javascript, I just changed the code I found and it works perfectly, but in my project, I definitelly need to set a link on the image. Do you have any idea how to do it please?
Try something like this (into the first for):
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
/*Start my code*/
if (i==3) { //3 is your 'img/enf.png', or check the string in img.src
img.onclick = function(e){
window.location.href = 'the link of your news.html';
}
}
/*End my code*/
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
c.append(_img);
layers.push(_img);
}
EDIT
You are right, we wrong.
First of all, what your code generate is an SVG, and the SNAP library click event is this: http://snapsvg.io/docs/#Element.click
For this reason, the code above must be modified in this way:
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
/*Start my code*/
if (i==3) {
_img.click(function(){
//window.location.href = 'www.debil.cz';
alert('yeah');
});
}
/*End my code*/
c.append(_img);
layers.push(_img);
}
BUT
You must remember that: the parallax effect work on layers, and the click event can't fired if an "invisible" element is below (as a blank region of a PNG).
Here a working example but with click on the item in the foreground !!
https://jsfiddle.net/StepBaro/hachn1sL/3/
Here another working example with click on the third element, and the event fired only on very top (because the first is above).
https://jsfiddle.net/StepBaro/hachn1sL/4/
Your assets array has as the last item inserted the highest element.
This isn't tested, but based on the information you provided this may help.
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
//use an if statement to grab correct asset
//change page on click
if (img.src === "img/vybuch.png") {
img.onclick = function(e) {
document.location = "http://www.google.com/";
}
}
var _img = s.image(assets[i].url, assets[i].x, assets[i].y);
c.append(_img);
layers.push(_img);
}
Example:
var assets = [
{url: 'http://www.livefirelabs.com/images/learn-unix-demo-course.jpg', x: 0, y: 60, offset: -0.25},
]
for (var i = 0; i < assets.length; i++) {
var img = new Image();
img.src = assets[i].url;
img.onload = handle_load;
//use an if statement to grab correct asset
//change page on click
if (img.src === "http://www.livefirelabs.com/images/learn-unix-demo-course.jpg") {
img.onclick = function(e) {
document.location = "https://jsfiddle.net/";
}
}
document.body.appendChild(img);
}
function handle_load() {
//do nothing
}
I am implementing a webgl magnifier which works fine .
But it distorts when I apply zoom using mousewheel.
I am using fabric.js and fcanvas.getZoom() returns the current zoom level that I am using to scale the magnifier.
Here's the codepen .
Can anyone check why it doesn't work while zooming in using mousewheel.
Code :
`
MainCanvas = (function() {
function MainCanvas(image, WIDTH, HEIGHT) {
var err;
this.image = image;
this.WIDTH = WIDTH != null ? WIDTH : 128;
this.HEIGHT = HEIGHT != null ? HEIGHT : 128;
this.mouseout = bind(this.mouseout, this);
this.mouseover = bind(this.mouseover, this);
this.mousemove = bind(this.mousemove, this);
this.render = bind(this.render, this);
zoomcanvas = $(document.createElement('canvas'));
zoomcanvas.css({
'position': 'absolute',
'width': this.WIDTH,
'height': this.HEIGHT,
'z-index': '1000',
'border': '3px solid rgba(0,0,0,0.4)',
'border-radius': '50%',
'box-shadow': '2px 2px 16px 2px #223',
'pointer-events': 'none'
});
$('#canvases').append(zoomcanvas);
med = [0.5, 0.5];
this.scaled = 1;
try {
this.gl = zoomcanvas[0].getContext("experimental-webgl") || zoomcanvas[0].getContext("webgl");
} catch (_error) {
err = _error;
console.log(err.message);
alert(err.message);
}
this.gl.clearColor(0.8, 0.8, 0.8, 1.0);
this.mouse = {
x: .5,
y: .5
};
this.mvMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
this.pMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
this.data = {};
this.initShaders();
this.initBuffers();
this.initImages();
this.render();
this.image.mousemove(this.mousemove);
this.image.mouseover(this.mouseover).mouseout(this.mouseout);
}
MainCanvas.prototype.initShaders = function() {
var fragmentShader, vertexShader;
fragmentShader = this.getShader('shader-fs');
vertexShader = this.getShader('shader-vs');
this.shaderProgram = this.gl.createProgram();
this.gl.attachShader(this.shaderProgram, vertexShader);
this.gl.attachShader(this.shaderProgram, fragmentShader);
this.gl.linkProgram(this.shaderProgram);
if (!this.gl.getProgramParameter(this.shaderProgram, this.gl.LINK_STATUS)) {
console.log('Não pode inicializar shaders!');
}
this.gl.useProgram(this.shaderProgram);
this.data.vertexPositionAttribute = this.gl.getAttribLocation(this.shaderProgram, "aVertexPosition");
this.gl.enableVertexAttribArray(this.data.vertexPositionAttribute);
this.data.textureCoordAttribute = this.gl.getAttribLocation(this.shaderProgram, "aTextureCoord");
this.gl.enableVertexAttribArray(this.data.textureCoordAttribute);
this.data.samplerUniform0 = this.gl.getUniformLocation(this.shaderProgram, "sampler0");
this.data.medUniform = this.gl.getUniformLocation(this.shaderProgram, "med");
this.data.scaledUniform = this.gl.getUniformLocation(this.shaderProgram, "scaled");
};
MainCanvas.prototype.setMatrixUniforms = function() {
var normalMatrix;
this.gl.uniformMatrix4fv(this.data.pMatrixUniform, false, this.pMatrix);
this.gl.uniformMatrix4fv(this.data.mvMatrixUniform, false, this.mvMatrix);
normalMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
return this.gl.uniformMatrix3fv(this.data.nMatrixUniform, false, normalMatrix);
};
MainCanvas.prototype.getShader = function(id) {
var k, shader, shaderScript, str;
shaderScript = document.getElementById(id);
if (shaderScript === null) {
return false;
}
str = '';
k = shaderScript.firstChild;
while (k) {
if (k.nodeType === 3) {
str += k.textContent;
}
k = k.nextSibling;
}
if (shaderScript.type === "x-shader/x-fragment") {
shader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
} else {
shader = this.gl.createShader(this.gl.VERTEX_SHADER);
}
this.gl.shaderSource(shader, str);
this.gl.compileShader(shader);
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
console.log(this.gl.getShaderInfoLog(shader));
return false;
}
return shader;
};
MainCanvas.prototype.initBuffers = function() {
return this.bufferPlane();
};
MainCanvas.prototype.bufferPlane = function() {
var buffer, colors, indices, normais, uv, vertices;
vertices = [-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0];
buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertices), this.gl.STATIC_DRAW);
buffer.itemSize = 3;
buffer.numItems = 4;
this.data.vertexPositionBuffer = buffer;
normais = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1];
buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(normais), this.gl.STATIC_DRAW);
buffer.itemSize = 4;
buffer.numItems = 4;
this.data.vertexColorBuffer = buffer;
uv = [0, 0, 1, 0, 0, 1, 1, 1];
buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(uv), this.gl.STATIC_DRAW);
buffer.itemSize = 2;
buffer.numItems = 4;
this.data.vertexTextureCoordBuffer = buffer;
indices = [0, 1, 2, 2, 3, 1];
buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), this.gl.STATIC_DRAW);
buffer.itemSize = 1;
buffer.numItems = 6;
return this.data.vertexIndexBuffer = buffer;
};
MainCanvas.prototype.handleTexture = function(texture) {
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, canvas);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
this.scaled = Math.max(this.WIDTH / this.image.width(), this.HEIGHT / this.image.height());
return this.scaled / (fcanvas.getZoom());
};
MainCanvas.prototype.initImages = function() {
this.data.texture0 = this.gl.createTexture();
this.handleTexture(this.data.texture0);
};
MainCanvas.prototype.render = function(t) {
this.gl.viewport(0, 0, zoomcanvas[0].width, zoomcanvas[0].height);
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.gl.uniform1f(this.data.scaledUniform, this.scaled / fcanvas.getZoom() / 2);
this.gl.uniform2f(this.data.medUniform, parseFloat(med[0]) , parseFloat(med[1]));
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.data.vertexPositionBuffer);
this.gl.vertexAttribPointer(this.data.vertexPositionAttribute, this.data.vertexPositionBuffer.itemSize, this.gl.FLOAT, false, 0, 0);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.data.vertexTextureCoordBuffer);
this.gl.vertexAttribPointer(this.data.textureCoordAttribute, this.data.vertexTextureCoordBuffer.itemSize, this.gl.FLOAT, false, 0, 0);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.data.texture0);
this.gl.uniform1i(this.data.samplerUniform0, 0);
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.data.vertexIndexBuffer);
this.setMatrixUniforms();
return this.gl.drawElements(this.gl.TRIANGLES, this.data.vertexIndexBuffer.numItems, this.gl.UNSIGNED_SHORT, 0);
};
MainCanvas.prototype.mousemove = function(e) {
var o2, x, y;
o2 = this.image.offset();
x = (e.offsetX + o2.left);
y = (e.offsetY + o2.top);
zoomcanvas.css({
'left': parseInt(x - this.WIDTH * 0.5),
'top': parseInt(y - this.HEIGHT * 0.5)
});
med[0] = (((e.offsetX - imageAttrs.left) ) / (oImg.width));
med[1] = (1.0 - (((e.offsetY - imageAttrs.top)) / (oImg.height)));
$('body').css('cursor', 'none');
return this.render();
};
MainCanvas.prototype.mouseover = function(e) {
return zoomcanvas.show();
};
MainCanvas.prototype.mouseout = function(e) {
return zoomcanvas.fadeOut("fast");
};
return MainCanvas;
})();
window.requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
return window.setTimeout(callback, 40);
};
window.onload = function(e) {
var mainCanvas;
console.clear();
console.log(Date.now());
var width = $("#sampler0")[0].width; var height = $("#sampler0")[0].height;
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
var AR = calculateAspectRatio(width, height);
ctx.drawImage($("#sampler0")[0], 0, 0, AR.renderableWidth, AR.renderableHeight);
var scaleX = AR.renderableWidth / width;
var scaleY = AR.renderableHeight / height;
oImg = new fabric.Image(canvas,
{
selectable : false,
width : width,
height : height,
lockUniScaling: true,
centeredScaling: true,
scaleX : scaleX,
scaleY : scaleY,
alignX : "mid",
alignY : "mid",
});
fcanvas.add(oImg);
///bring image to center
fcanvas.centerObject(oImg);
/////////////////////////////////////////////////////////
///scale image back to default
oImg.scaleX = 1;
oImg.scaleY = 1;
///get left and top for zooming correctly.
imageAttrs.scaleX = scaleX;
fcanvas.zoomToPoint({ x: oImg.left, y: oImg.top }, scaleX);
oImg.on('mouseout', function(event) {
zoomcanvas.fadeOut("fast");
});
oImg.on('mouseover', function(event) {
zoomcanvas.show();
});
imageAttrs.left = oImg.left;
imageAttrs.top = oImg.top;
fcanvas.renderAll();
applyZoom();
return mainCanvas = new MainCanvas($("#canvases"), 256, 256);
};
var calculateAspectRatio = function (width, height) {
var imageAspectRatio = width / height;
var canvasAspectRatio = windowWidth / windowHeight;
var renderableHeight, renderableWidth, xStart, yStart;
var AR = new Object();
/// If image's aspect ratio is less than canvas's we fit on height
/// and place the image centrally along width
if(imageAspectRatio < canvasAspectRatio) {
renderableHeight = windowHeight ;
renderableWidth = width * (renderableHeight / height);
xStart = (windowWidth - renderableWidth) / 2;
yStart = 0;
}
/// If image's aspect ratio is greater than canvas's we fit on width
/// and place the image centrally along height
else if(imageAspectRatio > canvasAspectRatio) {
renderableWidth = $(window).width()
renderableHeight = height * (renderableWidth / width);
xStart = 0;
yStart = ( windowHeight - renderableHeight) / 2;
}
///keep aspect ratio
else {
renderableHeight = windowHeight ;
renderableWidth = windowWidth;
xStart = 0;
yStart = 0;
}
AR.renderableHeight = renderableHeight;
AR.renderableWidth = renderableWidth;
return AR;
}
/**
* Used to apply Zooming on the canvas.
*/
var applyZoom = function () {
var canvasarea = document.getElementById("canvases");
if (canvasarea.addEventListener) {
// IE9, Chrome, Safari, Opera
canvasarea.addEventListener("mousewheel", zoom, false);
// Firefox
canvasarea.addEventListener("DOMMouseScroll", zoom, false);
}
// IE 6/7/8
else canvasarea.attachEvent("onmousewheel", zoom);
return this;
}
function zoom(e) {
var evt=window.event || e;
var delta = evt.detail? evt.detail*(-120) : evt.wheelDelta;
var curZoom = fcanvas.getZoom(), newZoom = curZoom + delta / 4000,
x = e.offsetX, y = e.offsetY;
//applying zoom values.
fcanvas.zoomToPoint({ x: x, y: y }, newZoom);
if(e != null)e.preventDefault();
return false;
}
}).call(this);`
Thanks
I have code to resize rect in kinetic.js that works only once. after that it doesnt make rect resizable, here i am trying to add text within rect but once i set text within rect, click event on "box" not triggering on second time,pls suggest
var box = new Kinetic.Rect({
x : relativeX,
y : relativeY,
offset : [ 50, 25 ],
width : 100,
height : 50,
fill : 'yellow',
stroke : 'black',
strokeWidth : 1,
id:'comment'
});
group.add(box);
var simpleText = new Kinetic.Text({
x : relativeX - 48,
y : relativeY - 30,
text : 'Note',
fontSize : 15,
fontFamily : 'Calibri',
width:box.getWidth(),
height:box.getHeight(),
padding: 4,
fill : 'green',
id:"textBox"
});
group.add(simpleText);
var circle1 = new Kinetic.Circle({
x: relativeX+50,
y:relativeY+25,
radius: 4,
fill: 'red',
stroke: 'black',
strokeWidth: 1,
draggable: true,
visible:false
});
group.add(circle1);
layer.draw();
circle1.on("dragmove",function()
var pos = this.getPosition();
var x = pos.x;
var y = pos.y;
var rectX = box.getX();
var rectY = box.getY();
var x1= x - rectX;
var y1= y - rectY;
box.setSize(x1+50,y1+25);
var textX=simpleText.getX();
var textY=simpleText.getY();
var x2= x - textX;
var y2= y - textY;
simpleText.setSize(x2,y2);
var circle1X=circle1.getX();
var circle1Y=circle1.getY();
var x3=x-circle1X;
var y3=y-circle1Y;
circle1.setSize(x3,y3);
layer.draw();
});
box.on('mouseover', function() {
document.body.style.cursor = 'pointer'; });
box.on('mouseout', function() {
document.body.style.cursor = 'default'; });
circle1.on('mouseover', function() {
document.body.style.cursor = 'se-resize'; });
circle1.on('mouseout', function() {
document.body.style.cursor = 'default'; });
group.on('click', function(evt) {
var shape =circle1.getVisible();
if( shape==false)
{
circle1.show();
layer.draw();
$('html').on('keydown',function(e){
if(e.keyCode === 46){
group.destroy();
layer.draw();
}
});
}else{
circle1.hide();
layer.draw();
}
circle1.setVisible(false);
});
var canvas = document.getElementById('canDemo');
var canvas = document.getElementById('canDemo');
ctx = canvas.getContext('2d'),
font = '14px sans-serif',
hasInput = false;
box.on('dblclick', function() {
// canvas.onclick = function(e) {
if (hasInput) return;
addInput(e.clientX, e.clientY);
});
function addInput(x, y) {
var input = document.createElement('textarea');
input.id="comment_area";
input.type = 'textarea';
input.style.position = "absolute";
input.style.left = (x - 4) + 'px';
input.style.top = (y - 4) + 'px';
input.style.zIndex="3";
input.onkeydown = handleEnter;
document.body.appendChild(input);
input.focus();
hasInput = true; }
function handleEnter(e) {
var keyCode = e.keyCode;
if (keyCode === 27) {
simpleText.setText( $("#comment_area").val());
drawText(this.value, parseInt(this.style.left, 10), parseInt(this.style.top, 10));
document.body.removeChild(this);
hasInput = false;
}
}
$('#comment_area').keypress(function (e){
if(e.keyCode === 13){
e.preventDefault();
this.value = this.value.substring(0, this.selectionStart)+"\n";
}
});
function drawText(txt, x, y) {
ctx.textBaseline = 'top';
ctx.textAlign = 'left';
ctx.font = font;
ctx.fillText(txt, x - 4, y - 4);
layer.draw();}
I'm working in a small project where I'll need create a resizable parent shape and a resizable child shape with a connection line. I did in KinecticJS.
But, I have a problem for calculate the x1, x2 (start connector) and x2,y2 (end connector) when the shape is resizing.
This calculate is in the function addConnection:
var x1 = parentNode.getX() + rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getWidth()/2;
var y2 = childNode.getY() + rectChild.getHeight()/2;
I put my working code in http://jsfiddle.net/geremora/nxDNH/
My Javascript code:
var stage = new Kinetic.Stage({
container: 'container',
width: 400,
height: 400
});
var groupRoot = new Kinetic.Group({
x: 100,
y: 50,
draggable: true,
});
var layer = new Kinetic.Layer();
layer.add(groupRoot);
stage.add(layer);
newRect(groupRoot);
var groupChild = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
layer.add(groupChild);
newRect(groupChild);
var con = addConnection(groupRoot, groupChild);
layer.add(con);
con.moveToBottom();
stage.draw();
function newRect(group){
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 50,
height: 50,
fill: 'blue',
stroke: 'black',
strokeWidth: 1,
name:'rect'
});
group.add(rect);
addAnchor(group, rect.x, rect.y, 'topLeft');
addAnchor(group, rect.getWidth(), rect.y, 'topRight');
addAnchor(group, rect.getWidth(), rect.getHeight(), 'bottomRight');
addAnchor(group, rect.x, rect.getHeight(), 'bottomLeft');
group.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var rect = group.get('.rect')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
rect.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
rect.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 1,
radius: 5,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function addConnection(parentNode, childNode){
var connector = new Kinetic.Line({
drawFunc: function (canvas) {
var rectParent = parentNode.get('.rect')[0];
var rectChild = childNode.get('.rect')[0];
var ctx = canvas.getContext();
var x1 = parentNode.getX() + rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getWidth()/2;
var y2 = childNode.getY() + rectChild.getHeight()/2;
ctx.save();
ctx.strokeStyle = "red";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
},
points: [1, 1, 1, 3],
stroke: "red",
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round',
opacity: 1,
draggable: false
});
return connector;
}
Problem: when you are moving, for example, topLeft anchor, you are changing X position of rectange. But X position of group is not changing. So solution - add rect position when are are calculating position of connector:
var x1 = parentNode.getX() + rectParent.getX()+ rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getX()+ rectChild.getWidth()/2;
var y2 = childNode.getY() + rectChild.getY() + rectChild.getHeight()/2;
http://jsfiddle.net/lavrton/pAQKx/