Binding DOM elements to Kineticjs drag and drop shapes - html

I've been playing with the Kineticjs library. I have successfully added the canvas, created a shape and made it drag-and-drop.
I'd like to have html content from the page bound to or wrapped in the shape to be able to make it draggable in the same way, but still retain the interactive functionality in the html/css/jquery (so not caching the html as a bitmap, I thought about that).
I can't see how to do that, perhaps using the id selectors somehow?
Am I approaching it wrong and perhaps there's a simpler method to achieve the same result?
Appreciate any tips, advice or solutions.

OK so after a bit more playing, I gave up looking for ways to use the DOM, and instead, used the built-in text and image objects in kineticjs to recreate the stuff I first created with html/css. It's a bit long winded, would be interested to see if there's a shorter way.
// Create the Stage
var stage = new Kinetic.Stage({
container: 'container-kinetic',
width: 1024,
height: 768
});
// Start Steve
// Create the layer
var layer = new Kinetic.Layer();
// var rectX = stage.getWidth() / 2 - 50;
// var rectY = stage.getHeight() / 2 - 25;
// create the group
var group = new Kinetic.Group({
x: -365,
y: -275,
draggable: true
});
// circle border for object
var circ = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 43,
fill: '#fff',
stroke: '#cccccc',
strokeWidth: 1,
});
// this isn't doing anything - remove in cleanup
var steve = new Kinetic.Image({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
image: steve,
width: 81,
height: 81,
});
// add the object title
var titleText = new Kinetic.Text({
x: stage.getWidth() / 2 - 70,
y: stage.getHeight() / 2 + 55,
text: 'Steve Schofield - Founder',
fontSize: 10,
fontFamily: 'Maven Pro',
textFill: '#252525'
});
// add the object image
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: stage.getWidth() / 2 - 41,
y: stage.getHeight() / 2 - 41,
image: imageObj,
width: 81,
height: 81
});
// add the shape to the layer
group.add(yoda);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'img/team_1_p3.png';
// add the facebook icon
var imageObjfb = new Image();
imageObjfb.onload = function() {
var fbIcon = new Kinetic.Image({
x: stage.getWidth() / 2 - 26,
y: stage.getHeight() / 2 + 82,
image: imageObjfb,
width: 8,
height: 12
});
// add the shape to the layer
group.add(fbIcon);
// add the layer to the stage
stage.add(layer);
};
imageObjfb.src = 'img/facebook_icon_small.png';
// add the twitter icon
var imageObjtwitter = new Image();
imageObjtwitter.onload = function() {
var twitterIcon = new Kinetic.Image({
x: stage.getWidth() / 2 - 12,
y: stage.getHeight() / 2 + 84,
image: imageObjtwitter,
width: 12,
height: 10
});
// add the shape to the layer
group.add(twitterIcon);
// add the layer to the stage
stage.add(layer);
};
imageObjtwitter.src = 'img/twitter_icon_small.png';
// add the linkedin icon
var imageObjli = new Image();
imageObjli.onload = function() {
var liIcon = new Kinetic.Image({
x: stage.getWidth() / 2 - -4,
y: stage.getHeight() / 2 + 82,
image: imageObjli,
width: 11,
height: 12
});
// add the shape to the layer
group.add(liIcon);
// add the layer to the stage
stage.add(layer);
};
imageObjli.src = 'img/linkedin_icon_small.png';
// add the rss icon
var imageObjrss = new Image();
imageObjrss.onload = function() {
var rssIcon = new Kinetic.Image({
x: stage.getWidth() / 2 + 20,
y: stage.getHeight() / 2 + 83,
image: imageObjrss,
width: 12,
height: 11
});
// add the shape to the layer
group.add(rssIcon);
// add the layer to the stage
stage.add(layer);
};
imageObjrss.src = 'img/rss_icon_small.png';
// add cursor styling
group.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
group.on('mouseout', function() {
document.body.style.cursor = 'default';
});
// add the shape to the layer
group.add(circ);
group.add(steve);
group.add(titleText);
layer.add(group);
// add the layer to the stage
stage.add(layer);
steve.src = 'http://braindu.studiophp.net/investors.braindu/img/team_1_p3.png'; // end Steve

Related

How to rotate image using HTML5 canvas library like: KineticJS or KonvaJS?

