update
parent
4814b9c398
commit
e141a2db96
|
@ -456,39 +456,34 @@ elproto.asPX = function (attr, value) {
|
||||||
}
|
}
|
||||||
return +unit2px(this, 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.
|
/***
|
||||||
/*\
|
* Creates a `<use>` element linked to the current element
|
||||||
* SnapElement.use
|
**
|
||||||
[ method ]
|
= (SnapElement) the `<use>` element
|
||||||
**
|
*/
|
||||||
* Creates a `<use>` element linked to the current element
|
|
||||||
**
|
|
||||||
= (SnapElement) the `<use>` element
|
|
||||||
\*/
|
|
||||||
elproto.use = function () {
|
elproto.use = function () {
|
||||||
let use,
|
let id = this.node.id
|
||||||
id = this.node.id
|
let attr, use
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
id = this.id
|
id = this.id
|
||||||
$(this.node, {
|
this.node.id = id
|
||||||
id: id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
attr = { 'xlink:href': '#' + id }
|
||||||
if (
|
if (
|
||||||
this.type == 'linearGradient' ||
|
this.type == 'linearGradient' ||
|
||||||
this.type == 'radialGradient' ||
|
this.type == 'radialGradient' ||
|
||||||
this.type == 'pattern'
|
this.type == 'pattern'
|
||||||
) {
|
) {
|
||||||
use = make(this.type, this.node.parentNode)
|
use = make(this.type, this.node.parentNode, attr)
|
||||||
} else {
|
} else {
|
||||||
use = make('use', this.node.parentNode)
|
use = make('use', this.node.parentNode, attr)
|
||||||
}
|
}
|
||||||
$(use.node, {
|
|
||||||
'xlink:href': '#' + id
|
|
||||||
})
|
|
||||||
use.original = this
|
use.original = this
|
||||||
return use
|
return use
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixids(el) {
|
function fixids(el) {
|
||||||
let els = el.selectAll('*'),
|
let els = el.selectAll('*'),
|
||||||
it,
|
it,
|
||||||
|
@ -561,9 +556,7 @@ function fixids(el) {
|
||||||
\*/
|
\*/
|
||||||
elproto.clone = function () {
|
elproto.clone = function () {
|
||||||
let clone = wrap(this.node.cloneNode(true))
|
let clone = wrap(this.node.cloneNode(true))
|
||||||
if ($(clone.node, 'id')) {
|
|
||||||
$(clone.node, { id: clone.id })
|
|
||||||
}
|
|
||||||
fixids(clone)
|
fixids(clone)
|
||||||
clone.insertAfter(this)
|
clone.insertAfter(this)
|
||||||
return clone
|
return clone
|
||||||
|
|
13
src/paper.js
13
src/paper.js
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import eve from './eve.js'
|
import eve from './eve.js'
|
||||||
import { Snap, SnapElement, Paper, make } from './svg.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'
|
import { doc, win } from './lib/constants.js'
|
||||||
|
|
||||||
let proto = Paper.prototype
|
let proto = Paper.prototype
|
||||||
|
@ -28,20 +28,19 @@ let proto = Paper.prototype
|
||||||
* offset (number) stops offset 0..100
|
* offset (number) stops offset 0..100
|
||||||
*/
|
*/
|
||||||
function GaddStop(color, offset) {
|
function GaddStop(color, offset) {
|
||||||
let stop = $('stop'),
|
let attr = {
|
||||||
attr = {
|
offset: +offset + '%'
|
||||||
offset: +offset + '%'
|
}
|
||||||
}
|
|
||||||
color = parseColor(color)
|
color = parseColor(color)
|
||||||
attr['stop-color'] = color.hex
|
attr['stop-color'] = color.hex
|
||||||
if (color.opacity < 1) {
|
if (color.opacity < 1) {
|
||||||
attr['stop-opacity'] = color.opacity
|
attr['stop-opacity'] = color.opacity
|
||||||
}
|
}
|
||||||
$(stop, attr)
|
let stop = h('stop', attr)
|
||||||
let stops = this.stops(),
|
let stops = this.stops(),
|
||||||
inserted
|
inserted
|
||||||
for (let i = 0; i < stops.length; i++) {
|
for (let i = 0; i < stops.length; i++) {
|
||||||
let stopOffset = parseFloat(stops[i].attr('offset'))
|
let stopOffset = +stops[i].attr('offset')
|
||||||
if (stopOffset > offset) {
|
if (stopOffset > offset) {
|
||||||
this.node.insertBefore(stop, stops[i].node)
|
this.node.insertBefore(stop, stops[i].node)
|
||||||
inserted = true
|
inserted = true
|
||||||
|
|
248
src/svg.js
248
src/svg.js
|
@ -26,14 +26,6 @@ import {
|
||||||
extend
|
extend
|
||||||
} from './utils.js'
|
} 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) {
|
export function make(name, parent = doc.body, attr, children) {
|
||||||
let el = h(name, attr, children)
|
let el = h(name, attr, children)
|
||||||
parent.appendChild(el)
|
parent.appendChild(el)
|
||||||
|
@ -245,7 +237,7 @@ export class Snap {
|
||||||
if (is(values, 'array')) {
|
if (is(values, 'array')) {
|
||||||
let i = values.length
|
let i = values.length
|
||||||
while (i--)
|
while (i--)
|
||||||
if (abs(values[i] - value) <= tolerance) {
|
if (Math.abs(values[i] - value) <= tolerance) {
|
||||||
return values[i]
|
return values[i]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -423,9 +415,9 @@ function svgTransform2string(tstr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name == 'skewX') {
|
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') {
|
} 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 {
|
} else {
|
||||||
res.push([name.charAt(0)].concat(params))
|
res.push([name.charAt(0)].concat(params))
|
||||||
}
|
}
|
||||||
|
@ -545,7 +537,7 @@ export function unit2px(el, name, value) {
|
||||||
}
|
}
|
||||||
function getW(val) {
|
function getW(val) {
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
return E
|
return ''
|
||||||
}
|
}
|
||||||
if (val == +val) {
|
if (val == +val) {
|
||||||
return val
|
return val
|
||||||
|
@ -559,7 +551,7 @@ export function unit2px(el, name, value) {
|
||||||
}
|
}
|
||||||
function getH(val) {
|
function getH(val) {
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
return E
|
return ''
|
||||||
}
|
}
|
||||||
if (val == +val) {
|
if (val == +val) {
|
||||||
return val
|
return val
|
||||||
|
@ -627,45 +619,23 @@ export function unit2px(el, name, value) {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
function add2group(list) {
|
function add2group(...list) {
|
||||||
if (!is(list, 'array')) {
|
let i = 0
|
||||||
list = Array.prototype.slice.call(arguments, 0)
|
let node = this.node
|
||||||
|
|
||||||
|
while (this[i]) {
|
||||||
|
delete this[i++]
|
||||||
}
|
}
|
||||||
let i = 0,
|
|
||||||
j = 0,
|
for (let it of list) {
|
||||||
node = this.node
|
node.appendChild(it.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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let children = node.childNodes
|
let children = Array.from(node.childNodes)
|
||||||
for (i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
this[j++] = wrap(children[i])
|
this[i] = wrap(children[i])
|
||||||
}
|
}
|
||||||
return this
|
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 {
|
export class Paper {
|
||||||
constructor(width, height) {
|
constructor(width, height) {
|
||||||
|
@ -674,9 +644,6 @@ export class Paper {
|
||||||
dom = width
|
dom = width
|
||||||
}
|
}
|
||||||
if (dom) {
|
if (dom) {
|
||||||
if (dom.snap in hub) {
|
|
||||||
return hub[dom.snap]
|
|
||||||
}
|
|
||||||
let doc = dom.ownerDocument
|
let doc = dom.ownerDocument
|
||||||
res = new SnapElement(dom)
|
res = new SnapElement(dom)
|
||||||
desc = dom.querySelector('desc')
|
desc = dom.querySelector('desc')
|
||||||
|
@ -693,8 +660,7 @@ export class Paper {
|
||||||
extend(res, Paper.prototype)
|
extend(res, Paper.prototype)
|
||||||
res.paper = res.root = res
|
res.paper = res.root = res
|
||||||
} else {
|
} else {
|
||||||
res = make('svg', doc.body)
|
res = make('svg', doc.body, {
|
||||||
h(res.node, {
|
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
version: 1.1,
|
version: 1.1,
|
||||||
|
@ -704,48 +670,8 @@ export class Paper {
|
||||||
return res
|
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) {
|
mask(first) {
|
||||||
let attr,
|
let el = this.el('mask')
|
||||||
el = this.el('mask')
|
|
||||||
if (arguments.length == 1 && first && !first.type) {
|
if (arguments.length == 1 && first && !first.type) {
|
||||||
el.attr(first)
|
el.attr(first)
|
||||||
} else if (arguments.length) {
|
} else if (arguments.length) {
|
||||||
|
@ -754,21 +680,20 @@ export class Paper {
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
||||||
/*\
|
/***
|
||||||
**
|
* Equivalent in behaviour to @Paper.g, except it’s a pattern.
|
||||||
* Equivalent in behaviour to @Paper.g, except it’s a pattern.
|
- x (number) @optional X of the element
|
||||||
- x (number) @optional X of the element
|
- y (number) @optional Y of the element
|
||||||
- y (number) @optional Y of the element
|
- width (number) @optional width of the element
|
||||||
- width (number) @optional width of the element
|
- height (number) @optional height of the element
|
||||||
- height (number) @optional height of the element
|
- vbx (number) @optional viewbox X
|
||||||
- vbx (number) @optional viewbox X
|
- vby (number) @optional viewbox Y
|
||||||
- vby (number) @optional viewbox Y
|
- vbw (number) @optional viewbox width
|
||||||
- vbw (number) @optional viewbox width
|
- vbh (number) @optional viewbox height
|
||||||
- vbh (number) @optional viewbox height
|
**
|
||||||
**
|
= (object) the `pattern` element
|
||||||
= (object) the `pattern` element
|
**
|
||||||
**
|
*/
|
||||||
\*/
|
|
||||||
ptrn(x, y, width, height, vx, vy, vw, vh) {
|
ptrn(x, y, width, height, vx, vy, vw, vh) {
|
||||||
if (is(x, 'object')) {
|
if (is(x, 'object')) {
|
||||||
let attr = x
|
let attr = x
|
||||||
|
@ -794,31 +719,27 @@ export class Paper {
|
||||||
}
|
}
|
||||||
return this.el('pattern', attr)
|
return this.el('pattern', attr)
|
||||||
}
|
}
|
||||||
/*\
|
/*
|
||||||
**
|
**
|
||||||
* Creates a <use> element.
|
* Creates a <use> element.
|
||||||
- id (string) @optional id of element to link
|
- id (string) @optional id of element to link
|
||||||
* or
|
* or
|
||||||
- id (SnapElement) @optional element to link
|
- id (SnapElement) @optional element to link
|
||||||
**
|
**
|
||||||
= (object) the `use` element
|
= (object) the `use` element
|
||||||
**
|
**
|
||||||
\*/
|
*/
|
||||||
use(id) {
|
use(id) {
|
||||||
if (id != null) {
|
if (id instanceof SnapElement) {
|
||||||
if (id instanceof SnapElement) {
|
if (!id.attr('id')) {
|
||||||
if (!id.attr('id')) {
|
id.attr({ id: uuid(id.type + 'S') })
|
||||||
id.attr({ id: uuid(id.type + 'S') })
|
|
||||||
}
|
|
||||||
id = id.attr('id')
|
|
||||||
}
|
}
|
||||||
if (String(id).charAt() == '#') {
|
id = id.attr('id')
|
||||||
id = id.substring(1)
|
|
||||||
}
|
|
||||||
return this.el('use', { 'xlink:href': '#' + id })
|
|
||||||
} else {
|
|
||||||
return SnapElement.prototype.use.call(this)
|
|
||||||
}
|
}
|
||||||
|
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)
|
return this.el('symbol', attr)
|
||||||
}
|
}
|
||||||
/*\
|
/***
|
||||||
**
|
* Draws a text string
|
||||||
* Draws a text string
|
**
|
||||||
**
|
- x (number) x coordinate position
|
||||||
- x (number) x coordinate position
|
- y (number) y 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
|
||||||
- text (string|array) The text string to draw or array of strings to nest within separate `<tspan>` elements
|
= (object) the `text` element
|
||||||
= (object) the `text` element
|
**
|
||||||
**
|
> Usage
|
||||||
> Usage
|
let t1 = paper.text(50, 50, "Snap");
|
||||||
| let t1 = paper.text(50, 50, "Snap");
|
let t2 = paper.text(50, 50, ["S","n","a","p"]);
|
||||||
| let t2 = paper.text(50, 50, ["S","n","a","p"]);
|
// Text path usage
|
||||||
| // Text path usage
|
t1.attr({textpath: "M10,10L100,100"});
|
||||||
| t1.attr({textpath: "M10,10L100,100"});
|
// or
|
||||||
| // or
|
let pth = paper.path("M10,10L100,100");
|
||||||
| let pth = paper.path("M10,10L100,100");
|
t1.attr({textpath: pth});
|
||||||
| t1.attr({textpath: pth});
|
*/
|
||||||
\*/
|
|
||||||
text(x = 0, y = 0, text = '') {
|
text(x = 0, y = 0, text = '') {
|
||||||
return this.el('text', { x, y }, text)
|
return this.el('text', { x, y }, text)
|
||||||
}
|
}
|
||||||
/*\
|
/***
|
||||||
**
|
* Draws a line
|
||||||
* Draws a line
|
**
|
||||||
**
|
- x1 (number) x coordinate position of the start
|
||||||
- x1 (number) x coordinate position of the start
|
- y1 (number) y coordinate position of the start
|
||||||
- y1 (number) y coordinate position of the start
|
- x2 (number) x coordinate position of the end
|
||||||
- x2 (number) x coordinate position of the end
|
- y2 (number) y coordinate position of the end
|
||||||
- y2 (number) y coordinate position of the end
|
= (object) the `line` element
|
||||||
= (object) the `line` element
|
**
|
||||||
**
|
> Usage
|
||||||
> Usage
|
let t1 = paper.line(50, 50, 100, 100);
|
||||||
| let t1 = paper.line(50, 50, 100, 100);
|
*/
|
||||||
\*/
|
|
||||||
line(x1, y1, x2, y2) {
|
line(x1, y1, x2, y2) {
|
||||||
let attr = {}
|
let attr = {}
|
||||||
if (is(x1, 'object')) {
|
if (is(x1, 'object')) {
|
||||||
|
@ -1108,7 +1027,7 @@ export class Paper {
|
||||||
if (arguments.length == 1 && first && !first.type) {
|
if (arguments.length == 1 && first && !first.type) {
|
||||||
el.attr(first)
|
el.attr(first)
|
||||||
} else if (arguments.length) {
|
} else if (arguments.length) {
|
||||||
el.add(Array.from(arguments))
|
el.add(...Array.from(arguments))
|
||||||
}
|
}
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
@ -1179,9 +1098,6 @@ export class Paper {
|
||||||
|
|
||||||
export class SnapElement {
|
export class SnapElement {
|
||||||
constructor(el) {
|
constructor(el) {
|
||||||
if (el.snap in hub) {
|
|
||||||
return hub[el.snap]
|
|
||||||
}
|
|
||||||
let svg
|
let svg
|
||||||
try {
|
try {
|
||||||
svg = el.ownerSVGElement
|
svg = el.ownerSVGElement
|
||||||
|
@ -1210,7 +1126,7 @@ export class SnapElement {
|
||||||
transform: []
|
transform: []
|
||||||
}
|
}
|
||||||
el.snap = id
|
el.snap = id
|
||||||
hub[id] = this
|
|
||||||
if (this.type == 'g') {
|
if (this.type == 'g') {
|
||||||
this.add = add2group
|
this.add = add2group
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,8 @@ export function h(el, props = null, children) {
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.h = h
|
||||||
|
|
||||||
export function clone(obj) {
|
export function clone(obj) {
|
||||||
if (typeof obj == 'function' || Object(obj) !== obj) {
|
if (typeof obj == 'function' || Object(obj) !== obj) {
|
||||||
return obj
|
return obj
|
||||||
|
|
Loading…
Reference in New Issue