draw line without default selection in fabric.js - javascript

Good Night, dear colleages!
I need two draw application with two buttons: selection and draw line.
The button "selection" should select shapes to tranform them.
THe button draw line shoul draw line.
Now my code draw line and made it selected. I want to devide this functions. How should I solve my problem?
var Line = (function() {
function Line(canvas) {
this.canvas = canvas;
this.isDrawing = false;
this.bindEvents();
}
Line.prototype.bindEvents = function() {
var inst = this;
inst.canvas.on('mouse:down', function(o) {
inst.onMouseDown(o);
});
inst.canvas.on('mouse:move', function(o) {
inst.onMouseMove(o);
});
inst.canvas.on('mouse:up', function(o) {
inst.onMouseUp(o);
});
inst.canvas.on('object:moving', function(o) {
inst.disable();
})
}
Line.prototype.onMouseUp = function(o) {
var inst = this;
if (inst.isEnable()) {
inst.disable();
}
};
Line.prototype.onMouseMove = function(o) {
var inst = this;
if (!inst.isEnable()) {
return;
}
var pointer = inst.canvas.getPointer(o.e);
var activeObj = inst.canvas.getActiveObject();
activeObj.set({
x2: pointer.x,
y2: pointer.y
});
activeObj.setCoords();
inst.canvas.renderAll();
};
Line.prototype.onMouseDown = function(o) {
var inst = this;
inst.enable();
var pointer = inst.canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
var line = new fabric.Line(points, {
strokeWidth: 5,
stroke: 'red',
fill: 'red',
originX: 'center',
originY: 'center',
hasBorders: false,
hasControls: false
});
inst.canvas.add(line).setActiveObject(line);
};
Line.prototype.isEnable = function() {
return this.isDrawing;
}
Line.prototype.enable = function() {
this.isDrawing = true;
}
Line.prototype.disable = function() {
this.isDrawing = false;
}
return Line;
}());
console.log(fabric);
var canvas = new fabric.Canvas('canvas');
var line = new Line(canvas);
<div id="canvasContainer">
<canvas id="canvas" width="400" height="400" style="border: solid 1px"></canvas>
</div>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"
></script>

At the moment you have both drawing and selecting because Fabric makes it's associated canvas selectable by default.
This behaviour is controlled by changing the boolean .selection property on the object returned by calling new fabric.Canvas().
So all you have to do is set up two buttons (Select/Draw), set canvas.selection to the desired state and return from the mouseMove handler before doing any drawing in case selection==true.
Here's an example:
function select(state) {
canvas.selection = state;
}
var Line = (function() {
function Line(canvas) {
this.canvas = canvas;
this.isDrawing = false;
this.bindEvents();
}
Line.prototype.bindEvents = function() {
var inst = this;
inst.canvas.on('mouse:down', function(o) {
inst.onMouseDown(o);
});
inst.canvas.on('mouse:move', function(o) {
inst.onMouseMove(o);
});
inst.canvas.on('mouse:up', function(o) {
inst.onMouseUp(o);
});
inst.canvas.on('object:moving', function(o) {
inst.disable();
})
}
Line.prototype.onMouseUp = function(o) {
var inst = this;
if (inst.isEnable()) {
inst.disable();
}
};
Line.prototype.onMouseMove = function(o) {
var inst = this;
if (!inst.isEnable() || canvas.selection) {
return;
}
var pointer = inst.canvas.getPointer(o.e);
var activeObj = inst.canvas.getActiveObject();
activeObj.set({
x2: pointer.x,
y2: pointer.y
});
activeObj.setCoords();
inst.canvas.renderAll();
};
Line.prototype.onMouseDown = function(o) {
var inst = this;
inst.enable();
var pointer = inst.canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
var line = new fabric.Line(points, {
strokeWidth: 5,
stroke: 'red',
fill: 'red',
originX: 'center',
originY: 'center',
hasBorders: false,
hasControls: false
});
inst.canvas.add(line).setActiveObject(line);
};
Line.prototype.isEnable = function() {
return this.isDrawing;
}
Line.prototype.enable = function() {
this.isDrawing = true;
}
Line.prototype.disable = function() {
this.isDrawing = false;
}
return Line;
}());
var canvas = new fabric.Canvas('canvas');
canvas.selection = false;
var line = new Line(canvas);
<div id="canvasContainer">
<canvas id="canvas" width="400" height="400" style="border: solid 1px"></canvas>
</div>
<button onclick='select(true);'>Select</button>
<button onclick='select(false);'>Draw</button>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>

