update
parent
4814b9c398
commit
e141a2db96
|
@ -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 <use> instantiates. It's a part of SVG with which ordinary web developers may be least familiar.
|
||||
/*\
|
||||
* SnapElement.use
|
||||
[ method ]
|
||||
**
|
||||
* Creates a `<use>` element linked to the current element
|
||||
**
|
||||
= (SnapElement) the `<use>` element
|
||||
\*/
|
||||
/***
|
||||
* Creates a `<use>` element linked to the current element
|
||||
**
|
||||
= (SnapElement) the `<use>` 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
|
||||
|
|
13
src/paper.js
13
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
|
||||
|
|
248
src/svg.js
248
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 <use> element.
|
||||
- id (string) @optional id of element to link
|
||||
* or
|
||||
- id (SnapElement) @optional element to link
|
||||
**
|
||||
= (object) the `use` element
|
||||
**
|
||||
\*/
|
||||
/*
|
||||
**
|
||||
* Creates a <use> 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 `<tspan>` 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 `<tspan>` 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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue