Kinetic js drag, drop, resize and rotate image - html

I am trying to combine drag and drop resize image and rotating image on touch, and mine is behaving strange http://jsfiddle.net/littlechad/Kuaxn/
My code is as follows:
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 image = group.get('.image')[0];
var stage = group.getStage();
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
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;
}
image.setPosition(topLeft.getPosition());
var height = bottomLeft.attrs.y - topLeft.attrs.y;
var width = image.getWidth()*height/image.getHeight();
topRight.attrs.x = topLeft.attrs.x + width
topRight.attrs.y = topLeft.attrs.y;
bottomRight.attrs.x = topLeft.attrs.x + width;
bottomRight.attrs.y = topLeft.attrs.y + height;
if (width && height) {
image.setSize(width, height);
}
}
function rotate (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 image = group.get('.image')[0];
var stage = group.getStage();
var pos = stage.getMousePosition();
var xd = 150 - pos.x ;
var yd = 150 - pos.y ;
var theta = Math.atan2(yd, xd);
var degree = theta / (Math.PI / 180) - 45;
var height = bottomLeft.attrs.y - topLeft.attrs.y;
var width = image.getWidth() * height / image.getHeight();
console.log(degree);
console.log(width);
console.log(height);
image.setRotationDeg(degree);
return {
x: image.getAbsolutePosition().x,
y: image.getAbsolutePosition().y
}
}
function addAnchor (group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: 'transparent',
strokeWidth: 0,
radius: 20,
name: name,
draggable: false,
dragOnTop: false
});
if(name === 'topRight'){
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 20,
name: name,
draggable: true,
dragOnTop: false
});
}
anchor.on('dragmove', function () {
update(this);
rotate(this);
layer.draw();
});
anchor.on('mousedown touchstart', function () {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function () {
group.setDraggable(true);
layer.draw();
});
group.add(anchor);
}
function initStage () {
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 800
});
var imageGroup = new Kinetic.Group({
x: 150,
y: 150,
draggable: true,
});
var layer = new Kinetic.Layer({
width: 128,
height: 128,
offset: [64, 64]
});
layer.add(imageGroup);
var imgObj = new Image();
var imageInstance = new Kinetic.Image({
x: 0,
y: 0,
image: imgObj,
width: 200,
height: 138,
name: 'image',
});
imgObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
imageGroup.add(imageInstance);
addAnchor(imageGroup, 0, 0, 'topLeft');
addAnchor(imageGroup, 200, 0, 'topRight');
addAnchor(imageGroup, 200, 138, 'bottomRight');
addAnchor(imageGroup, 0, 138, 'bottomLeft');
imageGroup.on('dragstart', function() {
update(this);
rotate(this);
this.moveToTop();
});
stage.add(layer);
stage.draw();
}
function writeMessage (messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
//loadImages(sources, initStage);
initStage();
It seems that updating the offset is the problem, I have tried several things to set the offset so that it stays in the middle, yet I still can't figure out how, I am really new to HTML5 and KineticJs, please help me on this.
UPDATE:
The above fiddle is no longer working due to the fillColor broken on new browsers, I have updated the fiddle, although I haven't been able to figure out the solution for this.
Thanks

You were very close, just using some incorrect method names, and as was said before, the cdn needs to change.
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 image = group.get('.image')[0];
var stage = group.getStage();
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;
}
image.setPosition(topLeft.getPosition());
var height = bottomLeft.attrs.y - topLeft.attrs.y;
var width = image.getWidth()*height/image.getHeight();
topRight.attrs.x = topLeft.attrs.x + width
topRight.attrs.y = topLeft.attrs.y;
bottomRight.attrs.x = topLeft.attrs.x + width;
bottomRight.attrs.y = topLeft.attrs.y + height;
if(width && height) {
image.setSize(width, height);
}
}
function rotate(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 image = group.get('.image')[0];
var stage = group.getStage();
var pos = stage.getPointerPosition();
var xd = 150 - pos.x ;
var yd = 150 - pos.y ;
var theta = Math.atan2(yd, xd);
var degree = theta / (Math.PI / 180) - 45;
var height = bottomLeft.attrs.y - topLeft.attrs.y;
var width = image.getWidth()*height/image.getHeight();
console.log(degree);
console.log(width);
console.log(height);
image.setRotationDeg(degree);
return {
x: image.getAbsolutePosition().x,
y: image.getAbsolutePosition().y
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#fff',
fill: '#fff',
strokeWidth: 2,
radius: 20,
name: name,
draggable: false,
dragOnTop: false
});
if(name === 'topRight'){
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 20,
name: name,
draggable: true,
dragOnTop: false
});
}
anchor.on('dragmove', function() {
update(this);
rotate(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
group.add(anchor);
}
function initStage() {
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 800
});
var imageGroup = new Kinetic.Group({
x: 150,
y: 150,
draggable: true,
});
var layer = new Kinetic.Layer({
width: 128,
height: 128,
offset: [64, 64]
});
layer.add(imageGroup);
var imgObj = new Image();
var imageInstance = new Kinetic.Image({
x: 0,
y: 0,
image: imgObj,
width: 200,
height: 138,
name: 'image',
});
imgObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-
vader.jpg';
imageGroup.add(imageInstance);
addAnchor(imageGroup, 0, 0, 'topLeft');
addAnchor(imageGroup, 200, 0, 'topRight');
addAnchor(imageGroup, 200, 138, 'bottomRight');
addAnchor(imageGroup, 0, 138, 'bottomLeft');
imageGroup.on('dragstart', function() {
update(this);
rotate(this);
this.moveToTop();
});
stage.add(layer);
stage.draw();
}
function writeMessage(messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
loadImages(sources, initStage);
initStage();

Related

HTML5 get base64 code of image created in canvas

var ctx;
function roundedImage() {
var img = new Image();
img.onload = function() {
ctx.beginPath();
ctx.arc(160, 150, 75, 0, Math.PI * 2, true); //draw the circle
ctx.lineWidth = 5;
ctx.strokeStyle = 'white';
ctx.stroke();
ctx.clip();
ctx.closePath();
ctx.drawImage(img, 80, 70, 160, 160);
};
img.src = "xxxxx";
img.crossOrigin = "Anonymous";
}
function fillText(name) {
ctx.fillStyle = 'white';
ctx.font = '40pt Calibri';
ctx.fillText(name, 100, 100);
}
function backImg() {
var background = new Image();
background.src = "xxxxx";
background.onload = function(){
ctx.drawImage(background, 3, 3, canvas.width - 7, canvas.height - 7);
roundedImage()
}
}
function createCanvas(width, height) {
var canvas = document.createElement("canvas");
canvas.id = "canvas";
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
}
function admire() {
createCanvas(400,625)
backImg()
var original64 = canvas.toDataURL
console.log(original64);
}
window.onload = admire();
Everything is working fine but I am unable to get the base64 code. I am getting this in console "ƒ toDataURL() { [native code] }" How can I get base64 of canvas created.
And I want to show that base64 image in another canvas. How can I do that?

Exporting kineticJS to image (datatoURL)

I ran into an issue while using kineticJS to create multiple stages.
I am trying to export multiple "stages" to images but I cant get past exporting the first stage, the datatoURL function doesnt seem to be working, and it breaks my script, or perhaps I'm calling it at the wrong location...
When the user clicks the save button, each stage should be converted to an image and displayed on the same page.
Can anyone tell me why the first stage is not being displayed as an image on the page?
Thanks in advance
Here is the code that puts the stage data into the image placeholder on the page.
document.getElementById('save').addEventListener('click', function() {
stage.toDataURL({
callback: function(dataUrl) {
document.getElementById("canvasimg").src = dataUrl;
document.getElementById("canvasimg").style.display = "inline";
}
});
}, false);
below is the full code:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Canvas</title>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
<script type='text/javascript' src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<script type='text/javascript'>
$(window).load(function(){
var highlightWidth = 8;
var stage = new Kinetic.Stage({
container: 'container1',
width: 300,
height: 100
});
var layer = new Kinetic.Layer();
stage.add(layer);
document.getElementById('save').addEventListener('click', function() {
stage.toDataURL({
callback: function(dataUrl) {
document.getElementById("canvasimg").src = dataUrl;
document.getElementById("canvasimg").style.display = "inline";
}
});
}, false);
var dropzone = new Kinetic.Stage({
container: 'container2',
width: 300,
height: 100
});
var dropLayer = new Kinetic.Layer();
dropzone.add(dropLayer);
addBackground(stage, layer, dropLayer);
layer.draw();
addBackground(dropzone, dropLayer, layer);
dropLayer.draw();
var stage2 = new Kinetic.Stage({
container: 'container3',
width: 300,
height: 100
});
var layer2 = new Kinetic.Layer();
stage2.add(layer2);
var dropzone2 = new Kinetic.Stage({
container: 'container4',
width: 300,
height: 100
});
var dropLayer2 = new Kinetic.Layer();
dropzone2.add(dropLayer2);
addBackground(stage2, layer2, dropLayer2);
layer2.draw();
addBackground(dropzone2, dropLayer2, layer2);
dropLayer2.draw();
var images = {};
var URLs = {
house1: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg',
house2: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg',
house3: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg'
};
loadImages(URLs, start);
function start() {
var house1 = kImage(images.house1, 10, 10, 50, 50, layer);
var house2 = kImage(images.house2, 75, 10, 50, 50, layer);
var house3 = kImage(images.house3, 140, 10, 50, 50, layer);
layer.draw();
var house1 = kImage(images.house1, 10, 10, 50, 50, dropLayer);
var house2 = kImage(images.house2, 75, 10, 50, 50, dropLayer);
var house3 = kImage(images.house3, 140, 10, 50, 50, dropLayer);
dropLayer.draw();
var house1 = kImage(images.house1, 10, 10, 50, 50, layer2);
var house2 = kImage(images.house2, 75, 10, 50, 50, layer2);
var house3 = kImage(images.house3, 140, 10, 50, 50, layer2);
layer.draw();
var house1 = kImage(images.house1, 10, 10, 50, 50, dropLayer2);
var house2 = kImage(images.house2, 75, 10, 50, 50, dropLayer2);
var house3 = kImage(images.house3, 140, 10, 50, 50, dropLayer2);
dropLayer.draw();
}
function swapStagesIfSelected(sourceLayer, destinationLayer, startX, startY) {
var elements = sourceLayer.get("Image");
var totalWidth = 0;
var maxHeight = -999;
var layerWidth = destinationLayer.getStage().getWidth();
var layerHeight = destinationLayer.getStage().getHeight();
for (var i = 0; i < elements.length; i++) {
if (elements[i].isSelected) {
totalWidth += elements[i].getWidth();
maxHeight = Math.max(elements[i].getHeight(), maxHeight);
}
}
if (startX + totalWidth > layerWidth) {
startX = layerWidth - totalWidth - 15;
}
if (startY + maxHeight > layerHeight) {
startY = layerHeight - maxHeight - 15;
}
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.isSelected) {
var img = element.getImage();
kImage(img, startX, startY, element.getWidth(), element.getHeight(), destinationLayer);
startX += element.getWidth() + 10;
element.remove();
}
}
sourceLayer.draw();
destinationLayer.draw();
}
function kImage(image, x, y, width, height, theLayer) {
var image = new Kinetic.Image({
image: image,
x: x,
y: y,
width: width,
height: height,
strokeWidth: 0,
stroke: "white",
draggable: true
});
image.myLayer = theLayer;
image.isSelected = false;
image.on("click", function () {
this.myLayer.draw();
});
image.myLayer.add(image);
return (image);
}
function addBackground(theStage, theLayer, otherLayer) {
var background = new Kinetic.Rect({
x: 0,
y: 0,
width: theStage.getWidth(),
height: theStage.getHeight(),
fill: "white",
stroke: "blue",
strokeWidth: 1
});
background.on("click", function () {
var pos = theStage.getMousePosition();
var mouseX = parseInt(pos.x);
var mouseY = parseInt(pos.y);
swapStagesIfSelected(otherLayer, theLayer, mouseX, mouseY);
});
theLayer.add(background);
}
function loadImages(URLs, callback) {
var loaded = 0;
var needed = 0;
for (var url in URLs) {
needed++;
console.log(url);
}
for (var url in URLs) {
images[url] = new Image();
images[url].onload = function () {
if (++loaded >= needed) {
callback(images);
}
};
images[url].src = URLs[url];
}
}
});
</script>
</head>
<body>
<div id="container1"></div>
<div id="container2"></div>
<div id="container3"></div>
<div id="container4"></div>
<img style="background:url(test1.png);" id="canvasimg" style="display:none;">
<button id="save">Save as image</button>
</body>
</html>

