SVG.js line marker-mid - javascript

im trying to put the marker-mid on the line element, im using SVG.js. For example im using this code:
var draw = SVG('yourdivid');
var line = draw.line( 100, 100, 0, 0).move(20, 20);
line.stroke({ color: '#000', width: 2};
now how can i put the marker at the mid of this line using the marker-mid?
i read the doc of svg.js and also this" https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/marker-mid#Examples"
they say that you can use the marker-mid element also with the line, i know that this marker works with the path element, but i need to use it with a line, can you help me please?
thank you for your help

You could just work out the mid point of the line yourself and draw a circle at that point.
var start = [100, 100];
var end = [0, 0];
function midPoint(start, end) {
return [
(start[0] + end[0]) / 2,
(start[1] + end[1]) / 2
];
}
var lineGroup = svg.group();
lineGroup.line(start[0][0], start[0][1], end[0][0], end[0][1]);
var dot = lineGroup.circle(3);
var mid = midPoint(start, end);
dot.cx(mid[0]);
dot.cy(mid[1]);

marker-mid does not work on lines. To have start and end markers, this code would do it:
var draw = SVG('yourdivid');
draw.line( 100, 100, 0, 0)
.move(20, 20)
.stroke({ color: '#000', width: 2})
.marker('start', 10, 10, function(add){
add.circle(10).center(5,5)
})
However, to have markers at the mid of a line see p0wdr.com's answer

Related

Calculating line coordinates in Fabric.js

I am developing a self graphing program which draws a binary tree using Fabric.js. So far I have added draw node functions and now I am working on drawing links between the nodes, however the coordinates isn't getting calculated properly. Can anybody help me to point out what the error is? The function(node1,node2,angle) draws a node2 at 200pixels away from node1 at angle passed. I found the start points of line by following the same method I founded Circle center but just by adding circle's radius which is 20 in my case instead of 200 pixels. The end points were calculated by subtracting 20 from 200 and Hence using value 180.
This is the code that I wrote:
Code:
function addNode(node1,node2,angle)
{
var intialx=parseInt(node1.get('left'));
var initialy=parseInt(node1.get('top'));
if(angle<180)
{
var pointx =Math.abs(Math.cos(angle*Math.PI/180)*200+intialx);
var pointy=Math.abs(Math.sin(angle*Math.PI/180)*200-initialy);
var initiallinex=Math.abs(Math.cos(angle*Math.PI/180)*20+intialx);
var initialliney=Math.abs(Math.sin(angle*Math.PI/180)*20-initialy);
var finallinex=Math.abs(Math.cos(angle*Math.PI/180)*180+intialx);
var finalliney=Math.abs(Math.sin(angle*Math.PI/180)*180-initialy);
}
else
{
var pointx =Math.abs(Math.cos(angle*Math.PI/180)*200+intialx);
var pointy=Math.abs(Math.sin(angle*Math.PI/180)*200+initialy);
var initiallinex=Math.abs(Math.cos(angle*Math.PI/180)*20+intialx);
var initialliney=Math.abs(Math.sin(angle*Math.PI/180)*20+initialy);
var finallinex=Math.abs(Math.cos(angle*Math.PI/180)*180+intialx);
var finalliney=Math.abs(Math.sin(angle*Math.PI/180)*180+initialy);
}
var x=new fabric.Circle({ radius:20,originX: 'center', originY: 'center',fill:'red'});
var value1=String(node2);
var text= new fabric.Text(value1, {fontSize: 10, originX: 'center', originY: 'center'});
var group = new fabric.Group([ x, text ], {left:pointx, top: pointy, angle:0});
canvas.add(group);
canvas.add(new fabric.Line([initiallinex, initialliney, finallinex, finalliney], {
stroke: 'red'
}));
return group;
}
Output:
enter image description here

Paper.js - Clipping opacity for paths outside of area

I have a simple rectangle that forms the clipping area for all shapes added to the canvas, which is working great:
var area = new paper.Rectangle(
100, 100, 300, 120
);
var path = new paper.Path.Rectangle(area);
group.addChild(path);
group.clipped = true;
What I'm trying to achieve is instead of hiding the paths that fall outside of this area, they are shown with a slight opacity, something like:
Thanks in advance for any help and suggestions.
This is not a simple way as clipped, you might do it by using method intersect.
Please try this code.
// SET INITIAL
var area = new paper.Path.Rectangle(100, 100, 300, 220);
area.fillColor = 'yellow'
area.opacity = 0.2
var circle1 = new paper.Path.Circle({
center:[150, 150],
radius: 100,
fillColor: 'red'
})
// OPACITY CLIPPING
var circle2 = circle1.intersect(area)
circle1.opacity = 0.2

Animate SVG Line from Left to right Snap.svg

I'm trying to create an animated line as if its being drawn from one point to another. I have managed to get the line drawing on to the page but can't work out how to animate it as if it's being drawn?
https://jsfiddle.net/0sdt33dz/
function svgAnimate (){
var s = Snap('#svg');
var linePath = "M-3,148.6c0,0,43.9,7,49.4-17.2c3.5-15.3-9.4-19.7-17.3-13.8c-6,4.4-10,19,11.3,25.4 c24.9,7.5,70.7-31.2,91-61.8S233-41.5,286.3,29.2c0,0-60.7,35.5-24.9,87.9c36.2,53,83.5,15.6,83.5,15.6s19.3,19.5,68.4,17.1";
var lineLength = Snap.path.getTotalLength(linePath);
var lineDraw = s.path(linePath);
lineDraw.attr({
fill:'none',
stroke:'#009FE3',
'stroke-width' :6,
'stroke-linecap' :'round',
'stroke-linejoin' :'round',
'stroke-miterlimit' :10
});
lineDraw.animate({
stroke : '#fff'
},3000, mina.easein)
console.log(lineLength);
}
svgAnimate();
You're almost there, just missing two things.
First, you need to set the stroke-dasharray to '<length> <length>', this will create a "dashed" line with gaps/fill equal to the length of the entire line
lineDraw.attr({
fill:'none',
stroke:'#009FE3',
'stroke-dasharray': lineLength + ' ' + lineLength,
'stroke-dashoffset': lineLength,
'stroke-width' :6,
...
After this you need to animate the offset of the stroke to 0 using stoke-dashoffset
lineDraw.animate({
strokeDashoffset : 0
},3000, mina.easein)
working fiddle
var s = Snap("#myLine");
//Line parameters (x1, y1, x2, y2)
var line = s.line(30, 45, 30, 45);
line.attr({
stroke: "#000",
strokeWidth: 2
});
//Old x2 values is 30 and now it is increasing to 70 with 1 second duration
line.animate({x2: 70}, 1000);
I hope this answer will help you!

Fabric.js: Find the center of an object (rect) in a group

I need to find the center point of an object that has been placed into a group. Things l have tried:
• getCenterPoint(): returns the center point as if the object were at 0,0.
• Calculating the center point using getTop() and getLeft() of both the group and the object. Unfortunately while the group values work find the object returns negative values.
• Calculated the values using heights/widths of objects. This gets close in the case listed below, but that’s only because of the very specific properties of my example, and would not generalize.
The object below is what I’m currently working with, specifically I’m looking to find the center of rect2:
// create a rectangle object
var rect = new fabric.Rect({
top: 10,
fill: 'white',
stroke: 'black',
width: 20,
height: 20
});
// create a rectangle object
var rect2 = new fabric.Rect({
top: 10,
left: 20,
fill: 'white',
stroke: 'black',
width: 20,
height: 20
});
var line = new fabric.Line([ 20, 20, 40, 20],
{
top: 0,
left: 0,
stroke: 'black'
});
var group = new fabric.Group([ rect, rect2, line ],{
top: 100,
left: 100,
hasRotatingPoint: false
});
You can still use obj.getCenterPoint() on objects that have been added to a group; however, adding an object to a group removes the getCenterPoint method from the original obj reference.
If you reassign the obj references like below, you can then use getCenterPoint on each of them.
var allObjs = group.getObjects(),
rect1 = allObjs[0],
rect2 = allObjs[1],
line = allObjs[2];
return rect2.getCenterPoint();
Here is a working example: https://jsfiddle.net/ns9zLxeu/25/
Use something like
items = group._objects;
Run a loop in items of group, find your object, and get the co-ordinates of object inside a group.
eg : items[i].oCoords.tr.x
the rest is mathematics , mid point of tr.x and br.x = center x
similarly find y.
if you want to find the center to canvas : add group.top, group.left to these values.
Here is the math that I used to get the center of a given Rect
var x1 = e.target.oCoords.oCoords.mt.x;
var y1 = e.target.oCoords.oCoords.mt.y;
var x2 = e.target.oCoords.oCoords.mb.x;
var y2 = e.target.oCoords.oCoords.mb.y;
var centerX = (x1 + x2) / 2;
var centerY = (y1 + y2) / 2;
Then in my case I used the center coor to create a Line using:
var line = makeLine([centerx, centery, 250, 175]);
canvas.add(line);

Javascript Raphael problems with function in loop

Please bear with me, I'm still new to Javascript...
Here are two fiddles. The only difference between them is one has a text object as a title and the other does not; but this difference profoundly affects what happens when I mouseover the circle objects.
What I want is the behavior of the second fiddle, when there is a title like the first fiddle.
I've been trying to figure out how to get my function out of the loop so JSHint stops giving me an error... I have a feeling this behavior is caused by my lack of understanding of closure, binding, etc.
Fiddle 1 with title, mouseover is weird
Fiddle 2 no title, mouseover works
//Code for Fiddle 1: the only difference in Fiddle 2 is the indicated portion is commented out
var rsr = Raphael("holder", '1160', '1400');
// in the next fiddle this will be commented out
rsr.text(220, 50, 'Title').attr({
'font-size': 32,
'text-anchor': 'middle'
});
// end of comment out in Fiddle 2
var cir = []; // an array of circles
var xco = [206, 144.9, 317.4, 317.5]; // x coordinates of circle centers
var yco = [167.7, 231.8, 191.4, 256.8]; // y coordinates of circle centers
var rd = [25.5, 46, 34, 18.5]; // radii of circles
var circcolr = ['#939dac', '#000000', '#ecea5a', '#0da9f2']; // fill colors of circles
for (var i = 0; i < 4; i++) { // loop to draw circles
cir[i] = rsr.circle(xco[i], yco[i], rd[i]);
cir[i].attr({
fill: circcolr[i],
'fill-opacity': 1,
stroke: 'none'
});
}
for (var i in cir) {
(function (st) {
console.log(st.id);
st.node.onmouseover = function () {
st.animate({
r: rd[st.id] * 1.2
}, 200);
};
st.node.onmouseout = function () {
st.animate({
r: rd[st.id]
}, 100);
};
})(cir[i]);
}
The answer is pretty much there in the console logging you're already doing.
In the first case you create 5 objects the title and 4 circles so the title has id = 0 and the circles have id = 1, 2, 3, and 4.
In the second case you're only creating the circles so they have id = 0, 1, 2, 3
When you index into the rd array you're off by one in the title case. Changing the code at the end to this makes it work the same...
for (var i in cir) {
(function (cir, i) {
console.log(cir[i]);
cir[i].node.onmouseover = function () {
cir[i].animate({
r: rd[i] * 1.2
}, 200);
};
cir[i].node.onmouseout = function () {
cir[i].animate({
r: rd[i]
}, 100);
};
})(cir, i);
}

Categories

Resources