Skip to content

Commit

Permalink
SVG: use CSS transitions on SVG elements wherever supported
Browse files Browse the repository at this point in the history
- Basically, it works everywhere but IE9-11 and Edge 13-14+

Fixes gh-252
  • Loading branch information
timmywil committed Jul 26, 2016
1 parent e973e72 commit 13c113c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 24 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ iOS and Android are supported.

## SVG support

Panzoom supports panning and zooming SVG elements directly, in browsers that support SVG. Note that animations do not work on SVG elements,
but one could implement transitions manually by overriding the `setTransform()` method and integrating a tweening library for javascript animations (such as [tween.js](http://www.createjs.com/#!/TweenJS)).
Panzoom supports panning and zooming SVG elements directly, in browsers that support SVG.

In IE9-11 and Edge 13-14+, CSS animations/transitions do not work on SVG elements, at least for the transform style. They do work in other browsers.

One could implement transitions manually in those browsers by overriding the `setTransform()` method and integrating a tweening library for javascript animations (such as [tween.js](http://www.createjs.com/#!/TweenJS)).

**Compatibility note:** *There is a [known issue with Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=530985) and using the `focal` option. Firefox does not correctly maintain the dimensions of SVG parent elements, which throws off offsets. If using the `focal` option with SVG, the workaround is to set the correct offset on the Panzoom instance manually using `Panzoom.prototype.parentOffset` ([example](http://jsfiddle.net/timmywil/Vu8nA/)).*

Expand Down
38 changes: 29 additions & 9 deletions dist/jquery.panzoom.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @license jquery.panzoom.js v3.1.1
* Updated: Tue Jul 19 2016
* Updated: Tue Jul 26 2016
* Add pan and zoom functionality to any element
* Copyright (c) timmy willison
* Released under the MIT license
Expand Down Expand Up @@ -244,7 +244,7 @@

// Build the appropriately-prefixed transform style property name
// De-camelcase
this._transform = !this.isSVG && $.cssProps.transform.replace(rupper, '-$1').toLowerCase();
this._transform = $.cssProps.transform.replace(rupper, '-$1').toLowerCase();

// Build the transition value
this._buildTransition();
Expand Down Expand Up @@ -439,14 +439,23 @@

/**
* Sets a transform on the $set
* For SVG, the style attribute takes precedence
* and allows us to animate
* @param {String} transform
*/
setTransform: function(transform) {
var method = this.isSVG ? (transform === 'none' ? 'removeAttr' : 'attr') : 'style';
var $set = this.$set;
var i = $set.length;
while(i--) {
$[method]($set[i], 'transform', transform);
$.style($set[i], 'transform', transform);

// Support IE9-11, Edge 13-14+
// Set attribute alongside style attribute
// since IE and Edge do not respect style settings on SVG
// See https://css-tricks.com/transforms-on-svg-elements/
if (this.isSVG) {
$set[i].setAttribute('transform', transform);
}
}
},

Expand All @@ -464,13 +473,21 @@
if (transform) {
this.setTransform(transform);
} else {
// Retrieve the transform
transform = $[this.isSVG ? 'attr' : 'style'](transformElem, 'transform');

// IE and Edge still set the transform style properly
// They just don't render it on SVG
// So we get a correct value here
transform = $.style(transformElem, 'transform');

if (this.isSVG && (!transform || transform === 'none')) {
transform = $.attr(transformElem, 'transform') || 'none';
}
}

// Convert any transforms set by the user to matrix format
// by setting to computed
if (transform !== 'none' && !rmatrix.test(transform)) {

// Get computed and set for next time
this.setTransform(transform = $.css(transformElem, 'transform'));
}
Expand Down Expand Up @@ -692,11 +709,14 @@
var dims = options.dims = this.dimensions;
var clientX = focal.clientX;
var clientY = focal.clientY;
// Adjust the focal point for default transform-origin => 50% 50%

// Adjust the focal point for transform-origin 50% 50%
// SVG elements have a transform origin of 0 0
if (!this.isSVG) {
clientX -= (dims.width / startScale) / 2;
clientY -= (dims.height / startScale) / 2;
}

var clientV = new Vector(clientX, clientY, 1);
var surfaceM = new Matrix(matrix);
// Supply an offset manually if necessary
Expand Down Expand Up @@ -860,7 +880,8 @@
*/
_initStyle: function() {
var styles = {
// Set to defaults for the namespace
// Set the same default whether SVG or HTML
// transform-origin cannot be changed to 50% 50% in IE9-11 or Edge 13-14+
'transform-origin': this.isSVG ? '0 0' : '50% 50%'
};
// Set elem styles
Expand Down Expand Up @@ -1026,7 +1047,6 @@

/**
* Set transition property for later use when zooming
* If SVG, create necessary animations elements for translations and scaling
*/
_buildTransition: function() {
if (this._transform) {
Expand Down
Loading

0 comments on commit 13c113c

Please sign in to comment.