Drag and drop inside an image with kineticjs - javascript

I want to drop the star on a tree and detect which tree the star has been dropped on so I can highlight and select it eventually. But I couldn't get more than just moving the star.
I chose for kineticjs because it works with touchscreen so I don't want to use something else if possible. (unless it works with both touchscreen and mouse too)
This is my javascript:
<script defer="defer">
function drawImage(imageObj) {
var stage = new Kinetic.Stage({
container: "star",
width: 900,
height: 500
});
var layer = new Kinetic.Layer();
// star
var star = new Kinetic.Image({
image: imageObj,
x: 376,
y: 30,
width: 40,
height: 46,
draggable: true,
draw: false
});
// add cursor styling
star.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
star.on('mouseout', function() {
document.body.style.cursor = 'default';
});
layer.add(star);
stage.add(layer);
}
var imageObj = new Image();
imageObj.onload = function() {
drawImage(this);
};
imageObj.src = 'http://upload.wikimedia.org/wikipedia/commons/d/df/Star_icon_1.png';
</script>
Please see the fiddle for the full code:
http://jsfiddle.net/hpq7rpnh/1/

Add the trees as their own objects, and then you can check collision between stars and trees:
var starLayer = new Kinetic.Layer(); // its own layer, index should be above tree layer
var treeLayer = new Kinetic.Layer(); // its own layer
stage.add(treeLayer);
stage.add(starLayer);
var tree = new Kinetic.Rectangle( ... );
treeLayer.add(tree);
var tree2 = new Kinetic.Rectangle( ... ); // another tree at another coordinate
treeLayer.add(tree2); // assuming you have a layer for Trees ONLY already
later on, when the user drops the star, you need to check collision
// sample bounding box collision detection
function checkCollision(){
var trees = treeLayer.getChildren(); // gets all the trees
for(tree in trees)
if(star.xCoord > tree.xCoord && star.xCoord + star.width < tree.xCoord + tree.width ... same for y coordinates)
}

Related

HTML5 Canvas how to make image can resizable by Kinetic.js?

I have add image function :
$("ul#img a").click(function(){
addProduct( $('img', this) );
});
function addProduct( imgObj ){
var layer = new Kinetic.Layer();
var imageObj = new Image(); //createimage
imageObj.onload = function() {
var image = new Kinetic.Image({
x: stage.getWidth() / 2 - 53,
y: stage.getHeight() / 2 - 59,
image: imageObj,
draggable: true,
name: "image"
});
// add the shape to the layer
layer.add(image);
// add the layer to the stage
stage.add(layer);
=========== End function add Image to canvas ============
image.on("mouseover", function(){
var imagelayer = this.getLayer();
document.body.style.cursor = "move";
this.setStrokeWidth(2);
this.setStroke("white"); //It's border of image when hover
layer.draw();
writeMessage(messageLayer, "Delete it");}); //DeleteItem
image.on("mouseout", function(){
var imagelayer = this.getLayer();
document.body.style.cursor = "default";
this.setStrokeWidth(0);
this.setStroke("transparent");
layer.draw();
writeMessage(messageLayer, "");});
image.on("dblclick dbltap", function(){
layer.remove(image);
layer.clear();
layer.draw();});};
imageObj.src = imgObj.attr('src'); }
=========== End Event of Image ============
This code can add image to canvas ,can dragable but cant resizable
How to make this image can resizable?
Please explain to me please
Thank you so much.
Kinetic elements do not have a built-in way to let the user resize.
Here's code to let the user drag the right edge of the image to resize the image:
Listen for mousedown, mouseup and mousemove
If mousedown occurs on the right edge of the image, save that mouse x,y,
On each mousemove, scale the image by the aspect ratio created by the distance the mouse has moved.
Example code to get you started:
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var kImage;
var startRight=-1;
var startWidth=0;
var startHeight=0;
var img=new Image();
img.crossOrigin="anonymous";
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/facesSmall.png";
function start(){
kImage = new Kinetic.Image({
image:img,
x:10,
y:10,
width:img.width,
height:img.height,
});
layer.add(kImage);
layer.draw();
}
$(stage.getContent()).on('mousedown', function (event) {
var pos=stage.getPointerPosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
var ipos=kImage.position();
var isize=kImage.getSize();
var right=ipos.x+isize.width;
if(mouseX>right-10 && mouseX<right+10){
startRight=mouseX;
startWidth=isize.width;
startHeight=isize.height;
}
});
$(stage.getContent()).on('mouseup', function (event) {
startRight=-1;
});
$(stage.getContent()).on('mousemove', function (event) {
if(startRight>=0){
var pos=stage.getPointerPosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
var dx=mouseX-startRight;
var scaleFactor=(mouseX-(startRight-startWidth))/startWidth;
kImage.width(startWidth*scaleFactor);
kImage.height(startHeight*scaleFactor);
layer.draw();
}
});
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/kineticjs/5.2.0/kinetic.js"></script>
<h4>Drag the right border of the image to resize<br>it while maintaining aspect ratio.</h4>
<div id="container"></div>