i want to rotate image in center point only of the image and rotation tools stick on top left to image

i'm using Kineticjs to make tools in canvas to resize it or rotate
but when i try to rotate it tool drag away of it and image have a wrong rotate
chick the link of my code
http://jsfiddle.net/vipmaa/qFmsM/3/
$(document).ready(function(){
function randomInt(min,max){
return Math.floor(Math.random()*(max-(min+1))+(min+1));
}
//try to use
var stage = new Kinetic.Stage({
container: 'stage',
width: 500,
height: 450,
offsetX:30,
offsetY:30
});
function update(activeAnchor) {
var group = activeAnchor.getParent();
var RotateSign = group.get('.RotateSign')[0];
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 mask = group.get('.mask')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'RotateSign':
var radius = mask.getWidth() * mask.getScale().x + 55;
group.rotate(radius);
break;
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
RotateSign.setY(anchorY);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
RotateSign.setX(anchorX);
break;
}
mask.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if (width && height && (width > 1 && height > 1)) {
mask.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
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();
update(this);
});
// 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);
if(name == 'topLeft'){
anchor.hide();
}
}
function init(){
var rand = Math.ceil(Math.random() * 100087600);
var id = $(this).attr('data-name')+'_'+rand;
var config = {
id : 'canvas_'+id,
draggable:true,
name: 'art'
}
var x =randomInt(0,100);
var y =randomInt(0,100);
var artGroup = new Kinetic.Group({
x: x,
y: y,
name:'Group',
draggable: true
});
var layer = new Kinetic.Layer(config);
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: x,
y: y,
image: imageObj,
width: imageObj.width,
height: imageObj.height,
name: 'mask',
});
// add the shape to the layer
artGroup.add(yoda);
layer.add(artGroup);
// add the layer to the stage
stage.add(layer);
addAnchor(artGroup, x, y, 'topLeft');// it will be hide
addAnchor(artGroup, (x + imageObj.width), y, 'topRight');
addAnchor(artGroup, (x + imageObj.width), (y + imageObj.height), 'bottomRight');
addAnchor(artGroup, x, (y + imageObj.height), 'bottomLeft');
//Start add rotation tools
var sign = new Kinetic.Path({
name:'RotateSign',
x: x, y: y,
// Path from http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-path-tutorial/
data: 'M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z',
scale: 0.4, fill: 'black',
offset:25,
dragOnTop: false,
draggable: true
});
sign.on('dragmove', function () {
update(this);
layer.draw();
});
sign.on('mousedown touchstart', function () {
//artGroup.setDraggable(false);
//this.moveToTop();
});
sign.on('dragend', function () {
//artGroup.setDraggable(true);
layer.draw();
update(this);
});
artGroup.add (sign);
//End add rotation tools
artGroup.on('dragstart', function () {
this.moveToTop();
});
artGroup.on('dragmove', function() {
var img = layer.get('.mask');
});
layer.on('mouseover', function () {
document.body.style.cursor = 'pointer';
});
layer.on('mouseout', function () {
document.body.style.cursor = 'default';
});
stage.draw();
};
imageObj.src = "http://www.w3schools.com/images/w3logotest2.png";
};
init();});
i want to rotate around image and tool stick in image
can you know what is wrong in the code
You can go through the below,
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,
id :"anchor",
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);
stage.draw();
});
anchor.on('mousedown touchstart', function () {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function () {
group.setDraggable(true);
stage.draw();
});
// add hover styling
anchor.on('mouseover', function () {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
stage.draw();
});
anchor.on('mouseout', function () {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
stage.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
});
var yodaGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
var layer = new Kinetic.Layer();
/*
* go ahead and add the groups
* to the layer and the layer to the
* stage so that the groups have knowledge
* of its layer and stage
*/
layer.add(darthVaderGroup);
layer.add(yodaGroup);
stage.add(layer);
// darth vader
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);
Check http://jsfiddle.net/Qnil/XR7vL/
KineticJS is best to handle rotate image and stuff.
i found new canvas library (Fabric.js) it is solve all things i ask before
you can see blow link
Fabric JS
You can see different in rendering time
fabricjs vs kineticjs

