diff options
author | wout <wout@impinc.co.uk> | 2013-03-09 22:28:47 +0100 |
---|---|---|
committer | wout <wout@impinc.co.uk> | 2013-03-09 22:28:47 +0100 |
commit | 6c6c82ed59533f44f8754b69d47e3b11cd6dd129 (patch) | |
tree | adaef53d8970acb228fe14d490c532f1baabbb13 /src | |
parent | 16c4a146ee97fa43e0c456fe801490351e551e96 (diff) | |
download | svg.js-6c6c82ed59533f44f8754b69d47e3b11cd6dd129.tar.gz svg.js-6c6c82ed59533f44f8754b69d47e3b11cd6dd129.zip |
Bumped to v0.9, added better style management, text support and extended animation functionality0.10
Diffstat (limited to 'src')
-rw-r--r-- | src/arrange.js | 4 | ||||
-rw-r--r-- | src/bbox.js | 2 | ||||
-rw-r--r-- | src/color.js | 1 | ||||
-rw-r--r-- | src/doc.js | 10 | ||||
-rw-r--r-- | src/element.js | 108 | ||||
-rw-r--r-- | src/ellipse.js | 10 | ||||
-rw-r--r-- | src/event.js | 37 | ||||
-rw-r--r-- | src/fx.js | 72 | ||||
-rw-r--r-- | src/gradient.js | 32 | ||||
-rw-r--r-- | src/line.js | 29 | ||||
-rw-r--r-- | src/nested.js | 2 | ||||
-rw-r--r-- | src/path.js | 11 | ||||
-rw-r--r-- | src/pattern.js | 10 | ||||
-rw-r--r-- | src/poly.js | 4 | ||||
-rw-r--r-- | src/rect.js | 2 | ||||
-rw-r--r-- | src/regex.js | 37 | ||||
-rw-r--r-- | src/shape.js | 2 | ||||
-rw-r--r-- | src/sugar.js | 20 | ||||
-rw-r--r-- | src/svg.js | 86 | ||||
-rw-r--r-- | src/text.js | 128 | ||||
-rw-r--r-- | src/wrap.js | 32 |
21 files changed, 384 insertions, 255 deletions
diff --git a/src/arrange.js b/src/arrange.js index 47134ed..3ef486f 100644 --- a/src/arrange.js +++ b/src/arrange.js @@ -24,11 +24,9 @@ SVG.extend(SVG.Element, { } // Send given element one step backward , backward: function() { - var i - this.parent.level() - i = this.position() + var i = this.position() if (i > 1) this.parent.remove(this).add(this, i - 1) diff --git a/src/bbox.js b/src/bbox.js index d70ac68..6b9885a 100644 --- a/src/bbox.js +++ b/src/bbox.js @@ -8,7 +8,7 @@ SVG.BBox = function(element) { this.y = box.y + element.trans.y /* add the center */ - this.cx = box.x + element.trans.x + box.width / 2 + this.cx = box.x + element.trans.x + box.width / 2 this.cy = box.y + element.trans.y + box.height / 2 /* plain width and height */ diff --git a/src/color.js b/src/color.js index dde2c65..89c811d 100644 --- a/src/color.js +++ b/src/color.js @@ -42,7 +42,6 @@ SVG.Color = function(color) { this.r = color.r this.g = color.g this.b = color.b - } } @@ -26,9 +26,9 @@ SVG.Doc.prototype = new SVG.Container // Basically it sets the position of the svg node to absolute // when the dom is loaded, and resets it to relative a few milliseconds later. SVG.Doc.prototype.stage = function() { - var check, - element = this, - wrapper = document.createElement('div') + var check + , element = this + , wrapper = document.createElement('div') /* set temp wrapper to position relative */ wrapper.style.cssText = 'position:relative;height:100%;' @@ -40,10 +40,10 @@ SVG.Doc.prototype.stage = function() { /* check for dom:ready */ check = function() { if (document.readyState === 'complete') { - element.attr('style', 'position:absolute;') + element.style('position:absolute;') setTimeout(function() { /* set position back to relative */ - element.attr('style', 'position:relative;') + element.style('position:relative;') /* remove temp wrapper */ element.parent.removeChild(element.node.parentNode) diff --git a/src/element.js b/src/element.js index e11f650..2e7ebb2 100644 --- a/src/element.js +++ b/src/element.js @@ -23,7 +23,7 @@ SVG.Element = function(node) { } /* initialize style store */ - this.style = {} + this.styles = {} /* initialize transformation store with defaults */ this.trans = { @@ -112,6 +112,7 @@ SVG.extend(SVG.Element, { , remove: function() { if (this.parent) this.parent.remove(this) + return this } // Get parent document @@ -127,24 +128,29 @@ SVG.extend(SVG.Element, { if (arguments.length < 2) { /* apply every attribute individually if an object is passed */ if (typeof a == 'object') - for (v in a) this.attr(v, a[v]) + for (v in a) + this.attr(v, a[v]) /* act as a getter for style attributes */ else if (this._isStyle(a)) return a == 'text' ? this.content : a == 'leading' ? - this[a] : - this.style[a] + this.leading() : + this.style(a) /* act as a getter if the first and only argument is not an object */ else - return this.attrs[a] + return this.attrs[a] || this.node.getAttribute(a) } else if (v === null) { /* remove value */ this.node.removeAttribute(a) + } else if (a == 'style') { + /* redirect to the style method */ + return this.style(v) + } else { /* store value */ this.attrs[a] = v @@ -175,28 +181,38 @@ SVG.extend(SVG.Element, { a == 'text' ? this.text(v) : a == 'leading' ? - this[a] = v : - this.style[a] = v - - this.text(this.content) + this.leading(v) : + this.style(a, v) + + /* rebuild if required */ + if (this.rebuild) + this.rebuild() } } return this } // Manage transformations -, transform: function(o) { - /* act as a getter if the first argument is a string */ - if (typeof o === 'string') - return this.trans[o] +, transform: function(o, v) { + if (typeof o === 'string') { + /* act as a getter if only one string argument is given */ + if (arguments.length < 2) + return this.trans[o] + /* apply transformations as object if key value arguments are given*/ + var transform = {} + transform[o] = v + + return this.transform(transform) + } + /* ... otherwise continue as a setter */ - var key, transform = [] + var transform = [] /* merge values */ - for (key in o) - if (o[key] != null) - this.trans[key] = o[key] + for (v in o) + if (o[v] != null) + this.trans[v] = o[v] /* alias current transformations */ o = this.trans @@ -227,6 +243,52 @@ SVG.extend(SVG.Element, { /* add only te required transformations */ return this.attr('transform', transform.join(' ')) } + // Dynamic style generator +, style: function(s, v) { + if (arguments.length == 0) { + /* get full style */ + return this.attr('style') + + } else if (arguments.length < 2) { + /* apply every style individually if an object is passed */ + if (typeof s == 'object') { + for (v in s) this.style(v, s[v]) + + } else if (SVG.regex.isCss.test(s)) { + /* parse css string */ + s = s.split(';') + + /* apply every definition individually */ + for (var i = 0; i < s.length; i++) { + v = s[i].split(':') + + if (v.length == 2) + this.style(v[0].replace(/\s+/g, ''), v[1].replace(/^\s+/,'').replace(/\s+$/,'')) + } + } else { + /* act as a getter if the first and only argument is not an object */ + return this.styles[s] + } + + } else if (v === null) { + /* remove value */ + delete this.styles[s] + + } else { + /* store value */ + this.styles[s] = v + } + + /* rebuild style string */ + s = '' + for (v in this.styles) + s += v + ':' + this.styles[v] + ';' + + /* apply style */ + this.node.setAttribute('style', s) + + return this + } // Store data values on svg nodes , data: function(a, v, r) { if (arguments.length < 2) { @@ -257,19 +319,15 @@ SVG.extend(SVG.Element, { } // Show element , show: function() { - this.node.style.display = '' - - return this + return this.style('display', '') } // Hide element , hide: function() { - this.node.style.display = 'none' - - return this + return this.style('display', 'none') } // Is element visible? , visible: function() { - return this.node.style.display != 'none' + return this.style('display') != 'none' } // Private: find svg parent by instance , _parent: function(parent) { @@ -282,7 +340,7 @@ SVG.extend(SVG.Element, { } // Private: tester method for style detection , _isStyle: function(attr) { - return typeof attr == 'string' && this._isText() ? (/^font|text|leading/).test(attr) : false + return typeof attr == 'string' ? SVG.regex.isStyle.test(attr) : false } // Private: element type tester , _isText: function() { diff --git a/src/ellipse.js b/src/ellipse.js index f9398cf..6ff5608 100644 --- a/src/ellipse.js +++ b/src/ellipse.js @@ -17,15 +17,15 @@ SVG.extend(SVG.Ellipse, { }, // Custom size function size: function(width, height) { - return this. - attr({ rx: width / 2, ry: (height != null ? height : width) / 2 }). - center() + return this + .attr({ rx: width / 2, ry: (height != null ? height : width) / 2 }) + .center() }, // Custom center function center: function(x, y) { return this.attr({ - cx: x || (this.attrs.x || 0) + (this.attrs.rx || 0), - cy: y || (this.attrs.y || 0) + (this.attrs.ry || 0) + cx: x != null ? x : (this.attrs.x || 0) + (this.attrs.rx || 0) + , cy: y != null ? y : (this.attrs.y || 0) + (this.attrs.ry || 0) }) } diff --git a/src/event.js b/src/event.js index df3cd6a..84022c7 100644 --- a/src/event.js +++ b/src/event.js @@ -3,28 +3,27 @@ // rect.click(function() { // this.fill({ color: '#f06' }) // }) -;[ 'click', - 'dblclick', - 'mousedown', - 'mouseup', - 'mouseover', - 'mouseout', - 'mousemove', - 'mouseenter', - 'mouseleave', - 'touchstart', - 'touchend', - 'touchmove', - 'touchcancel' ].forEach(function(event) { +;[ 'click' +, 'dblclick' +, 'mousedown' +, 'mouseup' +, 'mouseover' +, 'mouseout' +, 'mousemove' +, 'mouseenter' +, 'mouseleave' +, 'touchstart' +, 'touchend' +, 'touchmove' +, 'touchcancel' ].forEach(function(event) { /* add event to SVG.Element */ SVG.Element.prototype[event] = function(f) { var self = this /* bind event to element rather than element node */ - this.node['on' + event] = typeof f == 'function' - ? function() { return f.apply(self, arguments); } - : null + this.node['on' + event] = typeof f == 'function' ? + function() { return f.apply(self, arguments) } : null return this } @@ -54,11 +53,11 @@ SVG.extend(SVG.Element, { SVG.on(this.node, event, listener) return this - }, + } // Unbind event from listener - off: function(event, listener) { +, off: function(event, listener) { SVG.off(this.node, event, listener) return this } -});
\ No newline at end of file +})
\ No newline at end of file @@ -11,7 +11,7 @@ SVG.extend(SVG.FX, { duration = duration == null ? 1000 : duration ease = ease || '<>' - var akeys, tkeys, tvalues + var akeys, tkeys, skeys , element = this.target , fx = this , start = new Date().getTime() @@ -20,24 +20,29 @@ SVG.extend(SVG.FX, { /* start animation */ this.interval = setInterval(function(){ // This code was borrowed from the emile.js micro framework by Thomas Fuchs, aka MadRobby. - var index + var i, key , time = new Date().getTime() , pos = time > finish ? 1 : (time - start) / duration /* collect attribute keys */ if (akeys == null) { akeys = [] - for (var key in fx.attrs) + for (key in fx.attrs) akeys.push(key) } /* collect transformation keys */ if (tkeys == null) { tkeys = [] - for (var key in fx.trans) + for (key in fx.trans) tkeys.push(key) - - tvalues = {} + } + + /* collect style keys */ + if (skeys == null) { + skeys = [] + for (key in fx.styles) + skeys.push(key) } /* apply easing */ @@ -57,23 +62,23 @@ SVG.extend(SVG.FX, { if (fx._move) element.move(fx._at(fx._move.x, pos), fx._at(fx._move.y, pos)) else if (fx._center) - element.move(fx._at(fx._center.x, pos), fx._at(fx._center.y, pos)) + element.center(fx._at(fx._center.x, pos), fx._at(fx._center.y, pos)) /* run all size properties */ if (fx._size) element.size(fx._at(fx._size.width, pos), fx._at(fx._size.height, pos)) /* animate attributes */ - for (index = akeys.length - 1; index >= 0; index--) - element.attr(akeys[index], fx._at(fx.attrs[akeys[index]], pos)) + for (i = akeys.length - 1; i >= 0; i--) + element.attr(akeys[i], fx._at(fx.attrs[akeys[i]], pos)) /* animate transformations */ - if (tkeys.length > 0) { - for (index = tkeys.length - 1; index >= 0; index--) - tvalues[tkeys[index]] = fx._at(fx.trans[tkeys[index]], pos) - - element.transform(tvalues) - } + for (i = tkeys.length - 1; i >= 0; i--) + element.transform(tkeys[i], fx._at(fx.trans[tkeys[i]], pos)) + + /* animate styles */ + for (i = skeys.length - 1; i >= 0; i--) + element.style(skeys[i], fx._at(fx.styles[skeys[i]], pos)) /* callback for each keyframe */ if (fx._during) @@ -100,12 +105,23 @@ SVG.extend(SVG.FX, { else this.attrs[a] = { from: this.target.attr(a), to: v } - return this; + return this } // Add animatable transformations -, transform: function(o) { - for (var key in o) - this.trans[key] = { from: this.target.trans[key], to: o[key] } +, transform: function(t, v) { + for (var key in t) + this.trans[key] = { from: this.target.trans[key], to: t[key] } + + return this + } + // Add animatable styles +, style: function(s, v) { + if (typeof s == 'object') + for (var key in s) + this.style(key, s[key]) + + else + this.styles[s] = { from: this.target.style(s), to: v } return this } @@ -122,11 +138,18 @@ SVG.extend(SVG.FX, { } // Add animatable size , size: function(width, height) { - var box = this.target.bbox() - - this._size = { - width: { from: box.width, to: width } - , height: { from: box.height, to: height } + if (this.target instanceof SVG.Text) { + /* animate font size for Text elements */ + this.attr('font-size', width) + + } else { + /* animate bbox based size for all other elements */ + var box = this.target.bbox() + + this._size = { + width: { from: box.width, to: width } + , height: { from: box.height, to: height } + } } return this @@ -162,6 +185,7 @@ SVG.extend(SVG.FX, { /* reset storage for properties that need animation */ this.attrs = {} this.trans = {} + this.styles = {} this._move = null this._size = null this._after = null diff --git a/src/gradient.js b/src/gradient.js index 73975c5..4c30b43 100644 --- a/src/gradient.js +++ b/src/gradient.js @@ -15,25 +15,25 @@ SVG.extend(SVG.Gradient, { return this.type == 'radial' ? this.attr({ fx: x + '%', fy: y + '%' }) : this.attr({ x1: x + '%', y1: y + '%' }) - }, + } // To position - to: function(x, y) { +, to: function(x, y) { return this.type == 'radial' ? this.attr({ cx: x + '%', cy: y + '%' }) : this.attr({ x2: x + '%', y2: y + '%' }) - }, + } // Radius for radial gradient - radius: function(radius) { +, radius: function(radius) { return this.type == 'radial' ? this.attr({ r: radius + '%' }) : this - }, + } // Add a color stop - at: function(stop) { +, at: function(stop) { return this.put(new SVG.Stop(stop)) - }, + } // Update gradient - update: function(block) { +, update: function(block) { /* remove all stops */ while (this.node.hasChildNodes()) this.node.removeChild(this.node.lastChild) @@ -42,9 +42,9 @@ SVG.extend(SVG.Gradient, { block(this) return this - }, + } // Return the fill id - fill: function() { +, fill: function() { return 'url(#' + this.attr('id') + ')' } @@ -81,20 +81,16 @@ SVG.extend(SVG.Stop, { /* add color stops */ update: function(o) { - var index, - style = '', - attr = ['opacity', 'color'] + var index + , attr = ['opacity', 'color'] /* build style attribute */ for (index = attr.length - 1; index >= 0; index--) if (o[attr[index]] != null) - style += 'stop-' + attr[index] + ':' + o[attr[index]] + ';' + this.style('stop-' + attr[index], o[attr[index]]) /* set attributes */ - return this.attr({ - offset: (o.offset != null ? o.offset : this.attrs.offset || 0) + '%', - style: style - }) + return this.attr('offset', (o.offset != null ? o.offset : this.attrs.offset || 0) + '%') } }) diff --git a/src/line.js b/src/line.js index 1e783e4..0712f1e 100644 --- a/src/line.js +++ b/src/line.js @@ -12,24 +12,25 @@ SVG.extend(SVG.Line, { var bbox = this.bbox() return this.attr({ - x1: this.attr('x1') - bbox.x + x, - y1: this.attr('y1') - bbox.y + y, - x2: this.attr('x2') - bbox.x + x, - y2: this.attr('y2') - bbox.y + y + x1: this.attr('x1') - bbox.x + x + , y1: this.attr('y1') - bbox.y + y + , x2: this.attr('x2') - bbox.x + x + , y2: this.attr('y2') - bbox.y + y }) - }, + } // Move element by its center - center: function(x, y) { +, center: function(x, y) { var bbox = this.bbox() return this.move(x - bbox.width / 2, y - bbox.height / 2) - }, + } // Set line size by width and height - size: function(width, height) { +, size: function(width, height) { var bbox = this.bbox() - this.attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', bbox.x + width) - return this.attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', bbox.y + height) + return this + .attr(this.attr('x1') < this.attr('x2') ? 'x2' : 'x1', bbox.x + width) + .attr(this.attr('y1') < this.attr('y2') ? 'y2' : 'y1', bbox.y + height) } }) @@ -37,10 +38,10 @@ SVG.extend(SVG.Line, { SVG.extend(SVG.Container, { line: function(x1, y1, x2, y2) { return this.put(new SVG.Line().attr({ - x1: x1, - y1: y1, - x2: x2, - y2: y2 + x1: x1 + , y1: y1 + , x2: x2 + , y2: y2 })) } })
\ No newline at end of file diff --git a/src/nested.js b/src/nested.js index 9d4401c..537d610 100644 --- a/src/nested.js +++ b/src/nested.js @@ -1,7 +1,7 @@ SVG.Nested = function() { this.constructor.call(this, SVG.create('svg')) - this.attr('style', 'overflow:visible') + this.style('overflow', 'visible') } // Inherit from SVG.Container diff --git a/src/path.js b/src/path.js index e62f8d1..2d3558f 100644 --- a/src/path.js +++ b/src/path.js @@ -6,18 +6,17 @@ SVG.Path = function() { SVG.Path.prototype = new SVG.Shape() SVG.extend(SVG.Path, { - - /* move using transform */ + // Move using transform move: function(x, y) { this.transform({ x: x, y: y }) - }, + } - /* set path data */ - plot: function(data) { + // Set path data +, plot: function(data) { return this.attr('d', data || 'M0,0') } -});
\ No newline at end of file +})
\ No newline at end of file diff --git a/src/pattern.js b/src/pattern.js index 7343d6a..c5f51e0 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -25,11 +25,11 @@ SVG.extend(SVG.Defs, { block(element) return element.attr({ - x: 0, - y: 0, - width: width, - height: height, - patternUnits: 'userSpaceOnUse' + x: 0 + , y: 0 + , width: width + , height: height + , patternUnits: 'userSpaceOnUse' }) } diff --git a/src/poly.js b/src/poly.js index 9e89570..ce5a70c 100644 --- a/src/poly.js +++ b/src/poly.js @@ -12,7 +12,7 @@ SVG.Polyline = function() { } // Inherit from SVG.Shape -SVG.Polyline.prototype = new SVG.Shape() +SVG.Polyline.prototype = new SVG.Shape // Add polygon-specific functions SVG.extend(SVG.Polyline, SVG.Poly) @@ -22,7 +22,7 @@ SVG.Polygon = function() { } // Inherit from SVG.Shape -SVG.Polygon.prototype = new SVG.Shape() +SVG.Polygon.prototype = new SVG.Shape // Add polygon-specific functions SVG.extend(SVG.Polygon, SVG.Poly)
\ No newline at end of file diff --git a/src/rect.js b/src/rect.js index 0a398be..1a3bf19 100644 --- a/src/rect.js +++ b/src/rect.js @@ -3,4 +3,4 @@ SVG.Rect = function() { } // Inherit from SVG.Shape -SVG.Rect.prototype = new SVG.Shape()
\ No newline at end of file +SVG.Rect.prototype = new SVG.Shape
\ No newline at end of file diff --git a/src/regex.js b/src/regex.js index e89dc85..adf82b4 100644 --- a/src/regex.js +++ b/src/regex.js @@ -1,18 +1,33 @@ // Storage for regular expressions SVG.regex = { + /* parse unit value */ + unit: /^([\d\.]+)([a-z%]{0,2})$/ - unit: /^([\d\.]+)([a-z%]{0,2})$/ + /* parse hex value */ +, hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i -, hex: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i - -, rgb: /rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/ - -, hsb: /hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/ - -, isHex: /^#/i - -, isRgb: /^rgb\(/ + /* parse rgb value */ +, rgb: /rgb\((\d+),(\d+),(\d+),([\d\.]+)\)/ + + /* parse hsb value */ +, hsb: /hsb\((\d+),(\d+),(\d+),([\d\.]+)\)/ -, isHsb: /^hsb\(/ + /* test hex value */ +, isHex: /^#[a-f0-9]{3,6}$/i + /* test rgb value */ +, isRgb: /^rgb\(/ + + /* test hsb value */ +, isHsb: /^hsb\(/ + + /* test css declaration */ +, isCss: /[^:]+:[^;]+;?/ + + /* test css property */ +, isStyle: /^font|text|leading|cursor/ + + /* test for blank string */ +, isBlank: /^(\s+)?$/ + }
\ No newline at end of file diff --git a/src/shape.js b/src/shape.js index a11bbc4..0594ed7 100644 --- a/src/shape.js +++ b/src/shape.js @@ -3,4 +3,4 @@ SVG.Shape = function(element) { } // Inherit from SVG.Element -SVG.Shape.prototype = new SVG.Element()
\ No newline at end of file +SVG.Shape.prototype = new SVG.Element
\ No newline at end of file diff --git a/src/sugar.js b/src/sugar.js index 14868e3..1f7339a 100644 --- a/src/sugar.js +++ b/src/sugar.js @@ -63,23 +63,19 @@ SVG.extend(SVG.Element, SVG.FX, { if (SVG.Text) { - SVG.extend(SVG.Text, { + SVG.extend(SVG.Text, SVG.FX, { // Set font font: function(o) { - var key, attr = {} - - for (key in o) - key == 'leading' ? - attr[key] = o[key] : + for (var key in o) key == 'anchor' ? - attr['text-anchor'] = o[key] : + this.attr('text-anchor', o[key]) : _styleAttr.indexOf(key) > -1 ? - attr['font-'+ key] = o[key] : - void 0 - - return this.attr(attr).text(this.content) + this.attr('font-'+ key, o[key]) : + this.attr(key, o[key]) + + return this } - + }) } @@ -1,56 +1,60 @@ -// Use the `svg()` function to create a SVG document within a given html element. The first argument can either be an id of the element or the selected element itself. +// Use the `SVG()` function to create a SVG document within a given html element. The first argument can either be an id of the element or the selected element itself. // -// var draw = svg('paper').size(300, 300) +// var draw = SVG('paper').size(300, 300) // var rect = draw.rect(100, 100).attr({ fill: '#f06' }) -// Shortcut for creating a svg document -this.svg = function(element) { +// The main wrapping element +this.SVG = function(element) { if (SVG.supported) return new SVG.Doc(element) } -// The main wrapping element -this.SVG = { - /* default namespaces */ - ns: 'http://www.w3.org/2000/svg' -, xlink: 'http://www.w3.org/1999/xlink' +// DEPRECATED!!! Use SVG() instead +this.svg = function(element) { + console.warn('WARNING: svg() is deprecated, please use SVG() instead.') + return SVG(element) +} + +// Default namespaces +SVG.ns = 'http://www.w3.org/2000/svg' +SVG.xlink = 'http://www.w3.org/1999/xlink' + +// Element id sequence +SVG.did = 1000 + +// Get next named element id +SVG.eid = function(name) { + return 'Svgjs' + name.charAt(0).toUpperCase() + name.slice(1) + 'Element' + (SVG.did++) +} + +// Method for element creation +SVG.create = function(name) { + /* create element */ + var element = document.createElementNS(this.ns, name) - /* element id sequence */ -, did: 1000 - - // Get next named element id -, eid: function(name) { - return 'Svgjs' + name.charAt(0).toUpperCase() + name.slice(1) + 'Element' + (SVG.did++) - } - // Method for element creation -, create: function(name) { - /* create element */ - var element = document.createElementNS(this.ns, name) - - /* apply unique id */ - element.setAttribute('id', this.eid(name)) - - return element - } + /* apply unique id */ + element.setAttribute('id', this.eid(name)) + + return element +} + // Method for extending objects -, extend: function() { - var modules, methods, key, i - - /* get list of modules */ - modules = Array.prototype.slice.call(arguments) - - /* get object with extensions */ - methods = modules.pop() - - for (i = modules.length - 1; i >= 0; i--) - if (modules[i]) - for (key in methods) - modules[i].prototype[key] = methods[key] - } +SVG.extend = function() { + var modules, methods, key, i + + /* get list of modules */ + modules = Array.prototype.slice.call(arguments) + + /* get object with extensions */ + methods = modules.pop() + for (i = modules.length - 1; i >= 0; i--) + if (modules[i]) + for (key in methods) + modules[i].prototype[key] = methods[key] } // svg support test @@ -59,4 +63,4 @@ SVG.supported = (function() { !! document.createElementNS(SVG.ns,'svg').createSVGRect })() -if (!SVG.supported) return false;
\ No newline at end of file +if (!SVG.supported) return false
\ No newline at end of file diff --git a/src/text.js b/src/text.js index 6201269..3feb514 100644 --- a/src/text.js +++ b/src/text.js @@ -1,77 +1,117 @@ // List font style attributes as they should be applied to style -var _styleAttr = ['size', 'family', 'weight', 'stretch', 'variant', 'style'] +var _styleAttr = ('size family weight stretch variant style').split(' ') SVG.Text = function() { this.constructor.call(this, SVG.create('text')) /* define default style */ - this.style = { 'font-size': 16, 'font-family': 'Helvetica', 'text-anchor': 'start' } - this.leading = 1.2 + this.styles = { + 'font-size': 16 + , 'font-family': 'Helvetica' + , 'text-anchor': 'start' + } + + this._leading = 1.2 } // Inherit from SVG.Element -SVG.Text.prototype = new SVG.Shape() +SVG.Text.prototype = new SVG.Shape SVG.extend(SVG.Text, { // Set the text content text: function(text) { - /* update the content */ - this.content = text = text || 'text' - this.lines = [] + /* act as getter */ + if (text == null) + return this.content - var index, length, tspan, - style = this._style(), - parent = this.doc(), - lines = text.split("\n"), - size = this.style['font-size'] + /* remove existing lines */ + this.clear() - /* remove existing child nodes */ - while (this.node.hasChildNodes()) - this.node.removeChild(this.node.lastChild) + /* update the content */ + this.content = SVG.regex.isBlank.test(text) ? 'text' : text + + var i, il + , lines = text.split('\n') /* build new lines */ - for (index = 0, length = lines.length; index < length; index++) { - /* create new tspan and set attributes */ - tspan = new SVG.TSpan(). - text(lines[index]). - attr({ - dy: size * this.leading - (index == 0 ? size * 0.3 : 0), - x: (this.attrs.x || 0), - style: style - }) + for (i = 0, il = lines.length; i < il; i++) + this.tspan(lines[i]) - /* add new tspan */ - this.node.appendChild(tspan.node) - this.lines.push(tspan) - } - /* set style */ - return this.attr('style', style) - }, - - // Build style based on _styleAttr - _style: function() { - var index, style = '' + return this.attr('style', this.style()) + } + // Create a tspan +, tspan: function(text) { + var tspan = new SVG.TSpan().text(text) - for (index = _styleAttr.length - 1; index >= 0; index--) - if (this.style['font-' + _styleAttr[index]] != null) - style += 'font-' + _styleAttr[index] + ':' + this.style['font-' + _styleAttr[index]] + ';' + /* add new tspan */ + this.node.appendChild(tspan.node) + this.lines.push(tspan) - style += 'text-anchor:' + this.style['text-anchor'] + ';' - - return style + return tspan.attr('style', this.style()) + } + // Move element by its center +, center: function(x, y) { + var anchor = this.style('text-anchor') + , box = this.bbox() + , x = anchor == 'start' ? + x - box.width / 2 : + anchor == 'end' ? + x + box.width / 2 : x + + return this.move(x, y - box.height / 2) + } + // Set font size +, size: function(size) { + return this.attr('font-size', size) + } + // Set / get leading +, leading: function(value) { + /* act as getter */ + if (value == null) + return this._leading + + /* act as setter */ + this._leading = value + + return this.rebuild() + } + // rebuild appearance type +, rebuild: function() { + var i, il + , size = this.styles['font-size'] + + /* define position of all lines */ + for (i = 0, il = this.lines.length; i < il; i++) + this.lines[i].attr({ + dy: size * this._leading - (i == 0 ? size * 0.3 : 0) + , x: (this.attrs.x || 0) + , style: this.style() + }) + + return this + } + // Clear all lines +, clear: function() { + /* remove existing child nodes */ + while (this.node.hasChildNodes()) + this.node.removeChild(this.node.lastChild) + + this.lines = [] + + return this } }) - +// tspan class SVG.TSpan = function() { this.constructor.call(this, SVG.create('tspan')) } // Inherit from SVG.Shape -SVG.TSpan.prototype = new SVG.Shape() +SVG.TSpan.prototype = new SVG.Shape // Include the container object SVG.extend(SVG.TSpan, { @@ -82,4 +122,4 @@ SVG.extend(SVG.TSpan, { return this } -});
\ No newline at end of file +})
\ No newline at end of file diff --git a/src/wrap.js b/src/wrap.js index d3c6b8f..9fa10a2 100644 --- a/src/wrap.js +++ b/src/wrap.js @@ -14,30 +14,30 @@ SVG.extend(SVG.Wrap, { // Move wrapper around move: function(x, y) { return this.transform({ - x: x, - y: y + x: x + , y: y }) - }, + } // Set the actual size in pixels - size: function(width, height) { +, size: function(width, height) { var scale = width / this._b.width this.child.transform({ - scaleX: scale, - scaleY: height != null ? height / this._b.height : scale + scaleX: scale + , scaleY: height != null ? height / this._b.height : scale }) return this - }, + } // Move by center - center: function(x, y) { +, center: function(x, y) { return this.move( - x + (this._b.width * this.child.trans.scaleX) / -2, - y + (this._b.height * this.child.trans.scaleY) / -2 + x + (this._b.width * this.child.trans.scaleX) / -2 + , y + (this._b.height * this.child.trans.scaleY) / -2 ) - }, + } // Create distributed attr - attr: function(a, v, n) { +, attr: function(a, v, n) { /* call individual attributes if an object is given */ if (typeof a == 'object') { for (v in a) this.attr(v, a[v]) @@ -60,9 +60,9 @@ SVG.extend(SVG.Wrap, { } return this - }, + } // Distribute plot method to child - plot: function(data) { +, plot: function(data) { /* plot new shape */ this.child.plot(data) @@ -71,8 +71,8 @@ SVG.extend(SVG.Wrap, { /* reposition element withing wrapper */ this.child.transform({ - x: -this._b.x, - y: -this._b.y + x: -this._b.x + , y: -this._b.y }) return this |