Related

FabricJS canvas drawImage not displaying image

Attempting to create a custom class that will display an image on the top left corner of a Fabric rectangle.
Extending the fabric class and calling ctx.drawImage isn't displaying anything.
var CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
const image = new Image();
image.src = signBtn;
this.callSuper('initialize', options);
this.set('label', options.label || '');
this.set('image', image);
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
ctx.drawImage(this.image, this.left+10, this.top-5, 15, 15);
}
});
fillText is working fine and displaying the label properly.
Tried a few different things thinking the image isn't loaded. It's imported as an SVG. I've gotten it to display in other ways but prefer to have a custom class handle this instead of event handlers.
You need to set image after load. You can use image.onload event callback, or use fabric.util.loadImage
DEMO
fabric.CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'customRect',
initialize: function(options) {
options || (options = { });
var that = this;
this.imageLoaded = false;
fabric.util.loadImage(options.signBtn,function(img){
that.set('image', img);
that.imageLoaded = true;
that.dirty = true;
//if canvas is global
canvas.renderAll();
},{
crossOrigin : 'annonymous'
});
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.label,
image : this.image
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
this.imageLoaded && ctx.drawImage(this.image, 10, -5, 15, 15);
}
});
fabric.CustomRect.fromObject = function(object, callback) {
return fabric.Object._fromObject('CustomRect', object, callback);
};
var url = 'https://upload.wikimedia.org/wikipedia/en/8/80/Wikipedia-logo-v2.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.CustomRect({
signBtn: url,
left : 10,
top : 10,
width : 200,
height: 200,
fill: 'green',
label : 'test'
});
canvas.add(rect);
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
canvas{
border:2px solid #000;
}
<script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script>
<canvas id="canvas" width="300" height="300"></canvas>
<button onclick="loadfromjson()">loadfromjson </button>
I believe there are some missing values like this.width and this.height?
In addition to that, you have to wait until the image is loaded to draw it. You can do something like this:
var CustomRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function(options) {
options || (options = { });
const image = new Image();
image.src = 'https://i.stack.imgur.com/CYp8Y.jpg';
this.callSuper('initialize', options);
image.onload = (function() {
this.width = image.width;
this.height = image.height;
this.image_loaded = true;
}).bind(this);
this.set('label', options.label || '');
this.set('image', image);
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function(ctx) {
if (this.image_loaded) {
this.callSuper('_render', ctx);
console.log(-this.width / 2, -this.height / 2);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
}
}
});
Note these two changes:
image.onload = (function() {
this.width = image.width;
this.height = image.height;
this.image_loaded = true;
}).bind(this);
I set the image_loaded to true inside the initialize method once the image is loaded. Then in the _render method I check if the image is loaded, and then draw it.
if(this.loaded){
//............
ctx.drawImage(this.image, -this.width / 2, -this.height / 2);
}
Here's a fiddle: https://jsfiddle.net/nimeshka/enL61g0w/55/
You might need to click on the canvas to trigger the render event. Otherwise you won't see the rectangle in the output box. (I haven't added it)
Hope it helps :)

Canvas background image clears when drawing over it

