FabricJs canvas Dragging First object loaded will drag all object - javascript

Hi i have a fabricJs canvas and i load an image . after that i draw rectangle on it (Region of interest)
What i want is , when i drag the image to move on it (after a zoom for exemple) all the rectangle move with it .
That's my actual code .
var canvas = new fabric.Canvas('c');
fabric.Image.fromURL("/images/test.png", (oImg) => {
canvas.add(oImg);
canvas.sendToBack(oImg);
canvas.renderAll();
}, {evented: false, selectable: false, hasBorders: false, hasControls: false, hasRotatingPoint: false});
var text = new fabric.Textbox('1. Text inside canvas', {
left: 100,
top: 50,
width:300,
fill: 'white'
});
canvas.add(text);
$("#zoomIn").click(function(){
zoomIn();
});
$("#zoomOut").click(function(){
zoomOut();
});
$("#btnResetZoom").click(function(){
resetZoom();
});
function zoomIn() {
canvas.setZoom(canvas.getZoom() *1.1);
canvas.renderAll();
}
function zoomOut() {
canvas.setZoom(canvas.getZoom() * 0.9);
canvas.renderAll();
}
function resetZoom() {
canvas.setZoom(1);
canvas.renderAll();
}
var DrawingRectangle;
var rectangle, isDown, origX, origY;
$("#select").click(function(){
canvas.isDrawingMode = false;
canvas.forEachObject(function(object){
object.selectable = true;
object.evented =true;
})
});
$("#draw").click(function(){
DrawingRectangle = true;
canvas.forEachObject(function(object){
object.selectable = false;
object.evented =false;
})
draw();
});
$("#delete").click(function(){
canvas.isDrawingMode = false;
});
function draw(){
canvas.on('mouse:down', function(o){
var pointer = canvas.getPointer(o.e);
isDown = true;
origX = pointer.x;
origY = pointer.y;
rectangle = new fabric.Rect({
left: origX,
top: origY,
fill: 'transparent',
stroke: 'red',
strokeWidth: 3,
selectable: true,
});
rectangle.hasRotatingPoint=true;
canvas.add(rectangle);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if(origX>pointer.x){
rectangle.set({ left: Math.abs(pointer.x) });
}
if(origY>pointer.y){
rectangle.set({ top: Math.abs(pointer.y) });
}
rectangle.set({ width: Math.abs(origX - pointer.x) });
rectangle.set({ height: Math.abs(origY - pointer.y) });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
canvas.off('mouse:down');
canvas.off('mouse:move');
canvas.off('mouse:up');
});
}
What i do actually is when i click on the "Draw" button all my object become unselectable so i can draw over the image.
Then when i click on the "select" button , all my object become selectable (that only work for my image but not for the rectangles that i draw)
and once i move my image , the image come in foreground and my rectangle diseappear in the background.
1) Why my rectangle can't be selectable
2) How can i move all object when the image object (i guess with ID 0 because it's the first loaded object) is moved .
EDIT : Solved No1 . still have issue with No 2 .
i Tried to fire event with my image object but doesn't work . like this :
oImg.on('mouse:down', function(o){ it says it's undefined

var canvas = new fabric.Canvas('paper',{preserveObjectStacking:true});
canvas.backgroundColor = 'grey';
var isDown = false;
fabric.Image.fromURL("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.svg?v=6e4af45f4d66", function (oImg) {
canvas.add(oImg);
canvas.sendToBack(oImg);
oImg.on('mousedown', function() {
oImg.centerPt = this.getCenterPoint();
canvas.forEachObject(function(obj) {
obj.origPose = new fabric.Point(obj.left, obj.top);
})
})
oImg.on('mouseup', function() {
delete this.centerPt;
canvas.forEachObject(function(obj) {
delete obj.origPose;
})
})
oImg.on('moving', function(evt) {
var self = this;
var diff = this.getCenterPoint().subtract(self.centerPt);
canvas.forEachObject(function(obj) {
if (obj == self) return;
obj.set({
left: obj.origPose.x + diff.x,
top: obj.origPose.y + diff.y
})
obj.setCoords();
})
})
canvas.renderAll();
}, {
selectable: false,
});
var text = new fabric.Textbox('1. Text inside canvas', {
left: 100,
top: 50,
width: 300,
fill: 'white',
selectable: false
});
canvas.add(text);
$("#zoomIn").click(function() {
zoomIn();
});
$("#zoomOut").click(function() {
zoomOut();
});
$("#btnResetZoom").click(function() {
resetZoom();
});
function zoomIn() {
canvas.setZoom(canvas.getZoom() * 1.1);
canvas.renderAll();
}
function zoomOut() {
canvas.setZoom(canvas.getZoom() * 0.9);
canvas.renderAll();
}
function resetZoom() {
canvas.setZoom(1);
canvas.renderAll();
}
$("#select").click(function() {
DrawingRectangle = false;
canvas.selection = true;
canvas.off('mouse:down');
canvas.off('mouse:move');
canvas.off('mouse:up');
changeSelectableStatus(true);
});
$("#draw").click(function() {
canvas.selection = false;
draw();
changeSelectableStatus(false);
});
function changeSelectableStatus(val) {
canvas.forEachObject(function(obj) {
obj.selectable = val;
})
canvas.renderAll();
}
function draw() {
canvas.on('mouse:down', onMouseDown);
canvas.on('mouse:move', onMouseMove);
canvas.on('mouse:up', onMouseUp);
}
function onMouseDown(o) {
var pointer = canvas.getPointer(o.e);
isDown = true;
origX = pointer.x;
origY = pointer.y;
rectangle = new fabric.Rect({
left: origX,
top: origY,
fill: 'transparent',
stroke: 'red',
strokeWidth: 3,
selectable: false
});
canvas.add(rectangle);
}
function onMouseMove(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
rectangle.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
rectangle.set({
top: Math.abs(pointer.y)
});
}
rectangle.set({
width: Math.abs(origX - pointer.x)
});
rectangle.set({
height: Math.abs(origY - pointer.y)
});
canvas.renderAll();
};
function onMouseUp(o) {
rectangle.setCoords();
isDown = false;
DrawingRectangle = false;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script>
<canvas id="paper" width="800" height="300" style="border:1px solid #ccc;"></canvas>
<button id="draw">Draw ROI</button>
<button id="select">Select ROI(s)</button>
<button id="zoomIn">Zoom In</button>
<button id="zoomOut">Zoom Out</button>
<button id="btnResetZoom">Reset Zoom</button>
1) Draw ROI button> draw rectangle, where you draw rectangles.
2) Select ROI button > select objects(move,rotate).
3) zoom in/out button.
4) and in canvas one image there, if you drag that image what ever objects there they will drag with that much distance with which image covered.
use preserveObjectStacking:true then objects wont come on top while dragging.

