After updating KineticJS from v4.0.5 to v4.3.1, I can no longer fill a Polygon with an Image using this method:
polygon.setFill({
image: imageObj
});
I end up with a black background. Is there another way around this?
Attempt: I tried poly.setFillPattern(image)
jsfiddle: http://jsfiddle.net/eeSSN/
Remove "fill" config in Kinetic.Polygon.
You created thingImage but never used it.
You can use "setFillPatternImage"
You have to call stage.draw inside iamge.onload
Code:
var stage = new Kinetic.Stage({
container: 'canvas',
width: 600,
height: 600
});
var layer = new Kinetic.Layer();
// Outline
var poly = new Kinetic.Polygon({
points: [0, 0, 400, 0, 400, 400, 0, 400],
//fill: 'red',
stroke: '#000',
strokeWidth: 0,
name: 'poly',
draggable: false
});
var imageObj = new Image();
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
imageObj.onload = function() {
poly.setFillPatternImage(imageObj);
stage.draw();
}
layer.add(poly);
stage.add(layer);
http://jsfiddle.net/lavrton/eeSSN/1/
Related
I currently have some javascript that receives an image from a variable and loads it into the canvas. The canvas is inside a div in order to use kineticjs. I'm loading a regular hexagon with the following code:
function MakeShape()
{
var stage = new Kinetic.Stage({
container: 'container',
width: 490,
height: 225
});
var polyLayer = new Kinetic.Layer();
var hexagon = new Kinetic.RegularPolygon({
x: stage.width()/2,
y: stage.height()/2,
sides: 6,
radius: 70,
fill: 'red',
offset: {
x: 100,
y: 0
},
draggable: true
});
polyLayer.add(hexagon);
stage.add(polyLayer);
}
However, when loading, the layer receives the background of the canvas, when I want the shape to be above the image. Do I have to draw the image onto the layer as well as the shape? How am I supposed to do this when the image is loaded before the shape? Thanks.
I'm not sure what you mean by "javascript receives an image from a variable and loads it into the Canvas". I'm guessing that your Canvas element's is assigned a background-image==that image.
Anyway, new Kinetic.Stage plus new Kinetic.Layer will create a new canvas that covers the container element. So any image you put in your Div and Canvas will be overlaid by the new Canvas that KineticJS creates.
Bottom line...Yes, draw the image onto the layer (using new Kinetic.Image) and eliminate your Canvas element with the image.
Good luck with your project!
[ Added Example code ]
var stage = new Kinetic.Stage({
container: 'container',
width: 490,
height: 225
});
var polyLayer = new Kinetic.Layer();
stage.add(polyLayer);
var hexagon,image1;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/nightscape.jpg";
function start(){
// add the image first
// It's z-index will be lower then the hexagon's z-index
// so the hexagon will be drawn over the image
image1=new Kinetic.Image({
x:0,
y:0,
image:img,
});
polyLayer.add(image1);
hexagon = new Kinetic.RegularPolygon({
x: stage.width()/2,
y: stage.height()/2,
sides: 6,
radius: 70,
fill: 'red',
offset: {
x: 100,
y: 0
},
draggable: true
});
polyLayer.add(hexagon);
polyLayer.draw();
}
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:490px;
height:225px;
}
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
<h4>Background image with draggable hex on top.</h4>
<div id="container"></div>
I would like to animate moving a draggable shape to another position after it has been dragged in KineticJS. I would like to animate the movement of the shape over a period of time (for example, over 1 second). For example, I create a draggable shape and save its initial xy coordinates. I register a "dragend" event on this shape. Then, I drag the shape to a new position. When I release the drag, the dragend event is called. In that event function, I want to animate/ease the shape back to its original position. See my JSFiddle for a complete example: DragSample.
(function () {
//create variables at global scope
var layer;
var stage;
var triangle;
var triangleLastX = 190;
var triangleLastY = 120;
var tween;
function initTween() {
tween = new Kinetic.Tween({
node: triangle,
duration: 1,
easing: Kinetic.Easings.EaseInOut,
x: 400,
y: 200,
});
}
this.init = function () {
layer = new Kinetic.Layer();
stage = new Kinetic.Stage({
container: 'container',
width: 800,
height: 600
});
triangle = new Kinetic.RegularPolygon({
x: 190,
y: 120,
sides: 3,
radius: 80,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
triangle.on('dragstart', function () {
triangleLastX = triangle.attrs.x;
triangleLastY = triangle.attrs.y;
});
triangle.on('dragend', function () {
tween.play();
stage.draw();
});
layer.add(triangle);
stage.add(layer);
initTween ();
}
window.onload = init();
})();
I have tried doing this several ways. The last way I attempted to do this was using Kinetic's Tween(), however, when I play this Tween from the dragend event handler function, it moves the shape back to its original position immediately (i.e. the position when the drag started), then applies the Tween.
Is there any way to achieve animating the movement of a draggable shape to its original position (or any other position for that matter) in dragend using KineticJS?
As I mentioned in my comment above, I have found the solution and that is to simply call my initTween() function in the dragend event handler. Following is the updated source for DragSample
(function () {
//create variables at global scope
var layer;
var stage;
var triangle;
var triangleLastX = 190;
var triangleLastY = 120;
var tween;
function initTween() {
tween = new Kinetic.Tween({
node: triangle,
duration: 1,
easing: Kinetic.Easings.EaseInOut,
x: triangleLastX,
y: triangleLastY,
});
}
this.init = function () {
layer = new Kinetic.Layer();
stage = new Kinetic.Stage({
container: 'container',
width: 800,
height: 600
});
triangle = new Kinetic.RegularPolygon({
x: 190,
y: 120,
sides: 3,
radius: 80,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
triangle.on('dragstart', function () {
});
triangle.on('dragend', function () {
initTween();
tween.play();
stage.draw();
});
layer.add(triangle);
stage.add(layer);
}
window.onload = init();
})();
I'm just starting out the KineticJS library and been playing about with it creating shapes etc.. However, I'm struggling to create a custom circle with my own image in it. I have tried using the fillPattern but it doesn't scale/centre correctly at all. Am I meant to use my own circle image or a rectangle image and then let KineticJS take care of things?
Just to give a bit of background: What I want is 3 balls bouncing in and then settling in place.
Any advice is welcome.
Sorted it... needed the offset values
var ball = new Image();
ball.src = 'ball2.jpg';
ball.height = 230;
ball.width = 230;
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 1000
});
var circle = new Kinetic.Circle({
x: 300,
y: 300,
radius: 115,
fillPatternImage: ball,
fillPatternOffset :{
x: -115,
y: -115
}
});
var layer = new Kinetic.Layer();
// add the shape to the layer
layer.add(circle);
// add the layer to the stage
stage.add(layer);
ball.onload = function () {
stage.draw();
}
Im new to kineticJs and working on adding multiple images on a kinetic.stage.
At first I had successfully created a canvas using this code:
var stage = new Kinetic.Stage({
container: 'content',
width: x,
height: y
});
//declare layer
var layer = new Kinetic.Layer();
//declare image
var baseImage = new Kinetic.Image({
image: $('#img')[0];
});
layer.add(baseImage);
stage.add(layer);
but I have to add more and more images to the canvas every once in a while and so I made a function that adds another image to the canvas. My code goes like this..
function addImageLayer(){
//declare layer
var layer2 = new Kinetic.Layer();
//declare image
var image2 = new Image();
image2.src = "../resources/images/frames/newYearBunny.png";
image2.onload = function(){
var KineticImage2 = new Kinetic.Image({
x: 200,
y: 50,
image: image2,
draggable: true
});
layer2.add(KineticImage2);
stage.add(layer2);
}}
Unfortunately, Ive just added a new on top of my existing whereas I must add a layer.
Thanks
You can add new images to the existing layer
(Make sure you layer.draw() after adding new objects to a layer so they are displayed)
function addImageLayer(){
//declare image
var image2 = new Image();
image2.src = "../resources/images/frames/newYearBunny.png";
image2.onload = function(){
var KineticImage2 = new Kinetic.Image({
x: 200,
y: 50,
image: image2,
draggable: true
});
layer.add(KineticImage2);
layer.draw();
}
}
What I want do is dynamically create a shape on mousedown, and then immediately have it (the shape) follow the mouse cursor until mouseup sets it in place.
Here is what I have so far and it's not working for me.
addNegativeButton.on('mousedown', function(){
var userPos = stage.getUserPosition();
shapesLayer.add(new Kinetic.Image({
image: imageObj,
x: userPos.x,
y: userPos.y,
height: 25,
width: 25,
rotation: 1,
draggable: true,
offset: 12
}));
var last = shapesLayer.getChildren()[shapesLayer.getChildren().length -1];
stage.on("mouseup", function(){
last.setAbsolutePosition(stage.getUserPosition());
stage.off("mouseup");
});
To reiterate:
What I have is an 'addNegativeButton' which when clicked creates a shape.
But I want it to follow the mouse cursor until the click is released.
http://jsfiddle.net/CPrEe/37/
Any suggestions?
Turns out its rather simple ;)
After you add the element/shape, all you have to do is use the simulate function to simulate mouse down and it drags....
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 20,
y: 20,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
//What I really want here is to start dragging the circle until the
//user releases the mouse, which would then place the circle.
rect.on('mousedown', function(evt) {
var userPos = stage.getUserPosition();
var latestElement = new Kinetic.Circle({
x: userPos.x,
y: userPos.y,
radius: 20,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
})
layer.add(latestElement);
// Here's the bit you want. After adding the circle (with draggable:true) simulate the mousedown event on it which will initiate the drag
latestElement.simulate('mousedown');
layer.draw();
});
layer.add(rect);
stage.add(layer);
http://jsfiddle.net/CPrEe/38/
http://kineticjs.com/docs/symbols/Kinetic.Node.php#simulate