Moving an image in an canvas on page load - html

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

Related

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>

How to make KineticJs custom shape

I am trying to make KineticJs html 5 custom shape.
But it is not working in Google chrome. Not draggable in Firefox and also shape are not same in size.
Can anybody tell why?
live code http://jsfiddle.net/prantor19/wGE2a/8/
var stage = new Kinetic.Stage({
container: 'canvas-container',
width: 500,
height: 500,
});
var layer = new Kinetic.Layer();
drawWindow = function(canvas) {
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.x,this.attrs.y);
context.lineTo(this.attrs.width,this.attrs.y);
context.lineTo(this.attrs.width,this.attrs.height);
context.lineTo(this.attrs.x,this.attrs.height);
context.closePath();
context.clip();
context.drawImage(img,this.attrs.img_x,this.attrs.img_y);
}
img = document.createElement('img');
img.src= "http://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Nature_reserve_Kladrubska_hora_in_summer_2011_(17).JPG/1024px-Nature_reserve_Kladrubska_hora_in_summer_2011_(17).JPG";
var window1 = new Kinetic.Shape({
drawFunc: drawWindow,
x: 0,
y: 0,
width: 100,
height: 100,
img:img,
img_x:0,
img_y:0,
draggable: true
});
var window2 = new Kinetic.Shape({
drawFunc: drawWindow,
x: 10,
y: 60,
width: 100,
height: 100,
img:img,
img_x:-250,
img_y:0,
draggable: true
});
pointercursor = function() {
document.body.style.cursor = 'pointer';
}
defaultCursor = function() {
document.body.style.cursor = 'default';
}
window1.on('mouseover',pointercursor );
window1.on('mouseout', defaultCursor);
window2.on('mouseover',pointercursor );
window2.on('mouseout', defaultCursor);
layer.add(window1);
layer.add(window2);
stage.add(layer);
Your script has errors in it
Unable to get image data from canvas because the canvas has been tainted by cross-origin data. kinetic-v4.3.2-beta.js:4365
Uncaught Error: SecurityError: DOM Exception 18
Chrome refuse to work with cross domain images on cavas.
For dragging, you need to add this set stroke for the shape
stroke: 'black',
and at the end of drawFunc
canvas.fillStroke(this);
Here is the my working version from yours
http://jsfiddle.net/W7SGT/
You should be using the canvas renderer when drawing a custom shape in KienticJS, or else it has no way to handle the events on the shape. Here's a tutorial on custom shapes:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/
you might also take a look at the Kinetic.Image shape to see how it handles images specifically:
https://github.com/ericdrowell/KineticJS/blob/master/src/shapes/Image.js

Binding DOM elements to Kineticjs drag and drop shapes

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

Cannot use Kineticjs in html5

I want to use the Kinetic js library in order to make the drag and resize effect in my images on the canvas.
So I am following this example http://www.html5canvastutorials.com/labs/html5-canvas-drag-and-drop-resize-and-invert-images/
My html let's say is like that:
.....
<div id="container"></div>
.....
Then on load I do:
$(document).ready(function() {
loadImage()
});
function loadImage(){
imageObj = new Image();
imageObj.onload = function(){
var stage = new Kinetic.Stage("container", 578, 200);
var layer = new Kinetic.Layer();
var x = stage.width / 2 - 200 / 2;
var y = stage.height / 2 - 137 / 2;
var image = new Kinetic.Image({
image: imageObj,
x: x,
y: y
});
image.draggable(true);
// add cursor styling
image.on("mouseover", function(){
document.body.style.cursor = "pointer";
});
image.on("mouseout", function(){
document.body.style.cursor = "default";
});
layer.add(image);
stage.add(layer);
};
imageObj.src = 'myImage.png';
}
But what I get is this message:
"Uncaught TypeError: Cannot call method 'appendChild' of undefined"
referring I think in the container div.
What could be the problem?
Thanks in advance
The constructor call is not right.
Try
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 363
});
For the drag part, you can make your layer draggable with
var layer = new Kinetic.Layer({draggable: true});
You can see a basic example of this working in this fiddle
Try setDraggable:
image.setDraggable(true);
But, have to ask, why dont you use the canvas constructor from Kinetic? I believe that you cannot use this library if you are manipulating the canvas directly

Html 5 canvas update with KinetickJS

I am using KinetickJS to draw images on screen.
I have a layer on the stage, and recieve 1000 of images in base64 format.
First I try to draw them with Kinetic
Example 1, works fine BUT after 1000 of images when I try to drag or do something with layer it became veeeeeeeery slow.So I try next example
var imageObj = new Image();
imageObj.onload = function () {
var image = new Kinetic.Image({
x: imageInfo.LocationX,
y: imageInfo.LocationY,
image: imageObj,
width: imageInfo.Width,
height: imageInfo.Height,
name: "Update"
});
layer.add(image);
layer.draw();
};
imageObj.src = "data:image/jpeg;base64," + imageInfo.Image;
Example 2, but in this case canvas began blinking for each update
var imageObj = new Image();
imageObj.onload = function () {
var canvas = layer.canvas;
var context = canvas.getContext('2d');
// context.globalCompositeOperation = "destination-over";
context.drawImage(imageObj, imageInfo.LocationX, imageInfo.LocationY);
};
imageObj.src = "data:image/jpeg;base64," + imageInfo.Image;
So do you have any ideas how to make it faster and/or disable blinking?
The newest KineticJS 4.3 speeds up dragging and other functionality quite a lot. This would probably fix your problem.
http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.0.min.js