Svg.js: Transform origin when animating

Created on 5 Jul 2013  Â·  9Comments  Â·  Source: svgdotjs/svg.js

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

Most helpful comment

Just wondering if the "origin" feature ever made it? I couldnt find any in the documentation.

All 9 comments

Great to hear you like svg.js! The easiest way to this kind of animation is to put the elements in a group and position them with half negative width and height. A quick example with a square and circle:

var group = draw.group().move(100, 100)
group.rect(100, 100).move(-50,-50).fill('none').stroke({ width: 1, color: '#ff0099' })
group.circle(110).move(-55,-55).fill('none').stroke({ width: 1, color: '#009a99' })

group.animate(3000).scale(2)

Thank you — I had solved it like that before, but thought that there maybe might be an origin option, or something — nevertheless, it works now… appreciated! :) Is it possible that clipping won’t work now any more though (after grouping)? Let’s say I’d like the hexagon to be a mask for an image (the hexagon scales when hovered)… it only works when not in the group. Here is what I mean:

Here’s a simplified version of what I’m running:

var draw = SVG('canvas'),
hexagon = draw.polygon().ngon({
 radius: 70,
 points: 6
}),
img = draw.image('someimage.jpg', 195),
group = draw.group().move(80, 95)

group.add(hexagon);
hexagon.move(-70, -70);

img.clipWith(hexagon); // This doesn’t seem to work any more

Indeed, that is an SVG issue. Groups and clipPaths/masks don't work very well together, it's a real pain.

But is this more in the line of what you are trying to achieve?

http://jsfiddle.net/wout/FQcPv/

var draw = SVG('canvas')

var img = draw.image('http://distilleryimage9.s3.amazonaws.com/bab9aef0cadd11e2972d22000aa82023_7.jpg', 450)

var hexagon = draw.polygon().ngon({
 radius: 70,
 points: 6
})

img.clipWith(hexagon.center(225,225))

hexagon.animate(2000).scale(3).during(function() {
  this.center(225,225)
})

Just as a side note, I am working on a new class called SVG.Origin that will define the origin for all transformations and animations. The code would then look something like:

/* move by upper left corner */
rect.move(150, 200, '0,0')

/* move by center */
rect.move(150, 200, '0.5,0.5')

/* move by bottom right corner */
rect.move(150, 200, '1,1')

/* move by a fixed point */
rect.move(150, 200, { x: 175, y: 225 })

But it is still in very early beta and I am not yet sure I will eventually release it.

Please excuse my late reply, I’ve been a bit sick over the last week. :/

Yes, that is approximately what I was trying to achieve — works now. Thank you very much! :)

What’s just weird is, that it doesn’t work in Firefox (at all), neither does your fiddle. Any idea what might be causing it?

True, I forgot about that. Firefox is a bitch when it comes to getBBox on elements in the defs. Firefox treats them the same way as html elements with display:none, they don't have a geometry. The center() method in svg.js requires the values of the bbox() method. Therefore my example does not work because to FireFox, the elements in the defs have 0 width and height. A few years ago this bug has already been submitted to FireFox but they didn't do anything about it.

Here is how you can solve this problem:
http://jsfiddle.net/wout/FQcPv/3/

Happy I ended up here again, seems like I didn’t hit enter the last time I commented…

THANK YOU! :)

Just wondering if the "origin" feature ever made it? I couldnt find any in the documentation.

Was this page helpful?
0 / 5 - 0 ratings