I am able to rotate a rectangle (shape) using KineticJS library I would like now to rotate an image, How I can do that?
var stage = new Kinetic.Stage({
container: 'container',
width: 530,
height: 530
});
var layer = new Kinetic.Layer();
var bg = new Kinetic.Image({
x: 0,
y: 0,
width: 530,
height: 530,
fill: '#D7D7D7',
});
/****************** image **********************/
//sticker.setRotationDeg(90);
var imageObj = new Image();
function sticker(v) {
if(!imageObj.src){
var sticker = new Kinetic.Image({
x: 280,
y: 300,
image: imageObj,
draggable: true
});
layer.add(sticker);
}
imageObj.src = 'http://cdn.sstatic.net/photo/img/apple-touch-icon.png';
layer.draw();
}
/****************** image **********************/
layer.add(bg);
stage.add(layer);
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.2.min.js"></script>
<div id="container"></div>
<input type="button" value="ShowSticker" onclick="sticker();"> click show sticker
<input type="button" value="rotate"> up + 5
I want to Click The rotation
step 1 click button show sticker
step 2 click button rotate
Each time you press + 5
or see web : http://jsfiddle.net/m1erickson/Z6Yg8/
As I have understood from you that you want to rotate an image, here is the following:
First I suggest you to use KonvaJS library which is forked from KineticJS but is supported by a community, as now KeniticJS is no longer supported.
In order to rotate in image you need to load it into the layer:
imageObj.onload = function() {
var yoda = new Konva.Image({
x: 50,
y: 50,
image: imageObj,
width: 106,
height: 118,
name: "yoda"
});
And then rotate it:
$("#rotate").click(function () {
layer.find('Image').rotate(500 * Math.PI / 180);
layer.draw();
});
Here is a full example

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/

Crop an image and then apply filter Kinetic

I am using Kinetic for some image processing. What happens is that I crop my image and then by clicking a button I want to make it black and white. For some reason the simple setFilter function is not working in this case, when you do crop first.
This is the code for cropping:
layer.removeChildren();
layer.clear();
image = new Kinetic.Image({
image: canvasImage,
x: (canvasWidth/2-theSelection.w/2),
y: (canvasHeight/2-theSelection.h/2),
width: theSelection.w,
height: theSelection.h,
crop: [theSelection.x, theSelection.y, theSelection.w, theSelection.h],
name: "image_tmp"
});
layer.add(image);
stage.draw();
And here is the function I decided to use for applying the filter:
var imgPixels = ctx.getImageData(xx, yy, imgW, imgH);
for(var y = 0; y < imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
ctx.putImageData(imgPixels, xx, yy, 0, 0, imgPixels.width, imgPixels.height);
So now I get my cropped image with the filter, but if I want to continue doing something to the image object, I am getting:
TypeError: a.getType is not a function
I think also that the image object I used to use in my code, is now like undefined.
So for example I want after the filter to do layer.add(image) and I want image variable to be the new black and white one and not the old one.
So does anyone have an idea what is the problem, or how can I make the new imgPixels to be the same as my image. Thanks in advance
Is there any reason you didn't use the Kinetic.Filters.Grayscale filter?
Here are 2 ways you can do it:
1) Use setFilter (it works!)
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: 200,
y: 50,
image: imageObj,
crop: [0, 0, 50, 100]
});
// add the shape to the layer
layer.add(yoda);
// add the layer to the stage
stage.add(layer);
yoda.setFilter(Kinetic.Filters.Grayscale);
layer.draw();
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
2) Set the filter property on the image beforehand
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: 200,
y: 50,
image: imageObj,
crop: [0, 0, 50, 100],
filter: Kinetic.Filters.Grayscale
});
// add the shape to the layer
layer.add(yoda);
// add the layer to the stage
stage.add(layer);
//yoda.setFilter(Kinetic.Filters.Grayscale);
//layer.draw();
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
Either way you don't need to add any new images, the original Kinetic.Image is filtered black & white.
UPDATE
Open this link: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-image-tutorial/
And copy and paste this code, replacing all the code in the link. It's working fine for me..
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<button id="crop">Crop</button>
<button id="gray">Grayscale</button>
<button id="both">Both</button>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.0.min.js"></script>
<script defer="defer">
var yoda;
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
yoda = new Kinetic.Image({
x: 200,
y: 50,
image: imageObj,
width: 106,
height: 118
});
// add the shape to the layer
layer.add(yoda);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
document.getElementById('crop').addEventListener('click', function() {
yoda.setCrop([20, 20, 50, 50]);
layer.draw();
});
document.getElementById('gray').addEventListener('click', function() {
yoda.setFilter(Kinetic.Filters.Grayscale);
layer.draw();
});
document.getElementById('both').addEventListener('click', function() {
yoda.setCrop([20, 20, 50, 50]);
yoda.setFilter(Kinetic.Filters.Grayscale);
layer.draw();
});
</script>
</body>
</html>

Moving an image in an canvas on page load

Demo
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var yoda = new Kinetic.Image({
x: 200,
y: 50,
image: imageObj,
width: 106,
height: 118
});
// add the shape to the layer
layer.add(yoda);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
var amplitude = 150;
var period = 2000;
// in ms
var centerX = stage.getWidth() / 2;
var anim = new Kinetic.Animation(function(frame) {
yoda.setX(amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX);
}, layer);
anim.start();
How would I have the yoda image animate from left to right, say 50px, once on page load? Is it possible to do this with easing as well? Very new to canvas, thanks for any help. Would this be better suited to be left to jQuery instead?
If you look at console you'll see that yoda is not defined. This is happening because image.onload is a function and variables created inside a function are visible only inside that function. So you need to create yoda outside a function.
Also start the animation only after the image is loaded.
Modified Fiddle

add image as tooltip for rectangle on canvas

I have a grid and I'm looking to basically add a tooltip Image for each rectangle in the grid. Basically, first I need to be able to add an image to the canvas on the rectangle mouse over event. Eventually each rectangle would have it's own image so I need to keep track of the rectangles...do I add them to an array?
Here is my fiddle for what I've got so far:
http://jsfiddle.net/marseilles84/7ZzTh/1/
Here is a sample image source to use:
'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
<div id="container"></div>​
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 500
});
var layer = new Kinetic.Layer();
for (var i=0; i<7; i++)
{
for(c=0; c<18; c++)
{
var colorPentagon = new Kinetic.Rect({
x: (45*c),
y: 45*i,
width:40,
height:40,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
colorPentagon.on('mouseover touchstart', function() {
//code here
});
layer.add(colorPentagon);
}
}
stage.add(layer);
http://jsfiddle.net/7ZzTh/2/
This is probably more of what you're looking for.
colorPentagon.on('mouseover touchstart', function() {
var userPos = stage.getUserPosition();
yoda.setPosition(userPos.x,userPos.y);
layer.add(yoda);
layer.draw();
});
colorPentagon.on('mouseout touchstart', function() {
yoda.remove();
layer.draw();
});
At the beginning you want:
var imageObj = new Image();
var yoda = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 106,
height: 118
});
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';