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

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>

Related

How to fix glitch with gif animation when loading through Konva.js and Gifler?

I did the gif-animation loading, following the example in the documentation. However, frames are skipped and frames are displayed incorrectly.
This happens to many gif files. Please, how to fix it, does anyone know?
Here is an example error:
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
stage.add(layer);
var canvas = document.createElement('canvas');
// use external library to parse and draw gif animation
function onDrawFrame(ctx, frame) {
// update canvas size
canvas.width = frame.width;
canvas.height = frame.height;
// update canvas that we are using for Konva.Image
ctx.drawImage(frame.buffer, 0, 0);
// redraw the layer
layer.draw();
}
gifler('https://i.gifer.com/8RDg.gif').frames(canvas, onDrawFrame);
// draw resulted canvas into the stage as Konva.Image
var image = new Konva.Image({
image: canvas
});
layer.add(image);
<script src="https://unpkg.com/konva#4.0.4/konva.min.js"></script>
<script src="https://unpkg.com/gifler#0.1.0/gifler.min.js"></script>
<div id="container"></div>
You have to try to use another library. I used libgif.js to solve this issue that is an example
var width = window.innerWidth;
var height = window.innerHeight;
var templateImage = new Image();
templateImage.onload = function(){
// image has been loaded
drawKonva(templateImage);
};
templateImage.src = "https://i.gifer.com/8RDg.gif";
function drawKonva(templateImage) {
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});
var layer = new Konva.Layer();
stage.add(layer);
var gif = new SuperGif({
gif: templateImage,
progressbar_height: 0,
auto_play: true,
loop_mode: true,
draw_while_loading: true
});
gif.load();
var gif_canvas = gif.get_canvas(); // the lib canvas
// a copy of this canvas which will be appended to the doc
var canvas = gif_canvas.cloneNode();
var context = canvas.getContext('2d');
function anim(t) { // our animation loop
context.clearRect(0,0,canvas.width,canvas.height); // in case of transparency ?
context.drawImage(gif_canvas, 0, 0); // draw the gif frame
layer.draw();
requestAnimationFrame(anim);
};
anim();
// draw resulted canvas into the stage as Konva.Image
var image = new Konva.Image({
image: canvas,
draggable: true
});
layer.add(image);
}

Drag and drop inside an image with kineticjs

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)
}

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
});

Draw Smaller moveable Images on big image loaed on Kinectjs canvas

I loaded a big image on to a kinectjs canvas.
Code below:
<div id ="imgarea" ></div>
var imageToCanvas = function(){
var stages = new Kinetic.Stage({
container: "imgarea",
});
var layer = new Kinetic.Layer();
var imageobj = new Image();
imageobj.onload = function(){
var img = new Kinetic.Image({
x: 10,
y: 10,
image: imageobj,
});
layer.add(img);
stages.add(layer);
};
imageobj.src = "foto/next.png";
console.log(imageobj);
};
$(document).ready( function(){
imageToCanvas();
});
please how can i draw smaller moveable and resizeable images(icons)with the onclick event on the big image i drew earlier.i tried doing that with the following code:
<Img src="testImage.jpg" onclick="var layer = new Kinetic.Layer(); drawImage(this.src);" />
But sadly its not working :(....somebody please help. Thanks

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