Can I implement snap to grid operation with images in KineticJS
using jquery? (http://jqueryui.com/demos/draggable/snap-to.html)
Like I have few draggable images inside a canvas and I want them to restrict the movement inside a canvas...
Is it even possible that 2 images can snap together when one comes near the other in the canvas??
And can it be achieved using kinetic.js or javascript...
Thanks
Ashish
Here is the code..
it's a little complicated. I mean I'm loading images from outside the canvas..and there are two sets..now I want one set to be able to snap to other..
<script src="kinetic-v3.8.0.min.js">
</script>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="jquery-1.7.1.js"></script>
<script src="jquery.ui.core.js"></script>
<script src="jquery.ui.widget.js"></script>
<script src="jquery.ui.mouse.js"></script>
<script src="jquery.ui.draggable.js"></script>
<script>
function drawImage(imageObj){
var stage = new Kinetic.Stage("container", 578, 500);
var layer = new Kinetic.Layer();
var x = stage.width / 2 - 200 / 2;
var y = stage.height / 2 - 137 / 2;
var width = 200;
var height = 137;
// darth vader
var darthVaderImg = new Kinetic.Shape(function(){
var context = this.getContext();
context.clearRect(x,y,width,height);
context.drawImage(imageObj, x, y, width, height);
// draw invisible detectable path for image
context.beginPath();
context.rect(x, y, width, height);
context.closePath();
});
// enable drag and drop
darthVaderImg.draggable(true);
// add cursor styling
darthVaderImg.on("mouseover", function(){
document.body.style.cursor = "pointer";
});
darthVaderImg.on("mouseout", function(){
document.body.style.cursor = "default";
});
//remove image on double click
darthVaderImg.on("dblclick dbltap", function(){
layer.remove(darthVaderImg);
layer.draw();
});
layer.add(darthVaderImg);
stage.add(layer);
//events
}
function drawImage2(imageObj){
var stage = new Kinetic.Stage("container", 578, 500);
var layer = new Kinetic.Layer();
var x = stage.width / 2 - 300 ;
var y = stage.height / 2 - 137 ;
var width = 200;
var height = 137;
// darth vader
var darthVaderImg2 = new Kinetic.Shape(function(){
var context = this.getContext();
context.drawImage(imageObj, x, y, width, height);
// draw invisible detectable path for image
context.beginPath();
context.rect(x, y, width, height);
context.closePath();
});
// enable drag and drop
darthVaderImg2.draggable(true);
// add cursor styling
darthVaderImg2.on("mouseover", function(){
document.body.style.cursor = "pointer";
});
darthVaderImg2.on("mouseout", function(){
document.body.style.cursor = "default";
});
//remove image on double click
darthVaderImg2.on("dblclick dbltap", function(){
layer.remove(darthVaderImg2);
layer.draw();
});
layer.add(darthVaderImg2);
stage.add(layer);
$( ".darthVaderImg2" ).draggable({ grid: [ 20,20 ] });
}
function load(img){
// load image
var imageObj = new Image();
imageObj.onload = function(){
drawImage(this);
};
imageObj.src = img.src;
};
function load2(img){
// load image
var imageObj = new Image();
imageObj.onload = function(){
drawImage2(this);
};
imageObj.src = img.src;
};
</script>
<title>HTMl5 drag drop multiple elements</title></head>
<body onmousedown="return false;">
<div id="container">
</div>
<div id="check1">
<ul id="img"> <li><a href="#"onclick="load(document.getElementById('i1'))">
<img class="ui-widget-header" src="dog.png" id="i1" alt="doggie" width="60"height="55"/>
</a></li>
<li>
<a href="#" onclick="load(document.getElementById('i2'))">
<img src="dog2.png" id="i2" alt="Pulpit rock" width="60" height="55" /></a>
</li>
</ul>
</div>
<ul id="img1">
<li><a href="#" onclick="load2(document.getElementById('i4'))">
<img alt="doggie" src="beach.png" id="i4" width="60" height="55" />
</a></li>
<li><a href="#" onclick="load2(document.getElementById('i5'))">
<img alt="doggie" src="cat3.png" id="i5" width="60" height="55" /></a></li>
</ul>
</body>
</html>
You can do this different by using the dragBoundFunc.
return {
x: Math.round(pos.x / grid) * grid,
y: Math.round(pos.y / grid) * grid
}
I have created a complete snapping example: http://jsfiddle.net/PTzsB/1/
I submitted an answer to this question that doesn't use jQuery. Instead, there is a patch you can apply which gives you drag and drop with snap to grid in KineticJS on the HTML5 canvas.
Using jquery draggable UI with kineticJs to make elements snap to grid?
This is all very possible. It requires being a bit more familiar than the average jQuery user, though.
First, implementing the snap-to:
This is a simple idea. You use the jQuery UI Library. You add the necessary function for the 'snap-to' feature, by invoking 'snap-to' on all elements with the class of 'KineticJsImage'.
$( ".KineticJsImage" ).draggable({ snap: true });
Second, for all images propogated by KineticJs, we add the class 'KineticJsImage'
..I don't have anything to work with here...
You simply need to find where the image output is controlled and add a class
of KineticJsImage to the code.
As you mentioned in your first question, you'd found the snap-to operation. The 2nd box in the demo on that page uses the generic (code I mentioned above, as well) snap: true parameter. When you invoke this, you're telling the page to snap all draggable elements with the class of 'KineticJsImage' to ANY element that has ALSO been declared draggle.
$(".someElement").draggable({ snap: false }); // drags wherever, does not snap.
$(".KineticJsImage").draggable({snap: true }); // drags everywhere, snaps to anything.
$(".KineticJsImage").draggable({snap: '.KineticJsImage' }); // This will ensure that
any element with the class of 'KineticJsImage' is not only draggable, but will snap
to any other element with the class of' 'KineticJsImage' that is also draggable.
Everything you want to achieve is doing able with jQuery UI and the draggable / droppable extensions provided within.
Fool around and try to figure out out. When you can't, come back with the code and we'll show you where to go from there.
$("
Related
I am trying to implement drag and drop an image element onto an SVG canvas but the elements are not in the same div. I have tried to use clientX and clientY properties but they are out by about 20 pixels when I come to drop the element. I think the problem is that the SVG coordinates work from the top of the root SVG element but drag and drop coordinates are from the visible view port. When I try to release the rock image on the canvas it just seems to go to any random place on it and sometimes off the canvas completely.
I have uploaded all my code to https://github.com/kiwiheretic/gravity
(It shouldn't be too difficult to just clone the repo and open index.html within the browser to see the problem.)
The relevant HTML code is as follows:
<div style="background-color:black; width: min-content;">
<svg id="space" width="600" height="400" xmlns="http://www.w3.org/2000/svg" onload="makeDraggable(evt)">
</svg>
</div>
<div id="object-block-1" class="objects">
<div class="box">
<img src="asteroid.png" alt="asteroid">
</div>
</div>
</div>
The relevant javascript code is:
var objblock = document.getElementById("object-block-1");
objblock.addEventListener("dragstart", function(evt) {
draggedObject = evt.target;
});
objbl
objblock.addEventListener("dragend", function(evt) {
var x = evt.clientX;
var y = evt.clientY;
var src = draggedObject.getBoundingClientRect();
console.log([x,y]);
var space = document.getElementById("space");
var tgt = space.getBoundingClientRect();
if (doesPointCollide(x,y,tgt)) {
//asteroid = makeAsteroid(x, y, 50, 50);
//space.appendChild(asteroid);
}
});
objblock.addEventListener("drag", function(evt) {
var space = document.getElementById("space");
var rect = space.getBoundingClientRect();
var src = draggedObject.getBoundingClientRect();
var x = (src.x - rect.x) + evt.clientX;
var y = (src.y + rect.y) + evt.clientY;
document.getElementsByName("drag-x")[0].value = parseInt(x);
document.getElementsByName("drag-y")[0].value = parseInt(y);
});
I am using the right hand input boxes as kind of a debugging aid. I am not sure why drag-x and drag-y are not resolving to suitable SVG coordinates within the canvas and what needs to be done to fix that.
Any idea what javascript mouse event attributes and element attributes to work out my SVG coordinates for drag and drop?
I am creating an instructional slideshow with HTML5 canvas. Each slide has animated 2D elements moving an scaling and a navigation pointing to each slide. Ultimately, I'd like to create this without using Animate CC, just incase the program goes away and I'd have to start from scratch if edits need to be made (like Edge files). I'd like to manually code this with HTML5, CSS, and JavaScript preferably utilizing CreateJS.
I've located tutorials on simple slideshows and animated transitions, but I'm moreso looking for animation taking place in each slide or scene.
Is this possible? Is there a tutorial out there? Thank you in advance.
You absolutely don't have to use Adobe Animate to create animated content with CreateJS.
Here is a revised version of #hadders's code using CreateJS. Note that you need to use 1.0 to get the "yoyo" effect, which TweenJS calls "bounce"
var stage, bmp;
function init() {
stage = new createjs.Stage("canvas");
createjs.Ticker.on("tick", stage);
bmp = new createjs.Bitmap("https://s3-us-west-2.amazonaws.com/s.cdpn.io/56901/dog_1_small.jpg");
bmp.set({ x: 50, y: 50, alpha: 1});
stage.addChild(bmp);
createjs.Tween.get(bmp, {loop:-1, bounce:true}).to({
alpha: 0,
x:500,
y:400
}, 1000);
}
init();
Here is a fiddle with it in action: https://jsfiddle.net/8xmy6xuw/
Cheers,
Use a library such as GSAP. Create an object which contains the coords which you'll use to position the canvas elements e.g. {x:100, y:100} then use GSAP to tween the x/y values of the object. The canvas element can then be positioned/animated using this tweened coord object.
This seems like a decent enough example :
https://codepen.io/jonathan/pen/ychlf
HTML
<div id="canvas-wrapper">
<canvas id="canvas" width="800" height="600">canvas not supported</canvas>
</div>
JS
var ctx, img;
function init() {
ctx = document.getElementById("canvas").getContext("2d");
img = new Image();
img.src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/56901/dog_1_small.jpg";
img.xpos = 50;
img.ypos = 50;
img.globalAlpha = 1.0;
img.onload = function() {
TweenLite.ticker.addEventListener("tick",loop);
}
TweenMax.to(img, 1 ,{
globalAlpha:0,
xpos:500,
ypos:400,
repeat:-1,
yoyo:true
});
}
function loop(){
ctx.clearRect(0,0,800,600);
ctx.globalAlpha = img.globalAlpha;
ctx.drawImage(img, img.xpos, img.ypos);
}
init();
hope that helps
When I hover over the transparent part of a PNG, it still acts as though I'm hovering over the actual image. Is there a way that I can prevent that from happening? So that it only takes action when I hover over the visible part of the image, and not the transparent part?
I tried to crop out the transparency, but I couldn't find a way how.
Can be done by converting png to canvas element
This works by loading a png into an HTML-5 canvas element, and then querying the canvas for the alpha value of the clicked pixel.
Working demo: http://jsfiddle.net/x9ScK/3/
HTML as follows...
<!-- create a canvas element to hold the PNG image -->
<canvas id="canvas1" width="500" height="500"></canvas>
Javascript like this...
// select the canvas element with jQuery, and set up
// a click handler for the whole canvas
$('#canvas1').on('click', function(e) {
// utility function for finding the position of the clicked pixel
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
// get the position of clicked pixel
var pos = findPos(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
// get reference to canvas element clicked on
var canvas = this.getContext('2d');
// return array of [RED,GREEN,BLUE,ALPHA] as 0-255 of clicked pixel
var pixel = canvas.getImageData(x, y, 1, 1).data;
// if the alpha is not 0, we clicked a non-transparent pixel
// could be easily adjusted to detect other features of the clicked pixel
if(pixel[3] != 0){
// do something when clicking on image...
alert("Clicked the dice!");
}
});
// get reference to canvas DOM element
var canvas = $('#canvas1')[0];
// get reference to canvas context
var context = canvas.getContext('2d');
// create an empty image
var img = new Image();
// after loading...
img.onload = function() {
// draw the image onto the canvas
context.drawImage(img, 0, 0);
}
// set the image source (can be any url - I used data URI to keep demo self contained)
img.src = "data:image/png;base64,iVBORw0KGgoAAAANS ... more image data ...TkSuQmCC"; // PNG with transparency
I know I've seen sites that let you "choose a color" based on the pixel you're hovering over. I'm not sure how they do it, but one option is to create an html image map (like this), so that different parts of your PNG trigger the "hover" and other parts don't. In essence, the mouse isn't hovering over the PNG; it's hovering over areas that you define in your HTML.
Here's an example that I took directly from the link above:
<body>
<img src="trees.gif" usemap="#green" border="0">
<map name="green">
<area shape="polygon" coords="19,44,45,11,87,37,82,76,49,98" href="http://www.trees.com/save.html">
<area shape="rect" coords="128,132,241,179" href="http://www.trees.com/furniture.html">
<area shape="circle" coords="68,211,35" href="http://www.trees.com/plantations.html">
</map>
</body>
I am using fabric js for canvas animation and I am created canvas with id 'canvas' then put image in it and set left position to zero. It's working fine but animate function is not working.
Please help me.
My code:
HTML:
<canvas id="canvas" width="990" height="285">
This text is displayed if your browser
does not support HTML5 Canvas.
</canvas>
javascript:
var canvas = new fabric.Canvas('canvas');
var image = new Image();
image.src = 'images/body.png';
var bugBody = fabric.Image.fromURL(image.src, function (oImg) {
canvas.add(oImg);
oImg.set('left',0)
});
bugBody.animate('left', 200, {
onChange: canvas.renderAll.bind(canvas)
});
Thanking You.
I think that this happen because your image is not complete loaded.
So, you can put your animation code inside your callback function.
Check this jsfiddle: http://jsfiddle.net/9x9Qc/
Like this:
var srcImg = "http://fabricjs.com/lib/pug.jpg";
// canvas
var canvas = new fabric.Canvas('c');
fabric.Image.fromURL(srcImg, function (oImg) {
canvas.add(oImg);
oImg.set('left',0);
oImg.set('top', 100);
oImg.scale(.25);
canvas.renderAll();
// and then, we can animate the image
oImg.animate('left', 200, {
onChange: canvas.renderAll.bind(canvas)
});
});
I'm trying to make a kinetic canvas where I can add pictures from another source dynamically and I wanted a grid in the background so I used the kinetic.rect from kinetic v3.8.2.
The images needs to be draggable, from kinetic v.3.6.0, but if I set draggable when having v3.8.2 active it breaks.
"config is undefined" according to FireBug.
"img.kinetic.draggable is not a method" says FireBug.
Is there a fix for this?
Can you post a small example? There have been changes to the Kinetic API. Here is a draggable image with 3.8.2:
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='js/kinetic/kinetic-v3.8.2.js'></script>
<script type='text/javascript'>
window.onload = function () {
var stage = new Kinetic.Stage('container', 400, 300);
var layer = new Kinetic.Layer({
name: 'someLayer'
});
var logo = new Image();
logo.onload = function() {
var myImage = new Kinetic.Image({
x: stage.width / 2 - (logo.width / 2)
, y: stage.height - logo.height - 5
, image: logo
, width: logo.width
, height: logo.height
});
myImage.draggable(true)
layer.add(myImage);
layer.draw();
}
logo.src = "\./resources/images/ccs_logo.png";
stage.add(layer)
}
</script>
</head>
<body onmousedown="return false;" bgcolor=#000000>
<div id="container">
</div>
</body>
</html>
Most notably, configs were recently introduced for class instantiation. A Kinetic rectangle used to be defined like so:
var rect = new Kinetic.Rectangle(function () {
//do drawing stuff here
});
But now it is defined with a config (an object literal):
var rect = new Kinetic.Rectangle({
x: 0,
y: 0,
height: 20,
width: 20
});
You can see examples in the docs; also check out the updated KineticJS Tutorials.