Related

Basic Fabric.js Image Selection with Mask

I have a unique (but hopefully simple) issue to fix with Fabric.js to fix.
I have this very simple example below:
I have
2 Images
Both have an absolutePositioned mask via clipPath property on the fabric.Image instance
My issue is:
I want the image to only be selectable (and hoverable) whenever the selection happens within the bounds of the mask, not anywhere on image (even outside of the bounds of its mask).
This image shows the mouse hovering over the red door picture (even though the mouse is outside of the mask bounds, but not outside the image bounds:
Here's a code snippet of the door image snippet:
fabric.Image.fromURL(url1, function(img){
canvas.add(img.set({
left: 0,
top: 0,
clipPath: rect1,
hasControls: false,
}));
img.on('mouseover', () => {
const filter = new fabric.Image.filters.BlendColor({
color: 'white',
alpha: 0.7,
mode: 'tint'
})
img.filters.push(filter)
img.applyFilters()
canvas.renderAll()
})
img.on('mouseout', () => {
img.filters.pop()
img.applyFilters()
canvas.renderAll()
})
}, {crossOrigin: "Anonymous"});
JS Fiddle Example showing the current behavior that I'm trying to change.
A possible solution is to listen to the mouse event in the canvas and toggle the activeObject based on the mouse position:
canvas.observe('mouse:move', function(options) {
const pos = canvas.getPointer(options.e);
if (!imageRight || !imageLeft) return
if (pos.x > 200) {
activeImage = imageRight
} else {
activeImage = imageLeft
}
const activeObj = canvas.getActiveObject();
if (activeImage !== activeObj) {
canvas.setActiveObject(activeImage);
canvas.renderAll()
}
});
This is a very simplified way to detect if the mouse is over the image. It checks if the x > 200 since that is where the line between both images is positioned. This could be improved to be more accurate, but it works just to illustrate the idea.
var canvas = window._canvas = new fabric.Canvas('c');
const url1 = 'https://picsum.photos/300/200'
const url2 = 'https://picsum.photos/320'
let imageRight
let imageLeft
let activeImage
canvas.observe('mouse:move', function(options) {
const pos = canvas.getPointer(options.e);
if (!imageRight || !imageLeft) return
if (pos.x > 200) {
activeImage = imageRight
} else {
activeImage = imageLeft
}
const activeObj = canvas.getActiveObject();
if (activeImage !== activeObj) {
canvas.setActiveObject(activeImage);
canvas.renderAll()
}
});
const baseProps = {
width: 200,
height: 200,
top: 0,
fill: '#000',
absolutePositioned: true,
hasControls: false,
evented: false,
selectable: false
}
const rect1 = new fabric.Rect({
...baseProps,
left: 0,
})
const rect2 = new fabric.Rect({
...baseProps,
left: 200,
})
canvas.add(rect1)
canvas.add(rect2)
fabric.Image.fromURL(url2, function(img) {
imageRight = img
canvas.add(img.set({
left: 200,
top: 0,
clipPath: rect2,
hasControls: false
}))
}, {
crossOrigin: "Anonymouse"
})
fabric.Image.fromURL(url1, function(img) {
imageLeft = img
canvas.add(img.set({
left: 0,
top: 0,
clipPath: rect1,
hasControls: false,
}));
}, {
crossOrigin: "Anonymous"
});
canvas {
border: 2px red solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.6.0/fabric.min.js"></script>
<canvas id="c" width="420" height="220"></canvas>

Cropping tool not working in Fabric 1.7+

I'm quite new to Fabric.js and I found some fiddle that is working correctly to 1.6.7 version including. So the tool allowed me to cut the selected area of ​the photo. However, since 1.7 this function draws a path in a different location than I select on the screen. Could I ask for a clue where the cause may lie?
http://jsfiddle.net/czechue/kNEaX/852/
var canvas = new fabric.Canvas('c1', {
isDrawingMode: true
});
var src = "http://fabricjs.com/lib/pug.jpg";
canvas.backgroundColor = "#333";
canvas.freeDrawingBrush.color = "purple"
canvas.freeDrawingBrush.width = 4
var el = new fabric.Rect({
fill: 'transparent',
originX: 'left',
originY: 'top',
stroke: '#ccc',
strokeDashArray: [2, 2],
opacity: 1,
width: 1,
height: 1
});
el.visible = false;
canvas.add(el);
var object;
fabric.util.loadImage(src, function (img) {
object = new fabric.Image(img);
object.set({
selectable: false
});
object.hasRotatingPoint = true;
canvas.add(object);
canvas.renderAll();
});
canvas.on('path:created', function(options) {
var path = options.path;
canvas.isDrawingMode = false;
object.clipTo = function(ctx) {
path.set({ objectCaching: false})
path.render(ctx);
};
object.selectable = true;
disabled = true;
el.visible = false;
canvas.renderAll();
});
So i suggest since the big differences between 1.6.7 and 1.7.x, to jump directly on 2.0, but apart this i think what you need to do is to use the object as dirty after you apply a clipPath.
canvas.on('path:created', function(options) {
var path = options.path;
canvas.isDrawingMode = false;
object.clipTo = function(ctx) {
path.set({ objectCaching: false })
path.render(ctx);
};
object.selectable = true;
object.dirty = true;
disabled = true;
el.visible = false;
canvas.renderAll();
});

Why does polygon gets misplaced when i pass transformed points?

Below is my code , when I modify the object I get transformed points so when I pass those transformed points, it places the object at slightly different position. I want have the modified shapes point's coordinates for which i multiplied each point with transform matrix and got new points, but when i pass those points to draw the same polygon, it places slightly at different position. So do i have to do any configuration?, My jsfiddle is https://jsfiddle.net/sL2np4wj/7/
<!-- fabric js code -->
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Fabric</title>
<script src="fabric.js\dist\fabric.min.js"></script>
<script src="js/fabric.canvasex"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
<style>
#canvas-container {
position: relative;
width: 640px;
height: 480px;
box-shadow: 0 0 5px 1px black;
margin: 10px auto;
border: 5px solid transparent;
}
#canvas-container.over {
border: 5px;
}
#images img.img_dragging {
opacity: 0.4;
}
</style>
</head>
<body>
<div id="images">
<img draggable="true" id="triangle" src="Images\triangle.png" width="50" height="50"></img><br/>
<img draggable="true" id="pentagon" src="Images\polygon.png" width="50" height="50"></img><br/>
<img draggable="true" id="rectangle" src="Images\square.png" width="50" height="50"></img><br/>
<img draggable="true" id="hexagon" src="Images\hexagon.png" width="50" height="50"></img><br/>
</div>
<div id="canvas-container">
<canvas id="canvas" width="640" height="480"></canvas>
</div>
<script>
$(document).ready(function() {
var canvas = new fabric.Canvas('canvas');
canvas.setBackgroundImage('file:///D:/New folder/Images/roi_image.png', canvas.renderAll.bind(canvas), {
width: canvas.width,
height: canvas.height,
backgroundColor:'white',
originX: 'left',
originY: 'top'
});
function handleDragStart(e) {
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
this.classList.add('img_dragging');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'copy';
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
var img = document.querySelector('#images img.img_dragging');
console.log('event: ', e);
console.log('image: ', img.id);
if(img.id === 'triangle') {
console.log('image: hereTriangle');
var id="shape"+0;
var points=[{"x":431.46311475409834,"y":182.35576211353316},{"x":366.0532786885246,"y":208.33652422706632},{"x":366.0532786885246,"y":156.375}];
var triangle = new fabric.Polygon(points,{
id:id,
fill: "transparent",
strokeWidth:0.75,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false
});
canvas.add(triangle);
//triangle.transformMatrix = [ 1, 0, 0, 1, 0, 0 ];
}else if(img.id === 'rectangle'){
var points1=regularPolygonPoints(4,30);
var rect = new fabric.Polygon(points1,{
fill: "transparent",
strokeWidth:0.75,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
top:e.layerY,
left:e.layerX,
transparentCorners: false
});
canvas.add(rect);
}else if(img.id === 'pentagon'){
var points=regularPolygonPoints(5,30);
var pentagon = new fabric.Polygon(points,{
width: 50,
height: 50,
fill: "transparent",
strokeWidth:0.25,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
top:e.layerY,
left:e.layerX,
transparentCorners: false
});
canvas.add(pentagon);
}else if(img.id === 'hexagon'){
var points=regularPolygonPoints(6,30);
var pentagon = new fabric.Polygon(points,{
fill: "transparent",
strokeWidth:0.25,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false,
left: e.layerX,
top: e.layerY
});
canvas.add(pentagon);
}else{
console.log('image: here');
var newImage = new fabric.Image(img, {
width: img.width,
height: img.height,
fill:"rgb(0,0,255)",
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false,
// Set the center of the new object based on the event coordinates relative
// to the canvas container.
left: e.layerX,
top: e.layerY
});
canvas.add(newImage);
}
return false;
}
function regularPolygonPoints(sideCount,radius){
var sweep=Math.PI*2/sideCount;
var cx=radius;
var cy=radius;
var points=[];
for(var i=0;i<sideCount;i++){
var x=cx+radius*Math.cos(i*sweep);
var y=cy+radius*Math.sin(i*sweep);
console.log("VALUE OF X :"+x);
points.push({x:x,y:y});
}
console.log("points "+JSON.stringify(points));
return(points);
}
function handleDragEnd(e) {
// this/e.target is the source node.
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
}
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img) {
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
});
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
canvas.on('object:modified',function(e){
addDeleteBtn(e.target.oCoords.mt.x, e.target.oCoords.mt.y, e.target.width);
var obj=e.target;
var polygon = e.target;
var matrix=[];
matrix=polygon.calcTransformMatrix();
console.log("Matrix : "+JSON.stringify(matrix));
var translatedPoints = polygon.get('points').map(function(p) {
return {
x: matrix[0] * p.x + matrix[2] * p.y + matrix[4],
y: matrix[1] * p.x + matrix[3] * p.y + matrix[5]
};
});
<!-- transformed points -->
console.log("Modified points :"+JSON.stringify(translatedPoints));
});
});

