summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorwout <wout@impinc.co.uk>2013-06-23 14:59:46 +0100
committerwout <wout@impinc.co.uk>2013-06-23 14:59:46 +0100
commita72b8a7afb609b9a76c494d9123d78e5c40962bf (patch)
treefdaacf9d56a3cc9e935ab1a5dcb4ad0458f929e4 /src
parent5e52bd4f9f309b20bc848d5d45e5e620b17c1ad7 (diff)
downloadsvg.js-a72b8a7afb609b9a76c494d9123d78e5c40962bf.tar.gz
svg.js-a72b8a7afb609b9a76c494d9123d78e5c40962bf.zip
Added SVG.Number, reworked gradient system
Diffstat (limited to 'src')
-rw-r--r--src/default.js34
-rw-r--r--src/element.js14
-rw-r--r--src/ellipse.js10
-rw-r--r--src/fx.js28
-rw-r--r--src/gradient.js35
-rw-r--r--src/number.js75
-rw-r--r--src/regex.js5
7 files changed, 143 insertions, 58 deletions
diff --git a/src/default.js b/src/default.js
index 314961d..fd85228 100644
--- a/src/default.js
+++ b/src/default.js
@@ -9,23 +9,25 @@ SVG.defaults = {
'fill-opacity': 1
, 'stroke-opacity': 1
, 'stroke-width': 0
- , fill: '#000'
- , stroke: '#000'
- , opacity: 1
+ , fill: '#000'
+ , stroke: '#000'
+ , opacity: 1
/* position */
- , x: 0
- , y: 0
- , cx: 0
- , cy: 0
- /* size */
- , width: 0
- , height: 0
- /* radius */
- , r: 0
- , rx: 0
- , ry: 0
- /* gradient */
- , offset: 0
+ , x: 0
+ , y: 0
+ , cx: 0
+ , cy: 0
+ /* size */
+ , width: 0
+ , height: 0
+ /* radius */
+ , r: 0
+ , rx: 0
+ , ry: 0
+ /* gradient */
+ , offset: 0
+ , 'stop-opacity': 1
+ , 'stop-color': '#000'
}
// Default transformation values
diff --git a/src/element.js b/src/element.js
index 3fa456f..d40108d 100644
--- a/src/element.js
+++ b/src/element.js
@@ -23,12 +23,18 @@ SVG.Element = function(node) {
SVG.extend(SVG.Element, {
// Move over x-axis
x: function(x) {
- if (x) x /= this.trans.scaleX
+ if (x) {
+ x = new SVG.Number(x)
+ x.value /= this.trans.scaleX
+ }
return this.attr('x', x)
}
// Move over y-axis
, y: function(y) {
- if (y) y /= this.trans.scaleY
+ if (y) {
+ y = new SVG.Number(y)
+ y.value /= this.trans.scaleY
+ }
return this.attr('y', y)
}
// Move by center over x-axis
@@ -50,8 +56,8 @@ SVG.extend(SVG.Element, {
// Set element size to given width and height
, size: function(width, height) {
return this.attr({
- width: width
- , height: height
+ width: new SVG.Number(width)
+ , height: new SVG.Number(height)
})
}
// Clone element
diff --git a/src/ellipse.js b/src/ellipse.js
index 2ff0c86..ea019e0 100644
--- a/src/ellipse.js
+++ b/src/ellipse.js
@@ -18,17 +18,17 @@ SVG.extend(SVG.Ellipse, {
}
// Move by center over x-axis
, cx: function(x) {
- return x == null ? this.attr('cx') : this.attr('cx', x / this.trans.scaleX)
+ return x == null ? this.attr('cx') : this.attr('cx', new SVG.Number(x).divide(this.trans.scaleX))
}
// Move by center over y-axis
, cy: function(y) {
- return y == null ? this.attr('cy') : this.attr('cy', y / this.trans.scaleY)
+ return y == null ? this.attr('cy') : this.attr('cy', new SVG.Number(y).divide(this.trans.scaleY))
}
// Custom size function
, size: function(width, height) {
return this.attr({
- rx: width / 2,
- ry: height / 2
+ rx: new SVG.Number(width).divide(2)
+ , ry: new SVG.Number(height).divide(2)
})
}
@@ -42,7 +42,7 @@ SVG.extend(SVG.Container, {
}
// Create an ellipse
, ellipse: function(width, height) {
- return this.put(new SVG.Ellipse().size(width, height).move(0, 0))
+ return this.put(new SVG.Ellipse).size(width, height).move(0, 0)
}
})
diff --git a/src/fx.js b/src/fx.js
index e1063e3..eb563fa 100644
--- a/src/fx.js
+++ b/src/fx.js
@@ -250,6 +250,16 @@ SVG.extend(SVG.FX, {
return this
}
+ // Add animateable gradient update
+, update: function(o) {
+ if (this.target instanceof SVG.Stop) {
+ if (o.opacity != null) this.attr('stop-opacity', o.opacity)
+ if (o.color != null) this.attr('stop-color', o.color)
+ if (o.offset != null) this.attr('offset', new SVG.Number(o.offset))
+ }
+
+ return this
+ }
// Add callback for each keyframe
, during: function(during) {
this._during = during
@@ -291,7 +301,10 @@ SVG.extend(SVG.FX, {
/* unit recalculation */
SVG.regex.unit.test(o.to) ?
- this._unit(o, pos) :
+ new SVG.Number(o.to)
+ .minus(new SVG.Number(o.from))
+ .times(pos)
+ .plus(new SVG.Number(o.from)) :
/* color recalculation */
o.to && (o.to.r || SVG.Color.test(o.to)) ?
@@ -300,19 +313,6 @@ SVG.extend(SVG.FX, {
/* for all other values wait until pos has reached 1 to return the final value */
pos < 1 ? o.from : o.to
}
- // Private: tween unit
-, _unit: function(o, pos) {
- var match, from
-
- /* convert FROM unit */
- match = SVG.regex.unit.exec(o.from.toString())
- from = parseFloat(match ? match[1] : 0)
-
- /* convert TO unit */
- match = SVG.regex.unit.exec(o.to)
-
- return (from + (parseFloat(match[1]) - from) * pos) + match[2]
- }
// Private: tween color
, _color: function(o, pos) {
var from, to
diff --git a/src/gradient.js b/src/gradient.js
index f98a0b0..71da7d1 100644
--- a/src/gradient.js
+++ b/src/gradient.js
@@ -13,19 +13,19 @@ SVG.extend(SVG.Gradient, {
// From position
from: function(x, y) {
return this.type == 'radial' ?
- this.attr({ fx: x + '%', fy: y + '%' }) :
- this.attr({ x1: x + '%', y1: y + '%' })
+ this.attr({ fx: new SVG.Number(x), fy: new SVG.Number(y) }) :
+ this.attr({ x1: new SVG.Number(x), y1: new SVG.Number(y) })
}
// To position
, to: function(x, y) {
return this.type == 'radial' ?
- this.attr({ cx: x + '%', cy: y + '%' }) :
- this.attr({ x2: x + '%', y2: y + '%' })
+ this.attr({ cx: new SVG.Number(x), cy: new SVG.Number(y) }) :
+ this.attr({ x2: new SVG.Number(x), y2: new SVG.Number(y) })
}
// Radius for radial gradient
-, radius: function(radius) {
+, radius: function(r) {
return this.type == 'radial' ?
- this.attr({ r: radius + '%' }) :
+ this.attr({ r: new SVG.Number(r) }) :
this
}
// Add a color stop
@@ -35,8 +35,7 @@ SVG.extend(SVG.Gradient, {
// Update gradient
, update: function(block) {
/* remove all stops */
- while (this.node.hasChildNodes())
- this.node.removeChild(this.node.lastChild)
+ this.clear()
/* invoke passed block */
block(this)
@@ -47,6 +46,10 @@ SVG.extend(SVG.Gradient, {
, fill: function() {
return 'url(#' + this.attr('id') + ')'
}
+ // Get a stop at the given index
+, get: function(i) {
+ return this.children()[i]
+ }
})
@@ -82,22 +85,18 @@ SVG.Stop = function(stop) {
}
// Inherit from SVG.Element
-SVG.Stop.prototype = new SVG.Element()
+SVG.Stop.prototype = new SVG.Element
//
SVG.extend(SVG.Stop, {
// add color stops
update: function(o) {
- var index
- , attr = ['opacity', 'color']
-
- /* build style attribute */
- for (index = attr.length - 1; index >= 0; index--)
- if (o[attr[index]] != null)
- this.style('stop-' + attr[index], o[attr[index]])
-
/* set attributes */
- return this.attr('offset', (o.offset != null ? o.offset : this.attr('offset')) + '%')
+ if (o.opacity != null) this.attr('stop-opacity', o.opacity)
+ if (o.color != null) this.attr('stop-color', o.color)
+ if (o.offset != null) this.attr('offset', new SVG.Number(o.offset))
+
+ return this
}
})
diff --git a/src/number.js b/src/number.js
new file mode 100644
index 0000000..28e260e
--- /dev/null
+++ b/src/number.js
@@ -0,0 +1,75 @@
+// Module for unit convertions
+SVG.Number = function(value) {
+
+ /* initialize defaults */
+ this.value = 0
+ this.unit = ''
+
+ /* parse value */
+ switch(typeof value) {
+ case 'number':
+ this.value = value
+ break
+ case 'string':
+ var match = value.match(SVG.regex.unit)
+
+ /* make valu numeric */
+ this.value = parseFloat(match[1])
+
+ /* normalize percent value */
+ if (match[2] == '%')
+ this.value /= 100
+
+ /* store unit */
+ this.unit = match[2]
+
+ break
+ default:
+ if (value instanceof SVG.Number) {
+ this.value = value.value
+ this.unit = value.unit
+ }
+ break
+ }
+}
+
+SVG.extend(SVG.Number, {
+ // Stringalize
+ toString: function() {
+ return (this.unit == '%' ? ~~(this.value * 100) : this.value) + this.unit
+ }
+, // Convert to primitive
+ valueOf: function() {
+ return this.value
+ }
+ // Convert to different unit
+, to: function(unit) {
+ if (typeof unit === 'string')
+ this.unit = unit
+
+ return this
+ }
+ // Add number
+, plus: function(number) {
+ this.value = this + new SVG.Number(number)
+
+ return this
+ }
+ // Subtract number
+, minus: function(number) {
+ return this.plus(-new SVG.Number(number))
+ }
+ // Multiply number
+, times: function(number) {
+ this.value = this * new SVG.Number(number)
+
+ return this
+ }
+ // Divide number
+, divide: function(number) {
+ this.value = this / new SVG.Number(number)
+
+ return this
+ }
+
+}) \ No newline at end of file
diff --git a/src/regex.js b/src/regex.js
index 4cd74ae..4286d8a 100644
--- a/src/regex.js
+++ b/src/regex.js
@@ -13,7 +13,7 @@ SVG.regex = {
/* parse rgb value */
, rgb: /rgb\((\d+),(\d+),(\d+)\)/
-
+
/* test hex value */
, isHex: /^#[a-f0-9]{3,6}$/i
@@ -31,5 +31,8 @@ SVG.regex = {
/* test for numeric string */
, isNumber: /^-?[\d\.]+$/
+
+ /* test for percent value */
+, isPercent: /^-?[\d\.]+%$/
} \ No newline at end of file