The application I'm attempting to write has a user upload an image to a canvas and then draw lines over it. So far I have the uploading to the canvas down as well as the drawing of the lines, except that whenever I draw a line on the canvas, the uploaded image disappears. Below you'll see the html and javascript code I currently have for the app. The various elements were obtained from various tutorials so i'm assuming there is some incompatibility that they are overwriting each other.
HTML
<input type='file' id="fileUpload">
<canvas id="c" width = 750 height= 400 style="border:1px solid #ccc"></canvas>
Javascript
// begin file upload block
function el(id) { return document.getElementById(id); }
var canvas = el("c");
var context = canvas.getContext("2d");
function readImage() {
if (this.files && this.files[0]) {
var FR = new FileReader();
FR.onload = function (e) {
var img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0,img.width,img.height,0,0,750,400);
};
img.src = e.target.result;
};
FR.readAsDataURL(this.files[0]);
}
}
el("fileUpload").addEventListener("change", readImage, false);
//end file upload block
//begin line drawing block
var canvas = new fabric.Canvas('c', { selection: false });
var line, isDown;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({ x2: pointer.x, y2: pointer.y });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
//end line drawing block
Use fabric.Image.fromURL to load image and then add to canvas using canvas.add().
DEMO
//begin line drawing block
var canvas = new fabric.Canvas('c', {
selection: false
});
var line, isDown;
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({
x2: pointer.x,
y2: pointer.y
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
//end line drawing block
// begin file upload block
function el(id) {
return document.getElementById(id);
}
function readImage() {
if (this.files && this.files[0]) {
var FR = new FileReader();
FR.onload = function(e) {
fabric.Image.fromURL(e.target.result, function(img) {
img.set({
left: 0,
top: 0,
evented: false
});
img.scaleToWidth(canvas.width);
img.setCoords();
canvas.add(img);
})
};
FR.readAsDataURL(this.files[0]);
}
}
el("fileUpload").addEventListener("change", readImage, false);
//end file upload block
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<input type='file' id="fileUpload">
<canvas id="c" width = 750 height= 400 style="border:1px solid #ccc"></canvas>

Get X and Y of a shape after dragging in Konva JS

I'm using Konva JS in my project. I'm adding a shape on a button click which is draggable. On click of the shape i need to get X and Y positions of the shape. getX and getY functions are returning the original X and Y. How can I update the X and Y after dragging.
Example code below.
var stage = new Konva.Stage({
container: 'canvas', // id of container <div>
width: 500,
height:300
});
jQuery("#add-shape").click(function(){
addShape();
});
var addShape = function(){
console.log("add shape");
var layer = new Konva.Layer();
var parentContainer = new Konva.Rect({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
width: 200,
height: 60,
cornerRadius: 10,
fill: '#ccc'
});
var smallCircle = new Konva.Circle({
x: stage.getWidth() / 2 + 200,
y: stage.getHeight() / 2 + 30,
radius: 15,
fill: "#F2784B",
stroke: "white",
strokeWidth: 2
});
smallCircle.on('click', function() {
console.log(this.getX(),this.getY());
addArrow(this.getX(),this.getY());
//get current X and Y here instead of origina X and Y
});
layer.add(parentContainer);
layer.add(smallCircle);
layer.draggable('true');
stage.add(layer);
}
var addArrow = function(arrowX,arrowY){
var connectorLayer = new Konva.Layer();
var connector = new Konva.Arrow({
points: [arrowX,arrowY,arrowX+10,arrowY],
pointerLength: 4,
pointerWidth: 4,
fill: 'black',
stroke: 'black',
strokeWidth: 2
});
connectorLayer.add(connector);
stage.add(connectorLayer);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.0.2/konva.min.js"></script>
<button id="add-shape">
Add shape
</button>
<div id="canvas">
</div>
If you need to get a mouse position you can use:
smallCircle.on('click', function() {
console.log(stage.getPointerPosition());
});
box.on('mouseout', function () {
document.body.style.cursor = 'default';
console.log(box.attrs.x);
console.log(box.attrs.y);
});
I don't know if this is what you're looking for and it's too late but i'll post it anyway for future developers..
Lets say this is my watermark image inside the layer and bluh bluh and i want it's position getX() and getY(): I use the group like this:
First the regular stuff to add the image:
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('Image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.position(topLeft.position());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if (width && height) {
image.width(width);
image.height(height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Konva.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function () {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function () {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function () {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function () {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function () {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
var stage = new Konva.Stage({
container: 'container',
width: 595,
height: 842
});
var layer = new Konva.Layer();
stage.add(layer);
//WaterMark
var WaterMarkImg = new Konva.Image({
width: 595,
height: 842
});
var WaterMarkGroup = new Konva.Group({
x: 0,
y: 0,
draggable: true
});
layer.add(WaterMarkGroup);
WaterMarkGroup.add(WaterMarkImg);
addAnchor(WaterMarkGroup, 0, 0, 'topLeft');
addAnchor(WaterMarkGroup, 595, 0, 'topRight');
addAnchor(WaterMarkGroup, 595, 842, 'bottomRight');
addAnchor(WaterMarkGroup, 0, 842, 'bottomLeft');
var imageObj1 = new Image();
imageObj1.onload = function () {
WaterMarkImg.image(imageObj1);
layer.draw();
};
imageObj1.src = "some image Url";
and this is simply the getX(): very simple
var x = WaterMarkGroup.getX();
alert(x);
I hope this helps anyone looking for it.
This is not the exact answer for the question. point is the draggable shape.
point.on('dragmove', (t) => {
console.log("dragmove", t.target.x(), t.target.y());
});
use shape.getAttr("x") and shape.getAttr("y"), following is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--mobile friendly-->
<meta name="viewport" content="width=device-width, user-scalable=yes">
</head>
<body>
<div id="c"></div>
<script type="module">
import "../../node_modules/konva/konva.js"
var stage = new Konva.Stage({
container: "#c",
width: 500,
height: 500
})
var layer = new Konva.Layer()
stage.add(layer)
var c = (x, y) => {
return new Konva.Circle({
x: x,
y: y,
stroke: "lightblue",
strokeWidth: 2,
radius: 10,
draggable: true
})
}
let c1 = c(50, 50)
layer.add(c1)
var c2 = c(100, 50)
layer.add(c2)
c1.on("dragmove", () => {
c2.setAttr("y", c1.getAttr("y"))
})
layer.draw()
</script>
</body>
</html>

Game loop not doing what its supposed to

Hi I'm trying to make a very simple game using javascripts canvas element. I have a rectangle thats drawn on the canvas and I would like for it to move across the canvas when user clicks a button but its not working.
here is my html:
<style>
canvas {
border: 1px solid black;
height: 300px;
width:500px;
}
</style>
</head>
<body>
<button id = "play">Click to play</button>
</body>
My javascript:
$( document ).ready(function() {
var x = document.createElement("CANVAS");
var ctx = x.getContext("2d");
ctx.fillStyle = "#FF0000";
var x1 = 10;
var y = 10;
ctx.fillRect(x1, y, 80, 10);
document.body.appendChild(x);
var Game = {stopped:true};;
Game.draw = function() {
ctx.fillRect(x1, y, 80, 10);
};
Game.update = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
x1 = x1+5;
};
Game.run = function() {
Game.update();
Game.draw();
};
$("#play").click(function() {
Game.stopped = false;
while (!Game.stopped){
Game.run();
}
});
});
There are multiple problems in your script.
there is no variable called, canvas it is x
Your loop is an infinite while loop, which does not give any time for the UI to update - since browser tab is a single threaded app both js execution and the repaint/refresh of the UI happens in the same thread
So
var interval;
$("#play").click(function () {
Game.stopped = false;
interval = setInterval(Game.run, 5);
});
$("#stop").click(function () {
Game.stopped = true;
clearInterval(interval);
});
Demo: Fiddle
There is another simple implement:
$(document).ready(function () {
var canvas = document.createElement("CANVAS");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FF0000";
var x1 = 10;
var y = 10;
ctx.fillRect(x1, y, 80, 10);
document.body.appendChild(canvas);
var Game = {stopped: true};
;
Game.draw = function () {
ctx.fillRect(x1, y, 80, 10);
};
Game.update = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
x1 = x1 + 5;
};
Game.run = function () {
Game.update();
Game.draw();
};
$("#play").click(function () {
Game.stopped = false;
// while (!Game.stopped) {
// Game.run();
// }
if(!Game.stopped){
setInterval(Game.run,1000);
}
});
});
For animation, it's better to use Window.requestAnimationFrame(), if you want to get a better performance.

How to get the position(in coordinates) of any image element(resizable/draggable) drawn upon html5 canvas?

currently i am drawing an image on a html5 canvas onclicking upon that image. the code for drawing that image is given below :
This is the given script function :
<script>
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('.image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
image.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
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];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container_canvas',
width: 578,
height: 400
});
var darthVaderGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var layer = new Kinetic.Layer();
layer.add(darthVaderGroup);
stage.add(layer);
var darthVaderImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.darthVader,
width: 200,
height: 138,
name: 'image'
});
darthVaderGroup.add(darthVaderImg);
addAnchor(darthVaderGroup, 0, 0, 'topLeft');
addAnchor(darthVaderGroup, 200, 0, 'topRight');
addAnchor(darthVaderGroup, 200, 138, 'bottomRight');
addAnchor(darthVaderGroup, 0, 138, 'bottomLeft');
darthVaderGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
function putDesign(designSrc)
{
designSrc = designSrc.split("images/");
var sources = {
darthVader: 'images/'+designSrc[1],
};
loadImages(sources, initStage);
}
</script>
and i am usinmg kinetic-v4.4.0.min.js (http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.0.min.js) for this,
and in html i am just calling this function putDesign , so this code will draw a canvas in this iv.
<div class="behind" id="behind">
<div id="canvasProductImage" style="text-align:center; width:300px; height:300px; background:url(images/a.png) 100px 100px no-repeat;">
<div id="container_canvas"></div>
</div>
Now this code will make me to draw an image in a div. here the image 1(tshirt (background image of the div in which we will draw our canvas)) , and image 2 (the drawn element),
so the mai task is that how can i get the position of drwan image, means how will i know the position of the drawn image on the canvas in coordinates ? as the image object is resizable ansd draggable so i want the last positioned coordinates ? Thanks in advance i am very near to my objective, kindly help.
image first :
image second :
How to get draggable/resizable image information (X/Y/Width/Height)
This code will report your image info when you drag/resize it:
darthVaderGroup.on("dragend",function(){$("#info").text(getImageInfo());});
function getImageInfo(){
var image=darthVaderImg;
return(
" X/Y:"+
image.getAbsolutePosition().x+"/"+
image.getAbsolutePosition().y+" -- Width/Height:"+
image.getWidth()+"/"+
image.getHeight()
);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/Hm9uN/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.1.min.js"></script>
<style>
body{ background-color: ivory; padding:15px; }
canvas{border:1px solid red;}
#wrapper{ position:relative; width:400px; height:400px; }
#Tshirt,#container_canvas{ position:absolute; top:0; left:0; }
</style>
<script>
$(function(){
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('.image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
image.setSize(width, height);
}
imgX=image.getAbsolutePosition().x;
imgY=image.getAbsolutePosition().y;
imgWidth=image.getWidth();
imgHeight=image.getHeight();
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container_canvas',
width: 578,
height: 400
});
var darthVaderGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var layer = new Kinetic.Layer();
layer.add(darthVaderGroup);
stage.add(layer);
var darthVaderImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.darthVader,
width: 200,
height: 138,
name: 'image'
});
darthVaderGroup.add(darthVaderImg);
addAnchor(darthVaderGroup, 0, 0, 'topLeft');
addAnchor(darthVaderGroup, 200, 0, 'topRight');
addAnchor(darthVaderGroup, 200, 138, 'bottomRight');
addAnchor(darthVaderGroup, 0, 138, 'bottomLeft');
darthVaderGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
darthVaderGroup.on("dragend",function(){$("#info").text(getImageInfo());});
function getImageInfo(){
var image=darthVaderImg;
return(
" X/Y:"+
image.getAbsolutePosition().x+"/"+
image.getAbsolutePosition().y+" -- Width/Height:"+
image.getWidth()+"/"+
image.getHeight()
);
}
}
function putDesign(designSrc){
designSrc = designSrc.split("images/");
var sources = {
darthVader: 'http://dl.dropbox.com/u/139992952/stackoverflow/love.png'
};
loadImages(sources, initStage);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
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];
}
}
putDesign("yourAssets");
}); // end $(function(){});
</script>
</head>
<body>
<p>Info:<span id="info"></span></p><br/>
<div id="wrapper">
<img id="Tshirt" src="http://dl.dropbox.com/u/139992952/stackoverflow/Tshirt.png" width=167px height=167px>
<div id="container_canvas"></div>
</div><br/>
</body>
</html>

Categories