KineticJS which layer clicked?

I use KineticJS add images to layers. I need to know which layer clicked.
This is jsfiddle: http://jsfiddle.net/yvp79ryf/1/
If i clicked first image just need get alert clicked is first layers otherwise second layer
HTML
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.3.min.js"></script>
<script defer="defer">
JavaScript
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: 140,
y: stage.getHeight() / 2 - 59,
image: imageObj,
width: 106,
height: 118
});
layer.add(yoda);
stage.add(layer);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
var layer2 = new Kinetic.Layer();
var imageObj2 = new Image();
imageObj2.onload = function() {
var filteredYoda = new Kinetic.Image({
x: 280,
y: stage.getHeight() / 2 - 59,
image: imageObj2,
width: 106,
height: 118
});
layer2.add(filteredYoda);
stage.add(layer2);
};
imageObj2.src = 'http://demo-stable-ofbiz.apache.org/images/products/GZ-1000/small.png';
You need to set id to layers to identify them.
var layer = new Kinetic.Layer({id:1});
var layer2 = new Kinetic.Layer({id:2});
Add click event handler on stage
stage.on('click', function(e) {
if(e.targetNode.parent.attrs.id == 1){
alert('first layer');
}else{
alert('second layer');
}
});
You can check layer id through the descendants
e is MouseEvent object.
e.targetNode is Kinetic.Image
e.targetNode.parent is Kinetic.Layer
e.targetNode.parent.attrs.id is id of Kinetic.Layer
If you click on an image, you can use .getLayer() to get a reference to the layer that your clicked image is on.
stage.on('click', function(e) {
console.log('layer:',e.target.getLayer().id());
});
KineticJS does not listen for clicks on the empty part of a layer. Therefore, if you click on an empty part of the stage then you cannot tell which layer was clicked. But since since layer2 is above layer then if you click on the empty part of the stage then you're always clicking on the top layer (layer2).

Dynamically adding circles on stage with KineticJS

I have the following code. I want the user to click on a stage object and a circle to be added .
My code
var stage, backgroundLayer, backgroundImage, imageObj;
var pointLayer, pointObj;
var points = {};
imageObj = new Image();
imageObj.src = "../media/proline_ap_pa_ceph__17839_1340650087_1280_1280.png"
window.onload = function (){
stage = new Kinetic.Stage({
width:800,
height:600,
container:'container'
});
pointLayer = new Kinetic.Layer({
width:stage.width,
height:stage.height
});
console.log(backgroundLayer);
console.log("successfully created stage")
stage.add(backgroundLayer);
stage.add(pointLayer);
document.getElementById('hide').addEventListener('click', function(){
backgroundImage.hide();
backgroundLayer.draw();
});
document.getElementById('show').addEventListener('click', function(){
backgroundImage.show();
backgroundLayer.draw();
});
stage.on('click', function (event){
console.log(event);
console.log("clicking on stage");
var point = new Kinetic.Circle({
fill:"black",
radius:40,
width:30,
height:30,
x:event.pageX,
y:event.pageY
});
console.log(point);
pointLayer.add(point);
pointLayer.draw();
stage.draw();
});
};
backgroundLayer = new Kinetic.Layer({
width:800,
height:600,
visible:true
});
imageObj.onload = function (){
console.log("Image loaded adding kinetic image")
backgroundImage = new Kinetic.Image({
image:imageObj,
width:800,
height:600
});
console.log("finised image loading");
console.log("Adding image to background Layer");
backgroundLayer.add(backgroundImage);
}
But no circle is shown on my stage, plus event.target seems to be of type Image, while I clicked on stage. I guess it's because the image sits on top of the layer added first on stage.
Listen for the contentClick event instead of the click event:
stage.on('contentClick',function(){
var pos=stage.getPointerPosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
// and now add your circle
});

How to clear & save canvas layer as image using javascript

