I'm completely new in HTML and kineticjs and I want to create an animation, which rotates an image around a certain point and by a certain angle. Then it has to stop.
Later I want to implement a way to control the angle by clicking a button. But to the first problem: This is the code so far:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.0.min.js"> </script>
<script defer="defer">
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,
//offset: [x:250, y: 100]
});
/*var imageObj2 = new Image();
imageObj.onload = function() {
var background = new Kinetic.Image({
x: 200,
y: 50,
image: imageObj,
width: 106,
height: 118,
}); */
// add the shape to the layer
layer.add(yoda);
//layer.add(background)
// add the layer to the stage
stage.add(layer);
var angularSpeed = 360 / 4;
var anim = new Kinetic.Animation(function(frame) {
var angleDiff = frame.timeDiff * angularSpeed / 1000;
yoda.rotate(angleDiff);
}, layer);
anim.start();
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
//other image source
</script>
</body>
</html>
Source: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-image-tutorial/
So how can I make the animation stop after - say - 50°?
Thanks for your help!
You can use Tween:
var tweaktween = new Kinetic.Tween({
node : yoda,
rotation : 50,
duration: 1
});
tween.start();
demo: http://jsfiddle.net/lavrton/2DDtW/
Related
Disclaimer: it may be considered this post is a duplicate of this post but I have demonstrated my need specifically.
I have a case in my KonvaJS application where I need to propagate a click event from the Rectangle shape (that is a child of the Upper Layer) to several images that are added to the Lower Layer.
Please note that I have in the Lower layer more than 50 objects between images and shapes, so how can I now what is the target object in the Lower Layer.
Kindly here is an example to demonstrate my need:
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var lowerLayer = new Konva.Layer();
var upperLayer = new Konva.Layer();
//lion
var lionImage = new Image();
lionImage.onload = function() {
var lion = new Konva.Image({
x: 50,
y: 50,
image: lionImage,
width: 106,
height: 118
});
// add the shape to the layer
lowerLayer.add(lion);
stage.draw();
lion.on("click", function() {
alert("you clicked the lion");
});
};
lionImage.src = 'http://konvajs.github.io/assets/lion.png';
//monkey
var monkeyImage = new Image();
monkeyImage.onload = function() {
var monkey = new Konva.Image({
x: 200,
y: 50,
image: monkeyImage,
width: 106,
height: 118
});
// add the shape to the layer
lowerLayer.add(monkey);
stage.draw();
monkey.on("click", function() {
alert("you clicked the monkey");
});
};
monkeyImage.src = 'http://konvajs.github.io/assets/monkey.png';
var upperTransparentBox = new Konva.Rect({
x: 0,
y: 0,
height: stage.height(),
width: stage.width(),
fill: 'transparent',
draggable: false,
name: 'upperTransparentBox'
});
upperTransparentBox.on("click", function() {
alert("you clicked the upper Transparent Box");
});
upperLayer.add(upperTransparentBox);
// add the layer to the stage
stage.add(lowerLayer);
stage.add(upperLayer);
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/konvajs/konva/1.0.2/konva.min.js"></script>
<meta charset="utf-8">
<title>Konva Image Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
Technically it is possible to manually trigger click event on any node.
But I think it is an antipattern. You can just find an intersection with 'getIntersection()' function and do what you need with a node.
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var lowerLayer = new Konva.Layer();
var upperLayer = new Konva.Layer();
//lion
var lionImage = new Image();
lionImage.onload = function() {
var lion = new Konva.Image({
x: 50,
y: 50,
name: 'lion',
image: lionImage,
width: 106,
height: 118
});
// add the shape to the layer
lowerLayer.add(lion);
stage.draw();
lion.on("click", function() {
alert("you clicked the lion");
});
};
lionImage.src = 'http://konvajs.github.io/assets/lion.png';
//monkey
var monkeyImage = new Image();
monkeyImage.onload = function() {
var monkey = new Konva.Image({
x: 200,
y: 50,
name: 'monkey',
image: monkeyImage,
width: 106,
height: 118
});
// add the shape to the layer
lowerLayer.add(monkey);
stage.draw();
monkey.on("click", function() {
alert("you clicked the monkey");
});
};
monkeyImage.src = 'http://konvajs.github.io/assets/monkey.png';
var upperTransparentBox = new Konva.Rect({
x: 0,
y: 0,
height: stage.height(),
width: stage.width(),
fill: 'transparent',
draggable: false,
name: 'upperTransparentBox'
});
upperTransparentBox.on("click", function() {
var target = lowerLayer.getIntersection(stage.getPointerPosition());
if (target) {
alert('clicked on ' + target.name());
}
});
upperLayer.add(upperTransparentBox);
// add the layer to the stage
stage.add(lowerLayer);
stage.add(upperLayer);
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/konvajs/konva/1.0.2/konva.min.js"></script>
<meta charset="utf-8">
<title>Konva Image Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
Im just trying to have the image tween slowly to the left. As far as I can tell, the code is correct. The image loads, but there is no motion.
var stage = new Kinetic.Stage({
container: 'container',
width: 1920,
height: 1080
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var space = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 1920,
height: 1080
});
// add the shape to the layer
layer.add(space);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'http://farm4.staticflickr.com/3768/11633218256_30a04f01c3_o.png';
var tween = new Kinetic.Tween({
node: space,
duration: 20,
x: -1920,
y: 0,
});
setTimeout(function() {
tween.play();
}, 2000);
A few scoping problems with the code:
Make sure your space and tween variables are in scope (currently hidden in .onload)
Since the image will take time to load, you should start the tween in imageObj.onload
Here's code and a Demo: http://jsfiddle.net/m1erickson/JT2cD/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:500px;
height:500px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer();
stage.add(layer);
var space;
var tween;
var imageObj = new Image();
imageObj.onload = function() {
space = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 1920/4,
height: 1080/4
});
// add the shape to the layer
layer.add(space);
// add the layer to the stage
stage.add(layer);
tween = new Kinetic.Tween({
node: space,
duration: 20,
x: -1920/4,
y: 0,
});
setTimeout(function(){ tween.play(); }, 2000);
};
imageObj.src = 'http://farm4.staticflickr.com/3768/11633218256_30a04f01c3_o.png';
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Okay, I now tried to load two Kinetic images, but it still doesn't work. I also tried to put it on another layer and on another stage. Nothing helped. But with one image everything is fine.
var stage = new Kinetic.Stage({
container: 'container',
width: 1600,
height: 1000
});
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
});
var imageObj2 = new Image();
imageObj2.onload = function() {
var vader = new Kinetic.Image({
x: 400,
y: 200,
image: imageObj2,
width: 206,
height: 218
});
// add the shape to the layer
layer.add(yoda);
layer.add(vader);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
imageObj2.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
OLD:
This is a sample code from http://www.html5canvastutorials.com/. I want to load two (or more) images and animate them both by clicking one button. Everything works fine with one picture, but this code confuses me. After the loadImages function is called there is no more reaction, even an alert isn't displayed. Where and how can I place my anim function?(I will implement the other animation later) Thanks for your ideas!
CSS
body {
margin: 0px;
padding: 0px;
}
#buttons {
position: absolute;
top: 50px;
left: 100px;
}
#buttons > input {
padding: 10px;
display: block;
margin-top: 5px;
}
HTML
<div id="container"></div>
<div id="buttons">
<input type="button" id="start" value="Start">
</div>
<canvas id="myCanvas" width="578" height="200"></canvas>
JS
document.getElementById('start').addEventListener('click', function() {
anim.start(); //button should start animation
}, false);
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
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];
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var sources = {
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg',
yoda: 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, function(images) {
context.drawImage(images.darthVader, 100, 30, 200, 137);
context.drawImage(images.yoda, 150, 55, 93, 104);
});
var angularSpeed = 360 / 4; //from this line on it's like the js-code doesn't exist
var anim = new Kinetic.Animation(function(frame) { exist
var angleDiff = frame.timeDiff * angularSpeed / 1000;
images.yoda.rotate(angleDiff); //sources. instead images.?
}, layer);
You are mixing html5 canvas code with KineticJS library code.
You must create Kinetic.Image objects from each of your image objects.
Only then you can use Kinetic.Animation to animate them into rotation.
Ok, so I am new to KineticJS and while playing with it, I can't seem to combine an image background with a rectangle layered above that image. Now, if I remove the background image, then the rectangle shows. Even if I put the rectangle code above the image, still doesn't show on top. Sure it is something simple I am missing but I can't seem to figure out what it is and can't find a similar issue here on stackoverflow. Thanks for the help.
Here is my code:
<!DOCTYPE HTML>
<html>
<head>
<style>
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.4.min.js"></script>
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 600,
height: 450
});
//Layer for our background
var background_layer = new Kinetic.Layer();
//Canvas background image
var canvasBackgroundImage = new Image();
canvasBackgroundImage.onload = function() {
var backgroundImage = new Kinetic.Image({
x: 0,
y: 0,
image: canvasBackgroundImage,
width: 600,
height: 450
});
background_layer.add(backgroundImage);
stage.add(background_layer);
};
canvasBackgroundImage.src = 'images/quiz_back.jpg'; //Location of our background
//Question container
var question_container_layer = new Kinetic.Layer();
var question_container = new Kinetic.Rect({
x: 100,
y: 100,
width: 200,
height: 200,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
question_container_layer.add(question_container);
stage.add(question_container_layer);
</script>
</body>
Your problem is that you're adding background_layer to the stage inside the canvasBackgroundImage.onload function. Javascript will run through the entire script, and add the question_container_layer to the stage first, AND THEN when your image loads, the background_layer will be added to the stage. As a result, the background image always appears on top of your rectangle layer.
To fix this, add the layers to your stage outside of your onload function:
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 600,
height: 450
});
//Layer for our background
var background_layer = new Kinetic.Layer();
var question_container_layer = new Kinetic.Layer();
stage.add(background_layer);
stage.add(question_container_layer);
//Canvas background image
var canvasBackgroundImage = new Image();
canvasBackgroundImage.onload = function() {
var backgroundImage = new Kinetic.Image({
x: 0,
y: 0,
image: canvasBackgroundImage,
width: 600,
height: 450
});
background_layer.add(backgroundImage);
background_layer.draw();
};
canvasBackgroundImage.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg'; //Location of our background
//Question container
var question_container = new Kinetic.Rect({
x: 50,
y: 50,
width: 200,
height: 200,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
question_container_layer.add(question_container);
question_container_layer.draw();
</script>
To avoid this in the future, unless you have dynamic layers to be added to the stage, I would recommend adding all known layers to the stage before doing anything else. That way you can control the ordering of your layers.
Or alternatively, you can use the zIndex property to order your layers. See here: Kinetic.Container#setZIndex
I'm having trouble creating an HTML5 canvas in which a an image is present, a shape is present, and the shape is draggable on the same stage. My gut tells me that I need to create multiple layers or multiple stages/canvases. Then have one be regular and the other be Kinetic. I've found some code for draggable shapes, code for displaying images and shapes, and I think my problem only lies in the implementation of the syntax. Here's the code:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 1px solid #9C9898;
}
</style>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v3.10.0.js"></script>
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 200
var layer = new Kinetic.Layer();
var rectX = stage.getWidth() / 2 - 50;
var rectY = stage.getHeight() / 2 - 25;
var box = new Kinetic.Rect({
x: rectX,
y: rectY,
width: 100,
height: 50,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4,
draggable: true
});
var layer1 = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var image = new Kinetic.Image({
x: stage.getWidth() / 2 - 53,
y: stage.getHeight() / 2 - 59,
image: imageObj,
width: 106,
height: 118
});
layer1.add(image);
stage.add(layer1);
// add cursor styling
box.on("mouseover", function() {
document.body.style.cursor = "pointer";
});
box.on("mouseout", function() {
document.body.style.cursor = "default";
});
layer.add(box);
stage.add(layer);
imageObj.src = "http://www.html5canvastutorials.com/demos/assets/yoda.jpg";
};
</script>
</head>
<body onmousedown="return false;">
<div id="container"></div>
</body>
</html>
Try this website: w3shools.com/html5/html5_draganddrop.asp