How to free draw circle using Fabric.js?

I am using FabricJS to draw circle in canvas:
var circle = new fabric.Circle({radius: 100,
fill: '',
stroke: 'red',
strokeWidth: 3,
originX: 'center',
originY: 'center'
});
var text = new fabric.Text('HELLO WORLD.',
{ fontSize: 30,
originX: 'center',
originY: 'center',
fill : 'red'
});
var group = new fabric.Group([ circle, text ], {
left: 150, top: 100
});
canvas.add(group);
This code draws a normal circle but I need to freely draw circle with mouse.
Any code help will be appreciated.
According to your previous code for drawing rectangle http://jsfiddle.net/Subhasish2015/8u1cqasa/2/ Here is the code for drawing circle:
$(document).ready(function(){
//Getting the canvas
var canvas1 = new fabric.Canvas("canvas2");
var freeDrawing = true;
var divPos = {};
var offset = $("#canvas2").offset();
$(document).mousemove(function(e){
divPos = {
left: e.pageX - offset.left,
top: e.pageY - offset.top
};
});
$('#2').click(function(){
//Declaring the variables
var isMouseDown=false;
var refCircle;
//Setting the mouse events
canvas1.on('mouse:down',function(event){
isMouseDown=true;
if(freeDrawing) {
var circle=new fabric.Circle({
left:divPos.left,
top:divPos.top,
radius:0,
stroke:'red',
strokeWidth:3,
fill:''
});
canvas1.add(circle);
refCircle=circle; //**Reference of rectangle object
}
});
canvas1.on('mouse:move', function(event){
if(!isMouseDown)
{
return;
}
//Getting yhe mouse Co-ordinates
if(freeDrawing) {
var posX=divPos.left;
var posY=divPos.top;
refCircle.set('radius',Math.abs((posX-refCircle.get('left'))));
canvas1.renderAll();
}
});
canvas1.on('mouse:up',function(){
canvas1.add(refCircle);
//alert("mouse up!");
isMouseDown=false;
//freeDrawing=false; // **Disables line drawing
});
});
});
var Circle = (function() {
function Circle(canvas) {
this.canvas = canvas;
this.className = 'Circle';
this.isDrawing = false;
this.bindEvents();
}
Circle.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();
})
}
Circle.prototype.onMouseUp = function(o) {
var inst = this;
inst.disable();
};
Circle.prototype.onMouseMove = function(o) {
var inst = this;
if (!inst.isEnable()) {
return;
}
var pointer = inst.canvas.getPointer(o.e);
var activeObj = inst.canvas.getActiveObject();
activeObj.stroke = 'red',
activeObj.strokeWidth = 5;
activeObj.fill = 'red';
if (origX > pointer.x) {
activeObj.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
activeObj.set({
top: Math.abs(pointer.y)
});
}
activeObj.set({
rx: Math.abs(origX - pointer.x) / 2
});
activeObj.set({
ry: Math.abs(origY - pointer.y) / 2
});
activeObj.setCoords();
inst.canvas.renderAll();
};
Circle.prototype.onMouseDown = function(o) {
var inst = this;
inst.enable();
var pointer = inst.canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var ellipse = new fabric.Ellipse({
top: origY,
left: origX,
rx: 0,
ry: 0,
transparentCorners: false,
hasBorders: false,
hasControls: false
});
inst.canvas.add(ellipse).setActiveObject(ellipse);
};
Circle.prototype.isEnable = function() {
return this.isDrawing;
}
Circle.prototype.enable = function() {
this.isDrawing = true;
}
Circle.prototype.disable = function() {
this.isDrawing = false;
}
return Circle;
}());
var canvas = new fabric.Canvas('canvas');
var circle = new Circle(canvas);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.17/fabric.min.js"></script>
Please draw circle here
<div id="canvasContainer">
<canvas id="canvas" width="400" height="400" style="border: solid 1px"></canvas>
</div>
Here is the detail blog with jsfiddle - https://blog.thirdrocktechkno.com/sketching-circle-of-a-html5-canvas-using-the-fabricjs-f7dbfa20cf2d
Here is an example of drawing a rectangle which I carefully made and works for latest versions. Krunan example seems to work OK- just in case this is a rectangle free drawing implementation that doesn't use DOM apis like e.clientX, offsetLeft, etc to track the coords, but fabric.js APIs only which I think is safer. Also unregister event listeners - I'm still trying to refine it since I need free drawing support for my project - Since there is no official support for this I wanted to reference the example here for others.
https://cancerberosgx.github.io/demos/misc/fabricRectangleFreeDrawing.html
An easy way to add a Circle to a canvas:
canvas.add(new fabric.Circle({ radius: 30, fill: "green", top: 100, left: 100 }));

