diff --git a/src/element.js b/src/element.js index e758fbb..597fb57 100644 --- a/src/element.js +++ b/src/element.js @@ -456,39 +456,34 @@ elproto.asPX = function (attr, value) { } return +unit2px(this, attr, value) } -// SIERRA SnapElement.use(): I suggest adding a note about how to access the original element the returned instantiates. It's a part of SVG with which ordinary web developers may be least familiar. -/*\ - * SnapElement.use - [ method ] - ** - * Creates a `` element linked to the current element - ** - = (SnapElement) the `` element - \*/ +/*** + * Creates a `` element linked to the current element + ** + = (SnapElement) the `` element +*/ elproto.use = function () { - let use, - id = this.node.id + let id = this.node.id + let attr, use + if (!id) { id = this.id - $(this.node, { - id: id - }) + this.node.id = id } + attr = { 'xlink:href': '#' + id } if ( this.type == 'linearGradient' || this.type == 'radialGradient' || this.type == 'pattern' ) { - use = make(this.type, this.node.parentNode) + use = make(this.type, this.node.parentNode, attr) } else { - use = make('use', this.node.parentNode) + use = make('use', this.node.parentNode, attr) } - $(use.node, { - 'xlink:href': '#' + id - }) + use.original = this return use } + function fixids(el) { let els = el.selectAll('*'), it, @@ -561,9 +556,7 @@ function fixids(el) { \*/ elproto.clone = function () { let clone = wrap(this.node.cloneNode(true)) - if ($(clone.node, 'id')) { - $(clone.node, { id: clone.id }) - } + fixids(clone) clone.insertAfter(this) return clone diff --git a/src/paper.js b/src/paper.js index 06744b0..3344a77 100644 --- a/src/paper.js +++ b/src/paper.js @@ -6,7 +6,7 @@ import eve from './eve.js' import { Snap, SnapElement, Paper, make } from './svg.js' -import { $, is, uuid, preload } from './utils.js' +import { $, h, is, uuid, preload } from './utils.js' import { doc, win } from './lib/constants.js' let proto = Paper.prototype @@ -28,20 +28,19 @@ let proto = Paper.prototype * offset (number) stops offset 0..100 */ function GaddStop(color, offset) { - let stop = $('stop'), - attr = { - offset: +offset + '%' - } + let attr = { + offset: +offset + '%' + } color = parseColor(color) attr['stop-color'] = color.hex if (color.opacity < 1) { attr['stop-opacity'] = color.opacity } - $(stop, attr) + let stop = h('stop', attr) let stops = this.stops(), inserted for (let i = 0; i < stops.length; i++) { - let stopOffset = parseFloat(stops[i].attr('offset')) + let stopOffset = +stops[i].attr('offset') if (stopOffset > offset) { this.node.insertBefore(stop, stops[i].node) inserted = true diff --git a/src/svg.js b/src/svg.js index bc41412..eeb759b 100644 --- a/src/svg.js +++ b/src/svg.js @@ -26,14 +26,6 @@ import { extend } from './utils.js' -let has = 'hasOwnProperty', - math = Math, - abs = math.abs, - E = '', - S = ' ', - objectToString = Object.prototype.toString, - hub = {} - export function make(name, parent = doc.body, attr, children) { let el = h(name, attr, children) parent.appendChild(el) @@ -245,7 +237,7 @@ export class Snap { if (is(values, 'array')) { let i = values.length while (i--) - if (abs(values[i] - value) <= tolerance) { + if (Math.abs(values[i] - value) <= tolerance) { return values[i] } } else { @@ -423,9 +415,9 @@ function svgTransform2string(tstr) { } } if (name == 'skewX') { - res.push(['m', 1, 0, math.tan(rad(params[0])), 1, 0, 0]) + res.push(['m', 1, 0, Math.tan(rad(params[0])), 1, 0, 0]) } else if (name == 'skewY') { - res.push(['m', 1, math.tan(rad(params[0])), 0, 1, 0, 0]) + res.push(['m', 1, Math.tan(rad(params[0])), 0, 1, 0, 0]) } else { res.push([name.charAt(0)].concat(params)) } @@ -545,7 +537,7 @@ export function unit2px(el, name, value) { } function getW(val) { if (val == null) { - return E + return '' } if (val == +val) { return val @@ -559,7 +551,7 @@ export function unit2px(el, name, value) { } function getH(val) { if (val == null) { - return E + return '' } if (val == +val) { return val @@ -627,45 +619,23 @@ export function unit2px(el, name, value) { return out } -function add2group(list) { - if (!is(list, 'array')) { - list = Array.prototype.slice.call(arguments, 0) +function add2group(...list) { + let i = 0 + let node = this.node + + while (this[i]) { + delete this[i++] } - let i = 0, - j = 0, - node = this.node - while (this[i]) delete this[i++] - for (i = 0; i < list.length; i++) { - if (list[i].type == 'set') { - list[i].forEach(function (el) { - node.appendChild(el.node) - }) - } else { - node.appendChild(list[i].node) - } + + for (let it of list) { + node.appendChild(it.node) } - let children = node.childNodes - for (i = 0; i < children.length; i++) { - this[j++] = wrap(children[i]) + let children = Array.from(node.childNodes) + for (let i = 0; i < children.length; i++) { + this[i] = wrap(children[i]) } return this } -// Hub garbage collector every 10s -setInterval(function () { - for (let key in hub) - if (hub[has](key)) { - let el = hub[key], - node = el.node - if ( - (el.type != 'svg' && !node.ownerSVGElement) || - (el.type == 'svg' && - (!node.parentNode || - ('ownerSVGElement' in node.parentNode && !node.ownerSVGElement))) - ) { - delete hub[key] - } - } -}, 1e4) export class Paper { constructor(width, height) { @@ -674,9 +644,6 @@ export class Paper { dom = width } if (dom) { - if (dom.snap in hub) { - return hub[dom.snap] - } let doc = dom.ownerDocument res = new SnapElement(dom) desc = dom.querySelector('desc') @@ -693,8 +660,7 @@ export class Paper { extend(res, Paper.prototype) res.paper = res.root = res } else { - res = make('svg', doc.body) - h(res.node, { + res = make('svg', doc.body, { width, height, version: 1.1, @@ -704,48 +670,8 @@ export class Paper { return res } - /*\ - ** - * Creates a nested SVG element. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `svg` element - ** - \*/ - svg(x, y, width, height, vbx, vby, vbw, vbh) { - let attrs = {} - if (is(x, 'object') && y == null) { - attrs = x - } else { - if (x != null) { - attrs.x = x - } - if (y != null) { - attrs.y = y - } - if (width != null) { - attrs.width = width - } - if (height != null) { - attrs.height = height - } - if (vbx != null && vby != null && vbw != null && vbh != null) { - attrs.viewBox = [vbx, vby, vbw, vbh] - } - } - return this.el('svg', attrs) - } - mask(first) { - let attr, - el = this.el('mask') + let el = this.el('mask') if (arguments.length == 1 && first && !first.type) { el.attr(first) } else if (arguments.length) { @@ -754,21 +680,20 @@ export class Paper { return el } - /*\ - ** - * Equivalent in behaviour to @Paper.g, except it’s a pattern. - - x (number) @optional X of the element - - y (number) @optional Y of the element - - width (number) @optional width of the element - - height (number) @optional height of the element - - vbx (number) @optional viewbox X - - vby (number) @optional viewbox Y - - vbw (number) @optional viewbox width - - vbh (number) @optional viewbox height - ** - = (object) the `pattern` element - ** - \*/ + /*** + * Equivalent in behaviour to @Paper.g, except it’s a pattern. + - x (number) @optional X of the element + - y (number) @optional Y of the element + - width (number) @optional width of the element + - height (number) @optional height of the element + - vbx (number) @optional viewbox X + - vby (number) @optional viewbox Y + - vbw (number) @optional viewbox width + - vbh (number) @optional viewbox height + ** + = (object) the `pattern` element + ** + */ ptrn(x, y, width, height, vx, vy, vw, vh) { if (is(x, 'object')) { let attr = x @@ -794,31 +719,27 @@ export class Paper { } return this.el('pattern', attr) } - /*\ - ** - * Creates a element. - - id (string) @optional id of element to link - * or - - id (SnapElement) @optional element to link - ** - = (object) the `use` element - ** - \*/ + /* + ** + * Creates a element. + - id (string) @optional id of element to link + * or + - id (SnapElement) @optional element to link + ** + = (object) the `use` element + ** + */ use(id) { - if (id != null) { - if (id instanceof SnapElement) { - if (!id.attr('id')) { - id.attr({ id: uuid(id.type + 'S') }) - } - id = id.attr('id') + if (id instanceof SnapElement) { + if (!id.attr('id')) { + id.attr({ id: uuid(id.type + 'S') }) } - if (String(id).charAt() == '#') { - id = id.substring(1) - } - return this.el('use', { 'xlink:href': '#' + id }) - } else { - return SnapElement.prototype.use.call(this) + id = id.attr('id') } + if (id.charAt() == '#') { + id = id.slice(1) + } + return this.el('use', { 'xlink:href': '#' + id }) } /*\ ** @@ -838,40 +759,38 @@ export class Paper { return this.el('symbol', attr) } - /*\ - ** - * Draws a text string - ** - - x (number) x coordinate position - - y (number) y coordinate position - - text (string|array) The text string to draw or array of strings to nest within separate `` elements - = (object) the `text` element - ** - > Usage - | let t1 = paper.text(50, 50, "Snap"); - | let t2 = paper.text(50, 50, ["S","n","a","p"]); - | // Text path usage - | t1.attr({textpath: "M10,10L100,100"}); - | // or - | let pth = paper.path("M10,10L100,100"); - | t1.attr({textpath: pth}); - \*/ + /*** + * Draws a text string + ** + - x (number) x coordinate position + - y (number) y coordinate position + - text (string|array) The text string to draw or array of strings to nest within separate `` elements + = (object) the `text` element + ** + > Usage + let t1 = paper.text(50, 50, "Snap"); + let t2 = paper.text(50, 50, ["S","n","a","p"]); + // Text path usage + t1.attr({textpath: "M10,10L100,100"}); + // or + let pth = paper.path("M10,10L100,100"); + t1.attr({textpath: pth}); + */ text(x = 0, y = 0, text = '') { return this.el('text', { x, y }, text) } - /*\ - ** - * Draws a line - ** - - x1 (number) x coordinate position of the start - - y1 (number) y coordinate position of the start - - x2 (number) x coordinate position of the end - - y2 (number) y coordinate position of the end - = (object) the `line` element - ** - > Usage - | let t1 = paper.line(50, 50, 100, 100); - \*/ + /*** + * Draws a line + ** + - x1 (number) x coordinate position of the start + - y1 (number) y coordinate position of the start + - x2 (number) x coordinate position of the end + - y2 (number) y coordinate position of the end + = (object) the `line` element + ** + > Usage + let t1 = paper.line(50, 50, 100, 100); + */ line(x1, y1, x2, y2) { let attr = {} if (is(x1, 'object')) { @@ -1108,7 +1027,7 @@ export class Paper { if (arguments.length == 1 && first && !first.type) { el.attr(first) } else if (arguments.length) { - el.add(Array.from(arguments)) + el.add(...Array.from(arguments)) } return el } @@ -1179,9 +1098,6 @@ export class Paper { export class SnapElement { constructor(el) { - if (el.snap in hub) { - return hub[el.snap] - } let svg try { svg = el.ownerSVGElement @@ -1210,7 +1126,7 @@ export class SnapElement { transform: [] } el.snap = id - hub[id] = this + if (this.type == 'g') { this.add = add2group } diff --git a/src/utils.js b/src/utils.js index cd570e1..3067a03 100644 --- a/src/utils.js +++ b/src/utils.js @@ -117,6 +117,8 @@ export function h(el, props = null, children) { return el } +window.h = h + export function clone(obj) { if (typeof obj == 'function' || Object(obj) !== obj) { return obj