Ivan Golubar
asked on
Using clicking on canvas to get coordinates to draw lines and anchor circles
Code below is from http://fabricjs.com/stickman and it is using fabrics.js library. (try to drag circle by pressing on mouse and moving)
Now coordinates for lines and circles are set by code. My goal is to set coordinates by clicking on canvas.
First click will be start and to determinate the end of polyline I need to use double click. I did try some options until now but i hope this one will be okay, as it has option to move lines by anchor circle. once the polyline has already been created for editing purposes.
Am sure i will have to use on click event and on double click event. So when i will click on fist point i will get circle. Next click will give me the second circle and the line between them and so on until double click. For now i have only one restriction and that is not to generate another circle, if i am clicking on existing circle.
What would be the logic to get coordinates by clicking on canvas and to draw while clicking ?
Now coordinates for lines and circles are set by code. My goal is to set coordinates by clicking on canvas.
First click will be start and to determinate the end of polyline I need to use double click. I did try some options until now but i hope this one will be okay, as it has option to move lines by anchor circle. once the polyline has already been created for editing purposes.
Am sure i will have to use on click event and on double click event. So when i will click on fist point i will get circle. Next click will give me the second circle and the line between them and so on until double click. For now i have only one restriction and that is not to generate another circle, if i am clicking on existing circle.
What would be the logic to get coordinates by clicking on canvas and to draw while clicking ?
var line1,line2,line3,line4 ;
function createObject(){
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
function makeCircle(left, top, line1, line2, line3, line4) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
c.line4 = line4;
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false
});
}
var line1 = makeLine([ 250, 125, 300, 175 ]),
line2 = makeLine([ 300, 175, 350, 225 ]),
line3 = makeLine([ 350, 225, 400, 275]),
line4 = makeLine([ 400, 275, 450, 325]);
canvas.add(line1, line2, line3, line4);
canvas.add(
makeCircle(line1.get('x1'), line1.get('y1'), null,line1),
makeCircle(line1.get('x2'), line1.get('y2'), line1,line2),
makeCircle(line2.get('x2'), line2.get('y2'), line2,line3),
makeCircle(line3.get('x2'), line3.get('y2'), line3,line4),
makeCircle(line4.get('x2'), line4.get('y2'), line4)
);
}
document.getElementById("clickMe").onclick = createObject;
var moveHandler = function (evt) {
var obj = evt.target;
obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
obj.line3 && obj.line3.set({ 'x1': obj.left, 'y1': obj.top });
obj.line4 && obj.line4.set({ 'x1': obj.left, 'y1': obj.top });
canvas.renderAll();
/}
canvas.on('object:moving', moveHandler);
Could you post all the code (html+js) in a attached file?
ASKER
I can't find link to online fabric library.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://can't find /fabric.min.js" ></script
<style>
</style>
<script>
var canvas = new fabric.Canvas('c');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var line1=[ ];
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
//selectable: false
});
}
var lineCount=0;
var posX1=0;
var posY1=0;
var posX2=0;
var posY2=0;
canvas.on('mouse:down', function(e) {
posX1 = posX2;
posY1 = posY2;
var pointer = canvas.getPointer(e.e);
var posX2 = pointer.x;
var posY2 = pointer.y;
if (lineCount!=0){
line1[lineCount] = makeLine([posX1, posY1, posX2, posY2 ]);
canvas5.add(line1[lineCount]);
}
});
</script>
</head>
<body>
<canvas id="c" width="1060" height="550" >
</div>
</body></html>
Check this script:
<script>
var canvas = new fabric.Canvas('c');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var line1=[ ];
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
//selectable: false
});
}
var lineCount=0;
var posX1=0;
var posY1=0;
var posX2=0;
var posY2=0;
canvas.on('mouse:down', function(e) {
if(lineCount===0){
var pointer = canvas.getPointer(e.e);
posX2 = pointer.x;
posY2 = pointer.y;
lineCount++
return;
}else{
var pointer = canvas.getPointer(e.e);
posX1=pointer.x;
posY1 = pointer.y;
line1 = makeLine([posX1, posY1, posX2, posY2 ]);
canvas.add(line1);
lineCount=0;
}
});
</script>
ASKER
I have got the mistake. Sorry.
var posX2 = pointer.x;
var posY2 = pointer.y;
I get lines now.
var posX2 = pointer.x;
var posY2 = pointer.y;
I get lines now.
Is it works now?
ASKER
Yes. I will now go on with drawing of circles.
ASKER
I had to get back to my previous code, because your code is doing, separate lines, but i need polyline which continues until i make a double click (check the begging of this question). I did add also circles between lines to have the anchor point for move handler.
Check the second attached code. When circles are pressed and moved lines should follow them. Under point 1 is original code from first post of this question. under point 2 is my try, but unsuccessful and under 3 the same as 2. With next error:
Uncaught TypeError: Cannot read property '0' of undefined for line 19 of second code snippet.
To recapitulate:
Now i am missing
1 double click to end the polyline.
2 move handler
3 check the attached picture: I don't want to ses line in circle
Check the second attached code. When circles are pressed and moved lines should follow them. Under point 1 is original code from first post of this question. under point 2 is my try, but unsuccessful and under 3 the same as 2. With next error:
Uncaught TypeError: Cannot read property '0' of undefined for line 19 of second code snippet.
To recapitulate:
Now i am missing
1 double click to end the polyline.
2 move handler
3 check the attached picture: I don't want to ses line in circle
var lineCount=0;
var posX1=0;
var posY1=0;
var posX2=0;
var posY2=0;
canvas.on('mouse:down', function(e) {
posX1 = posX2;
posY1 = posY2;
var pointer = canvas.getPointer(e.e);
posX2 = pointer.x;
posY2 = pointer.y;
var RP = document.getElementById("RadioPol").checked;
if (RP) {
if (lineCount!=0){
line1[lineCount] = makeLine([posX1, posY1, posX2, posY2 ]);
canvas.add(line1[lineCount]);
}
if (lineCount==0){canvas.add(makeCircle( posX2, posY2, null));}
if (lineCount>0){canvas.add( makeCircle(line1[lineCount].get('x2'), line1[lineCount].get('y2'), line1[lineCount-1],line1[lineCount]));}
}
lineCount=lineCount+1;
var leftx2,topy2;
var moveHandler = function (evt) {
var obj = evt.target;
leftx2 = obj.get('left');
topy2 = obj.get('top');
/*
1.
obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
obj.line3 && obj.line3.set({ 'x1': obj.left, 'y1': obj.top });
obj.line4 && obj.line4.set({ 'x1': obj.left, 'y1': obj.top });
canvas.renderAll();
2.
for (var i = 0, len = lineCount; i < len; i++) {
obj.line1[i] && obj.line1[i].set({ 'x2': obj.left, 'y2': obj.top });
}
3. */
obj.line1[0] && obj.line1[0].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[1] && obj.line1[1].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[2] && obj.line1[2].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[3] && obj.line1[4].set({ 'x2': obj.left, 'y2': obj.top });
7.png
Could you post all the code please because they are missing elements like "RadioPol"?
ASKER
Consider point 1 (from my last post) double click to end the polyline done.
No need to use double click. I will just check, if i am clicking on any object to end the polyline.
But i still need help with:
2 move handler
3 check the attached picture(previous post): I don't want to see line in circle.
No need to use double click. I will just check, if i am clicking on any object to end the polyline.
But i still need help with:
2 move handler
3 check the attached picture(previous post): I don't want to see line in circle.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src=".................../fabric.min.js"></script>
<style>
</style>
<script>
var line1=[];
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false
});
}
function makeCircle(left, top, line1, line2) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 2,
radius: 6,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
return c;
}
var clickonobject ;
var objectIndex;
var lineCount=0;
var posX1=0;
var posY1=0;
var posX2=0;
var posY2=0;
function drawPoly(){
var RP = document.getElementById("RadioPol").checked;
if (RP) {
if (lineCount!=0){
line1[lineCount] = makeLine([posX1, posY1, posX2, posY2 ]);
canvas.add(line1[lineCount]);
}
if (lineCount==0){canvas.add(makeCircle( posX2, posY2, null));}
if (lineCount>0){canvas.add( makeCircle(line1[lineCount].get('x2'), line1[lineCount].get('y2'), line1[lineCount-1],line1[lineCount]));}
}
lineCount=lineCount+1;
}
canvas.on('mouse:down', function(e) {
var obj2 = e.target;
if (obj2!= null){console.log(obj2.type);}
if (obj2==null){
//if (obj2.type== Circle){lineCount=0;}
// else{
posX1 = posX2;
posY1 = posY2;
var pointer = canvas.getPointer(e.e);
posX2 = pointer.x;
posY2 = pointer.y;
drawPoly();//}
}else{lineCount=0;}
});
var leftx2,topy2;
var moveHandler = function (evt) {
var obj = evt.target;
leftx2 = obj.get('left');
topy2 = obj.get('top');
//console.log(leftx2);
//console.log(topy2);
/*
obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
obj.line3 && obj.line3.set({ 'x1': obj.left, 'y1': obj.top });
obj.line4 && obj.line4.set({ 'x1': obj.left, 'y1': obj.top });
canvas.renderAll();
for (var i = 0, len = lineCount; i < len; i++) {
obj.line1[i] && obj.line1[i].set({ 'x2': obj.left, 'y2': obj.top });
}
obj.line1[0] && obj.line1[0].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[1] && obj.line1[1].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[2] && obj.line1[2].set({ 'x2': obj.left, 'y2': obj.top });
obj.line1[3] && obj.line1[4].set({ 'x2': obj.left, 'y2': obj.top });
*/
</script>
</head>
<body>
<canvas id="c" width="1060" height="550" >
</div>
</body></html>
ASKER
Next code is moving only line before the circle and not the other one.
The problem is in next line:
if (lineCount>0){canvas.add( makeCircle(line1[lineCount ].get('x2' ), line1[lineCount].get('y2') , line1[lineCount],line1[lineCount+1]));}
When i am making circles as anchor point i don't have yet the next line (i have the line before circle and not yet the line after circle)
So i must each time i make new line find the previouse circle and add to him line which was just been made. How to do that?
var leftx2,topy2;
var moveHandler = function (evt) {
var obj = evt.target;
leftx2 = obj.get('left');
topy2 = obj.get('top');
obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
}
The problem is in next line:
if (lineCount>0){canvas.add( makeCircle(line1[lineCount
When i am making circles as anchor point i don't have yet the next line (i have the line before circle and not yet the line after circle)
So i must each time i make new line find the previouse circle and add to him line which was just been made. How to do that?
ASKER
With next code also the problem number 2 is resolved.
Now when I press on circle i may drag both lines which are attached to specific circle as circle is moving.
Now about problem from point 3. ( small part of line is in the circle ( Check attached picture))
I am not sure if i could leave it as it is, as it gives me the direction of line creation. So consider this question closed.
How to assign points?
Untitled8.png
Now when I press on circle i may drag both lines which are attached to specific circle as circle is moving.
if (lineCount==0){
circle1[lineCount]=makeCircle( posX2, posY2, null,null);
canvas.add(circle1[lineCount]);
}
if (lineCount>0){
circle1[lineCount]= makeCircle(line1[lineCount].get('x2'), line1[lineCount].get('y2'), line1[lineCount],null);
canvas.add(circle1[lineCount]);
circle1[lineCount-1].line2 =line1[lineCount];
}
Now about problem from point 3. ( small part of line is in the circle ( Check attached picture))
I am not sure if i could leave it as it is, as it gives me the direction of line creation. So consider this question closed.
How to assign points?
Untitled8.png
Ivan I used your previous code ID 42519818 but unfortunately I haven't any output in my browser.Could you check again and repost your code?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
In the last post is my complete working code.
ASKER
So, next code should not do anything at first click and then on second click draw line from first click point to second one.
To get there I have as first resolve next:
why var posX1=0;
is then undefined inside canvas on mouse down function?
(pleas check attached picture)
Open in new window
linecor.png