Zoom doesn't work in 5.0.0 like in version bevor

I habe a problem that the zoom function in the new 5.0.0 version doesn't zoom like bevor.
I have tested the new Version 5.0.0 with the follwing test:
See this jsfiddle.
I change the .jsfile to:
http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.0.min.js
and make the changes for the new scale function:
ui.stage.setScale(newscale); --> ui.stage.setScale({x:newscale,y:newscale});
The error is that the zoompoint in 5.0.0 is the left top corner and not the mousepoint liek bevor.
Any suggestions ?
Just change this if you are using kinetic.jsv5.0.0
You can also view all the changes made in Kinetic.jsv5.0.0
ui.stage.setScale(newscale); --> ui.stage.setScale({x:newscale,y:newscale});
and
ui.stage.setOffset(ui.origin.x,ui.origin.y); --> ui.stage.setOffset({x: ui.origin.x, y: ui.origin.y});
or
Apply the following code:
var ui = {
stage: null,
scale: 1,
zoomFactor: 1.1,
origin: {
x: 0,
y: 0
},
zoom: function(event) {
event.preventDefault();
var evt = event.originalEvent,
mx = evt.clientX - ui.stage.getX(),
my = evt.clientY - ui.stage.getY(),
zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0)),
newscale = ui.scale * zoom;
ui.origin.x = mx / ui.scale + ui.origin.x - mx / newscale;
ui.origin.y = my / ui.scale + ui.origin.y - my / newscale;
ui.stage.setOffset({x: ui.origin.x, y: ui.origin.y});
ui.stage.setScale({x: newscale, y: newscale});
ui.stage.draw();
ui.scale *= zoom;
}
};
$(function() {
var width = $(document).width() - 2,
height = $(document).height() - 5;
var stage = ui.stage = new Kinetic.Stage({
container: 'container',
width: width,
height: height,
draggable: true
});
var layer = new Kinetic.Layer();
var box1 = ui.box = new Kinetic.Circle({
x: 50,
y: 50,
radius: 50,
fill: '#00D200',
stroke: 'black',
strokeWidth: 2,
draggable: true
});
var box2 = ui.box = new Kinetic.Circle({
x: 150,
y: 150,
radius: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 2,
draggable: true
});
// add cursor styling
box1.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
box1.on('mouseout', function() {
document.body.style.cursor = 'default';
});
// add cursor styling
box2.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
box2.on('mouseout', function() {
document.body.style.cursor = 'default';
});
layer.add(box1);
layer.add(box2);
stage.add(layer);
$(stage.content).on('mousewheel', ui.zoom);
});
JSFiddle: http://jsfiddle.net/bijaybhandari1989/6J8F5/4/

