Skip to content

Instantly share code, notes, and snippets.

@petersirka
Last active March 18, 2017 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petersirka/765205cc1957c3a9d581 to your computer and use it in GitHub Desktop.
Save petersirka/765205cc1957c3a9d581 to your computer and use it in GitHub Desktop.
jQuery SVG transform (animation) plugin
// A simple SVG animation
$.fn.transform = function(obj, duration, easing, complete) {
var REG_TRANSFORM = /\}(?=\w)/g;
var REG_ROTATE = /[-0-9\.\s]+/;
var REG_TRANSLATE = /[-0-9\.]+(\,|\s)?[-0-9\.]+/;
var REG_SCALE = /[0-9\.]+/;
var REG_SKEW = /[-0-9\.]+/;
if (typeof(easing) === 'function') {
complete = easing;
easing = undefined;
}
this.each(function() {
var self = $(this);
var t = self.attr('transform');
var transform = t;
var afrom = {};
var ato = {};
var aindex = {};
var index = -1;
for (var m in obj) {
var reg = new RegExp(m + '\\([-0-9\\.\\,\\s]+\\)', 'g');
var val = t.match(reg);
!val && (val = '');
index++;
switch (m) {
case 'rotate':
var arr = val.toString().match(REG_ROTATE);
!arr && (arr = '0 0 0');
arr = arr.toString().split(' ');
afrom.rotateA = parseFloat(arr[0]);
afrom.rotateB = parseFloat(arr[1]);
isNaN(afrom.rotateB) && (afrom.rotateB = 0);
afrom.rotateC = parseFloat(arr[2]);
isNaN(afrom.rotateC) && (afrom.rotateC = 0);
arr = obj[m].toString().split(' ');
ato.rotateA = parseFloat(arr[0]);
ato.rotateB = parseFloat(arr[1]);
ato.rotateC = parseFloat(arr[2]);
if (isNaN(ato.rotateB)) {
if (afrom.rotateB !== undefined)
ato.rotateB = afrom.rotateB;
else
ato.rotateB = 0;
}
if (isNaN(ato.rotateC)) {
if (afrom.rotateC !== undefined)
ato.rotateC = afrom.rotateC;
else
ato.rotateC = 0;
}
aindex.rotate = index;
transform = transform.replace(val, '{' + index + '}');
break;
case 'translate':
var arr = val.toString().match(REG_TRANSLATE);
!arr && (arr = '0 0');
arr = arr.toString().replace(/,/g, ' ').split(' ');
afrom.translateX = parseFloat(arr[0]);
afrom.translateY = parseFloat(arr[1]);
arr = obj[m].toString().replace(/,/g, ' ').split(' ');
ato.translateX = parseFloat(arr[0]);
ato.translateY = parseFloat(arr[1]);
isNaN(ato.translateX) && (ato.translateX = afrom.translateX);
isNaN(ato.translateY) && (ato.translateY = afrom.translateY);
aindex.translate = index;
transform = transform.replace(val, '{' + index + '}');
break;
case 'scale':
var scale = val.toString().match(REG_SCALE);
!scale && (scale = '1');
ato.scale = parseFloat(obj[m].toString());
afrom.scale = parseFloat(scale.toString().replace(',', '.'));
aindex.scale = index;
transform = transform.replace(val, '{' + index + '}');
break;
case 'skewX':
var skewX = val.toString().match(REG_SKEW);
!skewX && (skewX = '0');
ato.skewX = parseFloat(obj[m].toString());
afrom.skewX = parseFloat(skewX.toString().replace(',', '.'));
aindex.skewX = index;
transform = transform.replace(val, '{' + index + '}');
break;
case 'skewY':
var skewY = val.toString().match(REG_SKEW);
!skewY && (skewY = '0');
ato.skewY = parseFloat(obj[m].toString());
afrom.skewY = parseFloat(skewY.toString().replace(',', '.'));
aindex.skewY = index;
transform = transform.replace(val, '{' + index + '}');
break;
}
}
transform = transform.replace(REG_TRANSFORM, '} ');
if (!duration) {
var attr = transform;
aindex.translate >= 0 && (attr = attr.replace('{' + aindex.translate + '}', 'translate(' + ato.translateX + ' ' + ato.translateY + ')'));
aindex.scale >= 0 && (attr = attr.replace('{' + aindex.scale + '}', 'scale(' + ato.scale + ')'));
aindex.rotate >= 0 && (attr = attr.replace('{' + aindex.rotate + '}', 'rotate(' + ato.rotateA + (ato.rotateB !== undefined ? ' ' + ato.rotateB : '') + (ato.rotateC !== undefined ? ' ' + ato.rotateC : '') + ')'));
aindex.skewX >= 0 && (attr = attr.replace('{' + aindex.skewX + '}', 'skewX(' + ato.skewX + ')'));
aindex.skewY >= 0 && (attr = attr.replace('{' + aindex.skewY + '}', 'skewY(' + ato.skewY + ')'));
self.attr('transform', attr);
return;
}
$(afrom).animate(ato, { duration: duration, easing: easing, step: function() {
var attr = transform;
aindex.translate >= 0 && (attr = attr.replace('{' + aindex.translate + '}', 'translate(' + this.translateX + ' ' + this.translateY + ')'));
aindex.scale >= 0 && (attr = attr.replace('{' + aindex.scale + '}', 'scale(' + this.scale + ')'));
aindex.skewX >= 0 && (attr = attr.replace('{' + aindex.skewX + '}', 'skewX(' + this.skewX + ')'));
aindex.skewX >= 0 && (attr = attr.replace('{' + aindex.skewX + '}', 'skewX(' + this.skewX + ')'));
aindex.rotate >= 0 && (attr = attr.replace('{' + aindex.rotate + '}', 'rotate(' + this.rotateA + (this.rotateB !== undefined ? ' ' + this.rotateB : '') + (this.rotateC !== undefined ? ' ' + this.rotateC : '') + ')'));
self.attr('transform', attr);
}, done: complete });
});
return this;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment