svgdotjs / svg.js Goto Github PK
View Code? Open in Web Editor NEWThe lightweight library for manipulating and animating SVG
Home Page: https://svgjs.dev
License: Other
The lightweight library for manipulating and animating SVG
Home Page: https://svgjs.dev
License: Other
There is a copy/paste error in bbox function
/* add the center */
this.cx = this.x + box.width / 2
this.cy = this.x + box.height / 2
I can't seem to find a way to call back to an existing SVG element. For example - I am adding an ID attribute to each element rendered, then trying to refer back to certain elements based on that ID. However that takes me to the raw element, which contains none of the methods or properites that svg.js makes available. How can I refer back to elements in such a way?
Cheers,
Liam Coates
I am not sure if you can do that technically, but I would love to use it. maybe when:
draw_obj.parent
to create a svg js object with the DOM parent of the draw_obj element..
this is symmetric to your interface for iterating over children.
I am attempting to animate the rotation of a polygon with centre points defined.
cx = +joint.attr('cx');
cy = +joint.attr('cy');
poly.animate(2000, '<').rotate(-45, cx, cy);
However I get an error on line 1212
(fx.js line 297
)
match = SVG.regex.unit.exec(o.from.toString())
because o.from is not defined.
I have put a quick fix/hack in on the line before and now the animation works.
if (typeof o.from == 'undefined')
o.from = o.to;
I have no idea if this will break anything as I don't l know your code.
The Jasmine tests pass.
that is deep-copy it
eg gradient.transform ('Matrix', '0 .5261727,0,0,0.7582733, -9.5647863,5.1185895 ') it does not work
Firefox has something against 'getBBox()'
NS_ERROR_FAILURE: Component returned failure code: 0x80004005
(NS_ERROR_FAILURE) [nsIDOMSVGLocatable.getBBox] @ svg.js:374
I'm looking into a workaround as I'm pretty invested in this at the moment. Any advice is more than welcome. I'm thinking the first thing to do is check that the node.method is present, and if not come up with a fallback - possibly something borrowing from jQuery's left/top/width/height methods, unless there are other svg node methods that will get the job done.
Also this might only apply to certain node types. Looking into it...
One should be able to create a rectangle like this:
var rect = draw.rect('50%', '50%') - where the fractions are form the full width and height of the viewport.
or move like this:
rect.center(global.center.x, global.center.y)
also the existence of a global object that holds always the current center coordinates and the bounding box of the viewport. (This should change with any page resize)
One good starting code to implement this:
http://sliced.ro/smp/js/getscreen.js
In SVG.Element.attr function this.lines can be undefined, because in SVG.Text constructor you dont set this.lines = []
/* treat x differently on text elements */
if (a == 'x' && this._isText()) {
for (var i = this.lines.length - 1; i >= 0; i--)
this.lines[i].attr(a, v)
(excuse my bad english)
Maybe it is not the intention of svg.js, however I like the syntax and think that it should not too hard to make this possible. Any thoughts on this?
a group cannot be removed from the SVG document, because SVG.Group inherits from SVG.Container, which overwrite the method remove of SVG.Element.
(excuse my bad english)
Similarily to jQuery and Raphael, this function would allow to bind arbitrary objects to SVG elements. That's super helpful for any datavis applications.
Syntax:
el.data('key', obj); // store data, return element
el.data('key'); // return data
el.data('key', null); // remove data
Currently, element has a clone method which works well although it appears to do something I didn't expect with the offset. The very last line of the clone method has this:
/* apply attributes and translations */
return clone.transform({})
which results in the negative offset being applied. My original element had this
transform="translate(0,0)"
but the clone has
transform="translate(-711.3419799804688,-20.5)"
Is this intended?
Also, could we add a method for cloning an entire group (element and all its children)?
FYI, I'm working on a game that uses an svg map. You can see a test here: http://www.realitymeltdown.com/Svg/test-svgjs.html
Want to back this issue? Place a bounty on it! We accept bounties via Bountysource.
It would be nice if svg.js had the ability to add control a transform through just the matrix. As it is now it works like so:
var containerElement = document.getElementById("viewport");
var svg = new SVG(containerElement);
var circle = svg.circle( 100, 100 );
var matrixString = 'matrix( 1, 0, 0, 1, 1, 1 )';
// DOES NOT WORK
circle.transform( matrixString );
// DOES WORK
circle.attr( transform: matrixString);
The library is very interested and easy to use. I believe this feature would help add the ability for the developer to create custom animations and interactions.
Bests,
@dhaakon
On http://svgjs.com/test/ page, use console and type:
ย var draw = SVG('canvas');
On FF, this error shows up:-
ย TypeError: this.parent is null
ย .call(this, this.parent.nodeName == 'svg' ? this.parent : SVG.create('svg'))
Thanks for the great work you put into svg.js โ itโs quiet handy. I was just wondering if it is possible to set a transform-origin when animating, or scaling, that is. I want it to scale/blow up a hexagon, but using the center as the origin, not the upper left corner? Hereโs a hacked up, quick pen to elaborate a bit: codepen.io/mixn/pen/qbDJp
One thing that's keeping me with Raphael right now is the ability to animate customAttributes, which allows animating around a circular path and pretty much any other path you can think of. Just curious if there is any way to do this in svg.js or if you have plans to implement it. I'm also curious why you arent using requestAnimationFrame for animation? Thanks
var a = SVG(...).size(300,300)
var b = a.textflow("some very long text which should be wrapped in a box of specified size blah blah blah");
b.attr({x:100, y:100}); // moves to 100:100
b.size(150,20); //moves to 0, 0!
SVG.clear() removes everything inside the svg document. Elements created internally by svg.js should not be removed.
This bug leads to unable to create mask after calling SVG.clear()
If you call the test page with IE8, this raises several javascript errors.
SVG.supported throws in my case, a sequence error.
Right now it looks like you're exporting svg
and SVG
. I think you could probably reduce it by attaching the SVG
methods to the svg
function. Possibly something like this:
var svg = this.svg = function() {
}
svg.extend = function() { ... }
Hey guys,
I am using your library and really like it. However I am dealing a lot with groups and when I call
group.forward();
I get an error
Cannot call method 'children' of null
Is it the case that groups just cant be moved forward one layer at a time? if I call
group.front();
it works fine.
To reproduce run the following:
var group = page.group();
group.path('M10,20L30,40')
group.forward();
where page is a SVG. I am using chrome 26.0.1410.65.
Thanks for any help
So I have been able to mask a image with a gradient and with opacity. I have also had some success with animating the gradient mask over the element to reveal it. I was wondering if this is really supported or if there is a better way. Basically I'm trying to achieve a simple 'wipe on' of elements with a faded edge. Simple to do in flash , hard to do in html/javascript. Here is what I have so far which works.
$(window).load(function() {
var draw = SVG('svgRectangle').size(200, 155)
var imageDraw = SVG('imageDraw').size(200, 155)
var gradient = draw.gradient('linear', function(stop) {
stop.at({ offset: 0, color: '#000', opacity: 1 })
stop.at({ offset: 100, color: '#fff', opacity: 1 })
})
var rect2 = draw.rect(200, 155).attr({ fill: gradient})
var image = imageDraw.image('/us_assets/svg/img/image.png', 200, 155)
image.maskWith(rect2);
rect2.animate(2500, '>', 1000).move(500, 0).after(function() {
this.animate().move(0,0)
})
});
The text function of the Text "shape" assumes plain text only but SVG spec allows a mix of text nodes and possibly recursive TSPAN nodes that have attributes of there own.
Available methods will probably have to be changed. This might break current functionality and might require update to the documentation. Transforming newline characters(\n) into TSPAN might have to be removed or changed because it makes a lot of assumptions about the text passed as argument.
The Text and TSpan "shapes" will probably need more methods. I'm thinking something like addText and addTSpan which would append a new text node or a new TSPAN node to the element. The text getter methods would have to be modified to extract only text from descendant text nodes and TSPAN nodes.
The "title" tag in the group element would bring full compatibility with svg-edit and better compatibility with sozi.
In the eventuality of using svg.js for programming an editor, it could be used to encapsulate the names of the layers. Very useful for applications like mapping, labeling, arranging groups.
Not an issue. Here's a very simple addition to add support to svg foreignbject:
SVG.ForiegnObject = function() {
this.constructor.call(this, SVG.create('foreignObject'))
/* store type */
this.type = 'foreignObject'
}
SVG.ForiegnObject.prototype = new SVG.Shape
SVG.extend(SVG.ForiegnObject, {
appendChild: function (child, attrs) {
var newChild = typeof(child)=='string' ? document.createElement(child) : child
if (typeof(attrs)=='object'){
for(a in attrs) newChild[a] = attrs[a]
}
this.node.appendChild(newChild)
return this
},
getChild: function (index) {
return this.node.childNodes[index]
}
})
SVG.extend(SVG.Container, {
foreignObject: function(width, height) {
return this.put(new SVG.ForiegnObject).size(width == null ? 100 : width, height == null ? 100 : height)
}
})
And a simple example of use (assuming you put the above code in a file called svg.foreignobject.js:
<html>
<head>
<script src='svg.js'></script>
<script src='svg.foreignobject.js'></script>
</head>
<body onload="doit()">
<h1>Foreign Objects</h1>
<div id='canvas'></div>
<script>
var txt = "some text that is quite long. and it goes on and on. and it's pointless really. and the grammar is terrible. blah. blah. blah"
var canvas = SVG('canvas').size(1024, 550)
canvas.rect(1024, 550).attr({ fill: '#eee' })
var fobj = canvas.foreignObject(100,100).attr({id: 'fobj'})
function doit() {
fobj.appendChild("div", {id: 'mydiv', innerText: txt})
var n = fobj.getChild(0)
fobj.attr({width: 200, height: 100}).rotate(45).move(100,0)
n.style.height = '50px'
n.style.overflow = 'hidden'
n.style.border = "solid black 1px"
}
</script>
</body>
</html>
This is an alternative way to do text flowing and/or integrating a WYSWIG editor into a primarily SVG web page.
Calling update() on a gradient removes the nodes directly using .node.removeChild rather than svg.js's removeElement method, so the _children member is not updated.
Every time the gradient is updated, the list grows.
var setStops = function(stop)
{
stop.at({offset: 0, color: 'red'});
stop.at({offset: 1, color: 'blue'});
}
var g = svg.gradient('linear', setStops);
console.log(g.children().length); // 2
g.update(setStops);
console.log(g.children().length); // 4 (expected 2)
Hi Wout,
I have several existing groups that I would like to put in a (container) group.
Is this possible with svg.js?
Cheers.
.back() send item to position 1 instead of 0. The documentation states that this is because the defs element sits at position 0 yet for me (Chrome 28.0 ubuntu) defs is always the last sibling.
It would be nice to have SVG.js able to work from inside the SVG. In this case you could build your SVG editor as a SVG document and achieve from the very beginning resolution independency.
If this has been done already, needs documenting. For now I get
"Uncaught TypeError: Cannot set property 'cssText' of null svg.min.js:2
SVG.Doc.stage svg.min.js:2
SVG.Doc svg.min.js:2
SVG svg.min.js:2
(anonymous function)"
sorry. the code has more text, but gitbub's MD does not want to show it...
<script type="text/javascript" xlink:href="js/svg.min.js"></script>
<script type="text/javascript"> <![CDATA[
function doSomething()) {
var draw = SVG("viewport");
// do some svg.js work
}
]]> </script>
does SVG.js support this:
http://svg-mitchallen.blogspot.com.au/2005/03/morphing-shapes-in-svg.html
I read through the documentation, but I couldn't seem to find something related to it.
Not sure is this is a bug, feature request or documentation thing, but animating gradient colors could definitely be easier.
var s1, s2, s3
draw.gradient('radial', function(stop) {
s1 = stop.at({ offset: 0, color: '#000', opacity: 1 })
s2 = stop.at({ offset: 50, color: '#f03', opacity: 1 })
s3 = stop.at({ offset: 100, color: '#066', opacity: 1 })
})
s1.update({ offset: 10, color: '#0f0', opacity: 1 })
To me, it would be a lot cleaner if there was a getStops() or getStop(index) method on the Gradient.
s1.animate().update({color: '#0f0'}); // Doesn't work
This would be really nice to have.
s1.animate().attr({'stop-color': '#0f0'}); // Doesn't work
If you don't supply a color when you create the stop, then you can animate with the stop-color attribute
var s1, s2, s3
draw.gradient('radial', function(stop) {
s1 = stop.at({ offset: 0, opacity: 1 }) // No color!
s2 = stop.at({ offset: 50, color: '#f03', opacity: 1 })
s3 = stop.at({ offset: 100, color: '#066', opacity: 1 })
})
s1.attr({'stop-color': '#000'});
s1.animate({'stop-color': '#0f0'}); // This now works
Hey Wout,
Nothing big, but I just spotted a typo in the doc:
, scaleX: [scaling on x-axis]
, scaleX: [scaling on y-axis]
Terrific work, been getting my head around it for a few days now.
Cheers.
There are really two issues in this example.
Here is an example: http://jsfiddle.net/qeKdv/
Hey Wout,
I bumped on your Library end was wondering which direction your are heading with SVG.js? Is it going to be some kind of SMIL JS-implementation?! It looks promising cause I can't find any library out there that only focus on animation or interaction with SVGs. Raphael and D3.js focus more on doing it all in JS more towards data-visualisation.
Are you aware of a pretty old (2005) and don't know even maintained library called SmilScript?! http://schepers.cc/svg/smilscript/
Cheers,
Raymond
I'm not sure if this should be a plugin. I would put it in the base tools. Here is a demo. For horiz flip see comment:
Hello
whould it be possible to add textPath feature ?
I tried my self to add it but can't really understand which object is what
currently I have a path created with svg.js and know I must add a node like this
<text font-family="Verdana" font-size="20" font-weight="bold" fill="#ffffff">
<textPath xlink:href="#SvgjsPath1007" startOffset="100%" text-anchor="end">
Test
</textPath>
</text>
With SvgjsPath1007 the id of my path
This lib has drag ability which is very good. But in order to explore a svg image there is a strong need to drag and zoom in/out. Maybe on the mouse wheel.. and with an optional 2 keyboard keys.
This would be very interesting for Science. Then svg.js could be used for something like http://caskanatomy.info/microscopy/full.html
Hi, great job on this library, really impressive.
I edited it to add support for filters on top of already existing support for masks.
below are the changes:
change1:
// Create masking element
, mask: function() {
return this.defs().put(new SVG.Mask)
}
/**** RD-added: start *_/
// Create masking element
, filter: function() {
return this.defs().put(new SVG.Filter)
}
/_* RD-added: end ****/
// Create clipping element
, clip: function() {
return this.defs().put(new SVG.Clip)
}
change2:
SVG.extend(SVG.Element, {
// Distribute mask to svg element
maskWith: function(element) {
/* use given mask or create a new one */
this.mask = element instanceof SVG.Mask ? element : this.parent.mask().add(element)
return this.attr('mask', 'url(#' + this.mask.attr('id') + ')')
}})
/**** RD-added: start ****/
SVG.Filter = function() {
this.constructor.call(this, SVG.create('filter'))
}// Inherit from SVG.Container
SVG.Filter.prototype = new SVG.ContainerSVG.extend(SVG.Element, {
// Distribute mask to svg element
filterWith: function(element) {
/* use given mask or create a new one */
this.filter = element instanceof SVG.Filter ? element : this.parent.filter().add(element)
return this.attr('filter', 'url(#' + this.filter.attr('id') + ')')
}})
/**** RD-added: end ****/SVG.Clip = function() {
this.constructor.call(this, SVG.create('clipPath'))
}
Usage:
var toShow = draw.image('img/IMG_2.JPG', width, height);
var filter = draw.filter();
var gauss = SVG.create('feGaussianBlur');
gauss.setAttribute('stdDeviation', 3);
filter.node.appendChild(gauss);
toShow.filterWith(filter);
This works like a charm.
Regards,
Remy
There is a problem with the rotate function.
When i call rotate(90,0,0) the o.cx and o.cy values return false in the transform rotate statement.
if (o.rotation != 0)
transform.push('rotate(' + o.rotation + ',' + (o.cx || this.bbox().cx) + ',' + (o.cy || this.bbox().cy) + ')')
Let's say I have the following code:
var el = draw.group();
el.attr('transform', 'matrix(1,0,0,-1,0,0)');
The node of this object has now the attribute transform="matrix(1,0,0,-1,0,0)"
.
If I now try move the element:
el.move(100, 0);
It resets all previous transformations, and its node transform attribute looks like transform="translate(0,100)"
.
Is that expected? Right now the only way to wor around this behavior is doing something like this:
el.scale(1, -1);
var t = el.transform();
t.x = t.x + 100;
el.transform(t);
when you set the text property using aText.attr('text','asdf') the property is saved, but when you set it using aText.text('asdf') the property is not saved in aText.attrs.text
(excuse my bad english)
The svg.js works quite well and could be implemented quickly. Unfortunately, the mask seems to stop working as soon as you use the tag in the head. If this then refers to the root directory and the html file is in a subfolder. This applies with clip and maskWith.
greetings
If you clip a group and then try to clip an object within that group, you get an error.
This seems to be due to the clip
property being re-used for both the clipping object and "Create clipping object" method.
Reproduce:
window.onload = function()
{
var paper = SVG('canvas').size(200, 200);
var group = paper.group();
group.ellipse(200, 200).center(100, 100).fill('red');
var inner = group.ellipse(100, 100).center(100, 100).fill('blue');
var outerClip = paper.rect(100, 100).center(100, 100);
var innerClip = paper.rect(90, 90).center(100, 100);
group.clipWith(outerClip);
inner.clipWith(innerClip);
};
It seems to work ok if you just rename one of them:
clipWith: function(element) {
/* use given clip or create a new one */
// Was this.clip = element instanceof SVG.Clip ? element : this.parent.clip().add(element)
this.clip = element instanceof SVG.Clip ? element : this.parent.createClip().add(element)
return this.attr('clip-path', 'url(#' + this.clip.attr('id') + ')')
}
// Was clip: function() {
createClip: function() {
return this.defs().put(new SVG.Clip)
}
The bbox() object could have a new expandBy method that takes another bounding box so you could combine whatever you want.
Or maybe SVG.G needs to have bbox() implmented to automatically include its children.
I believe that for sending forward is very simple: you can add it again to it's parent with appendChild. but this has to be available and documented in SVG js. for sending to the background.. has to be the first child of the same parent.
var el = SVG.get("SvgjsG1007") //created with SVGjs in another function
var t = el.transform();
throws Uncaught TypeError: Cannot read property 'matrix' of undefined
Current issue attempting to absolute position an SVG canvas created using svg.js. Assigning the id attribute and using CSS to specify the position style property is overridden, it appears, during the Safari hack concerning text. Workaround?
Minimal (not) working example: http://jsfiddle.net/mreq/LP7sa/
Error: Invalid value for <rect> attribute x="NaN"
Error: Invalid value for <rect> attribute y="NaN"
There's a few more %
-related issues (am working on a responsive app, where everything is in given relative). I'll try to pinpoint all of them.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.