KineticJs anchors won't follow rectangle in same group

I grabbed a working example of scaling and dragging an image from HTML5 Canvas Tutorials, but I want to achieve the same effect using rectangles.
When I adapt the code to use Rects, the anchors stop following the Rect. What's the secret to getting this working?
Thanks for any tips!
<!DOCTYPE HTML>
<html>
<head>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.4.min.js"></script>
<style>
#container{
float:left;
border:1px solid red;
width:930px;
height:400px;
}
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body onmousedown="return false;">
<div id="container"></div>
<script>
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 mask = group.get('.mask')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
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;
}
mask.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
mask.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
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();
});
// 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 initStage() {
var stage = new Kinetic.Stage({
container: 'container',
width: 930,
height: 400
});
var redGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var greenGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
var layer = new Kinetic.Layer();
layer.add(redGroup);
layer.add(greenGroup);
stage.add(layer);
// red
var redRect = new Kinetic.Rect({
x: 0,
y: 0,
name: 'mask',
width: 100,
height: 100,
fill: 'red',
stroke: 'black',
strokeWidth: 1,
opacity:0.5,
draggable:true
});
redGroup.add(redRect);
addAnchor(redGroup, 0, 0, 'topLeft');
addAnchor(redGroup, 100, 0, 'topRight');
addAnchor(redGroup, 100, 100, 'bottomRight');
addAnchor(redGroup, 0, 100, 'bottomLeft');
redGroup.on('dragstart', function() {
this.moveToTop();
});
// green
var greenRect = new Kinetic.Rect({
x: 0,
y: 0,
name: 'mask',
width: 100,
height: 100,
fill: 'green',
stroke: 'black',
strokeWidth: 1,
opacity:0.5,
draggable:true
});
greenGroup.add(greenRect);
addAnchor(greenGroup, 0, 0, 'topLeft');
addAnchor(greenGroup, 100, 0, 'topRight');
addAnchor(greenGroup, 100, 100, 'bottomRight');
addAnchor(greenGroup, 0, 100, 'bottomLeft');
greenGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
initStage();
</script>
</body>
</html>
becuase you making your rectangle as well draggable, just remove that and it works.
btw thanks for your solution i need something very similar. :)
here it is your working one:
<!DOCTYPE HTML>
<html>
<head>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.4.min.js"></script>
<style>
#container {
float: left;
border: 1px solid red;
width: 930px;
height: 400px;
}
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body onmousedown="return false;">
<div id="container"></div>
<script>
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 mask = group.get('.mask')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
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;
}
mask.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if (width && height) {
mask.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
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();
update(this);
});
// 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 initStage() {
var stage = new Kinetic.Stage({
container: 'container',
width: 930,
height: 400
});
var redGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var greenGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
var layer = new Kinetic.Layer();
layer.add(redGroup);
layer.add(greenGroup);
stage.add(layer);
// red
var redRect = new Kinetic.Rect({
x: 0,
y: 0,
name: 'mask',
width: 100,
height: 100,
fill: 'red',
stroke: 'black',
strokeWidth: 1,
opacity: 0.5
});
redGroup.add(redRect);
addAnchor(redGroup, 0, 0, 'topLeft');
addAnchor(redGroup, 100, 0, 'topRight');
addAnchor(redGroup, 100, 100, 'bottomRight');
addAnchor(redGroup, 0, 100, 'bottomLeft');
redGroup.on('dragstart', function () {
this.moveToTop();
});
// green
var greenRect = new Kinetic.Rect({
x: 0,
y: 0,
name: 'mask',
width: 100,
height: 100,
fill: 'green',
stroke: 'black',
strokeWidth: 1,
opacity: 0.5
});
greenGroup.add(greenRect);
addAnchor(greenGroup, 0, 0, 'topLeft');
addAnchor(greenGroup, 100, 0, 'topRight');
addAnchor(greenGroup, 100, 100, 'bottomRight');
addAnchor(greenGroup, 0, 100, 'bottomLeft');
greenGroup.on('dragstart', function () {
this.moveToTop();
});
stage.draw();
}
initStage();
</script>
</body>
</html>