KineticJs - When dynamically creating rect, the rect behind it drags by itself

In kineticjs I am creating dynamic rectangles that are draggable. However when I create a new rectangle, the rectangle behind it automatically drags. I dont want this to happen.
You can see the behaviour in demo at http://jsfiddle.net/sandeepy02/8kGVD/12/
Step 1: Choose "create rectangle" and create rectangles.
Step 2: Choose "Move rectangle" and move the rectangles.
Step 3: Choose "create rectangle" and create rectangles. This causes the rectangles previously created to also move. This is unwanted.
<html>
<head>
<script>
function valButton(radios) {
var btn = document.getElementsByName(radios);
var cnt = -1;
for (var i = btn.length - 1; i > -1; i--) {
if (btn[i].checked) {
cnt = i;
i = -1;
}
}
if (cnt > -1) return btn[cnt].value;
else return null;
}
window.onload = function() {
layer = new Kinetic.Layer();
stage = new Kinetic.Stage({
container: "container",
width: 320,
height: 320
});
background = new Kinetic.Rect({
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
fill: "white"
});
layer.add(background);
stage.add(layer);
moving = false;
stage.on("mousedown touchstart", function() {
var btnName = valButton("group2");
if (btnName == "1") {
if (moving) {
moving = false;
layer.draw();
} else {
var mousePos = stage.getMousePosition();
rect = new Kinetic.Rect({
x: 22,
y: 7,
width: 0,
height: 0,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(rect);
//start point and end point are the same
rect.setX(mousePos.x);
rect.setY(mousePos.y);
rect.setWidth(0);
rect.setHeight(0);
moving = true;
layer.drawScene();
}
}
document.all.text.innerText = btnName +" "+moving;
}); //end of mousedown
stage.on("mousemove touchmove", function() {
var btnName = valButton("group2");
if (btnName == "1") {
if (moving) {
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
rect.setWidth(mousePos.x - rect.getX());
rect.setHeight(mousePos.y - rect.getY());
moving = true;
layer.drawScene();
}
}
else if (btnName == "3") {
layer.draw();
}
document.all.text.innerText = btnName +" "+moving;
}); //end of mousemove
stage.on("mouseup touchend", function() {
var btnName = valButton("group2");
if (btnName == "1") {
moving = false;
}
document.all.text.innerText = btnName +" "+moving;
}); //end of mouseup
};
</script>
</head>
<body>
<h2>Toggle buttons</h2>
<div class="toggle-btn-grp">
<label onclick="" class="toggle-btn"><input type="radio" value="1" name="group2"/> Create Rectangle</label>
<label onclick="" class="toggle-btn"><input type="radio" value="3" name="group2"/>Move Rectangle</label>
</div>
<div id="container" ></div>
<div id="text" >abc</div>
</body>
</html>​
Here is your updated function to fix the problem -
stage.on("mousedown touchstart", function() {
var btnName = valButton("group2");
if (btnName == "Create") {
if (moving) {
moving = false;
layer.draw();
} else {
var mousePos = stage.getMousePosition();
rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 0,
height: 0,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(rect);
//start point and end point are the same
rect.setX(mousePos.x);
rect.setY(mousePos.y);
rect.setWidth(0);
rect.setHeight(0);
moving = true;
rect.on("mousemove touchmove", function() {
var btnName = valButton("group2");
if (btnName == "Create") {
this.setDraggable(false);
}
else if (btnName == "Move") {
this.setDraggable(true);
}
document.all.text.innerText = btnName +" rect move MovingFlag: "+moving;
}); //end of rect mousemove
layer.drawScene();
}
}
document.all.text.innerText = btnName +" MovingFlag: "+moving;
}); //end of mousedown

Categories