I am trying to paint in canvas using kinetic-v4.7.2.min.js. It successfully draw lines when user touch that layer. I am using jsFiddle for this feature.
How can i clear this ractangle layer & how can i save that layer of container as an image?
JSFiddle
// create a stage and a layer
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// an empty stage does not emit mouse-events
// so fill the stage with a background rectangle
// that can emit mouse-events
var background = new Kinetic.Rect({
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
fill: 'white',
stroke: 'black',
strokeWidth: 1,
})
layer.add(background);
layer.draw();
// a flag we use to see if we're dragging the mouse
var isMouseDown = false;
// a reference to the line we are currently drawing
var newline;
// a reference to the array of points making newline
var points = [];
// on the background
// listen for mousedown, mouseup and mousemove events
background.on('mousedown', function () {
onMousedown();
});
background.on('mouseup', function () {
onMouseup();
});
background.on('mousemove', function () {
onMousemove();
});
// On mousedown
// Set the isMouseDown flag to true
// Create a new line,
// Clear the points array for new points
// set newline reference to the newly created line
function onMousedown(event) {
isMouseDown = true;
points = [];
points.push(stage.getMousePosition());
var line = new Kinetic.Line({
points: points,
stroke: "green",
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
newline = line;
}
// on mouseup end the line by clearing the isMouseDown flag
function onMouseup(event) {
isMouseDown = false;
}
// on mousemove
// Add the current mouse position to the points[] array
// Update newline to include all points in points[]
// and redraw the layer
function onMousemove(event) {
if (!isMouseDown) {
return;
};
points.push(stage.getMousePosition());
newline.setPoints(points);
// use layer.drawScene
// this is faster since the "hit" canvas is not refreshed
layer.drawScene();
}
Any help would be appreciated!!
Thanks.
Using toDataURL() method:
DEMO
$('button').on('click', function () {
var img = $('.kineticjs-content').find('canvas').get(0).toDataURL("image/png");
$('body').prepend('<img src="' + img + '">');
});

Interactive drawing with kineticjs

I'd like to draw a rectangle with click and drag. How can I do this ? Where do I have to put my click event listener ? On the stage or on the layer ? I have the following code but it doesn't work :
stage = new Kinetic.Stage({...})
layer = new Kinetic.Layer({...})
stage.add(layer)
stage.on('click', function() {
var pos = stage.getMousePosition();
var rect = new Kinetic.Rect({
x: pos.x,
y: pos.y,
width: 10,
height: 10,
});
layer.add(rect);
layer.draw();
})
Thanks.
As far as i know there is no "click" event on stage in kineticjs. You should use something like this:
stage.getContainer().addEventListener('mousedown', function(evt) {});
Link to a fiddle that shows what I've been working on:
http://jsfiddle.net/robtown/SGQq7/22/
It's a set of drawing tools using KineticJS and Sketch.js
You need to select "make sketch" to draw freehand and then "copy sketch to Kinetic" to copy your sketch into the kinetic stage. Select "Make rectangle" make a rectangle.
I need to include code to post this so here's the code for when you select the "Make Rectangle" button:
$('#makeRect').click(function (e) {
followRect = new Kinetic.Rect({
width: 120,
height: 40,
x: -200,
y:-200,
stroke: 'red',
strokeWidth: 3
});
drawLayer.setVisible(true);
drawLayer.add(followRect);
drawLayer.draw();
makeRect = true;
drawLayer.on("mousemove", function (e) {
if (makeRect) {
followRect.setX(e.x+5);
followRect.setY(e.y+5);
drawLayer.draw();
}
});
This creates a rectangle that follows the mouse until you click on the canvas, then it drops the rectangle into the Redlines layer of the stage:
drawLayer.on("mousedown", function (e) {
//for (var f = 0 ; f < 1; f++) {
//alert(e.length);
if (makeRect) {
addToRedlineLayer(e.x, e.y);
}
//}
followRect.setX(-200);
drawLayer.setVisible(false);
return;
});
I had the exact same problem, and indeed the method of Guilherme works greatly.
But there's a simple alternative: create a transparent Rect (Kinetic rectangle) the same size as the canvas:
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
function writeMessage(messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var shapesLayer = new Kinetic.Layer();
var messageLayer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x:0,
y:0,
width:stage.getWidth(),
height:stage.getHeight(),
stroke:0
});
rect.on('mousemove', function() {
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
writeMessage(messageLayer, 'x: ' + x + ', y: ' + y);
});
stage.getContainer().addEventListener('mouseout', function(evt) {
writeMessage(messageLayer, '');
});
shapesLayer.add(rect);
stage.add(shapesLayer);
stage.add(messageLayer);
}//]]>
</script>
The above code will print the x and y position of the mouse when you hover it over the canvas (a div with id "container"). You of course need to load the KineticJS library before using this code.

Categories

Resources