精简优化attr逻辑
parent
ca02ac252b
commit
994cb7e010
|
@ -277,6 +277,7 @@ eve.on('snap.util.attr.textpath', function (value) {
|
|||
}
|
||||
}
|
||||
})(-1)
|
||||
|
||||
eve.on('snap.util.attr.text', function (value) {
|
||||
if (this.type == 'text') {
|
||||
let i = 0,
|
||||
|
@ -303,6 +304,7 @@ eve.on('snap.util.attr.text', function (value) {
|
|||
}
|
||||
eve.stop()
|
||||
})(-1)
|
||||
|
||||
function setFontSize(value) {
|
||||
eve.stop()
|
||||
if (value == +value) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
*
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2021/05/30 11:43:54
|
||||
*/
|
||||
|
||||
export class EventEmitter {
|
||||
//
|
||||
__events__ = Object.create(null)
|
||||
|
||||
$on(name, fn) {
|
||||
if (this.__events__[name]) {
|
||||
this.__events__[name].push(fn)
|
||||
} else {
|
||||
this.__events__[name] = [fn]
|
||||
}
|
||||
}
|
||||
|
||||
$once(name, fn) {
|
||||
function fn1(...args) {
|
||||
fn(...args)
|
||||
}
|
||||
if (this.__events__[name]) {
|
||||
this.__events__[name].push(fn)
|
||||
} else {
|
||||
this.__events__[name] = [fn]
|
||||
}
|
||||
}
|
||||
|
||||
$off(name, fn) {
|
||||
if (this.__events__[name]) {
|
||||
if (fn) {
|
||||
this.__events__[name] = this.__events__[name].filter(it => it !== fn)
|
||||
} else {
|
||||
this.__events__[name] = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$emit(name, ...args) {
|
||||
if (this.__events__[name]) {
|
||||
for (let fn of this.__events__[name]) {
|
||||
try {
|
||||
fn.apply(this, args)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$destroy() {
|
||||
this.__events__ = Object.create(null)
|
||||
}
|
||||
}
|
173
src/svg.js
173
src/svg.js
|
@ -4,8 +4,6 @@
|
|||
* @date 2024/03/08 10:59:09
|
||||
*/
|
||||
|
||||
import eve from './eve.js'
|
||||
|
||||
import {
|
||||
doc,
|
||||
win,
|
||||
|
@ -18,7 +16,7 @@ import {
|
|||
import { Matrix } from './matrix.js'
|
||||
|
||||
import {
|
||||
$,
|
||||
h,
|
||||
is,
|
||||
uuid,
|
||||
clone,
|
||||
|
@ -36,11 +34,10 @@ let has = 'hasOwnProperty',
|
|||
objectToString = Object.prototype.toString,
|
||||
hub = {}
|
||||
|
||||
export function make(name, parent) {
|
||||
let res = $(name)
|
||||
parent.appendChild(res)
|
||||
let el = wrap(res)
|
||||
return el
|
||||
export function make(name, parent = doc.body, attr, children) {
|
||||
let el = h(name, attr, children)
|
||||
parent.appendChild(el)
|
||||
return wrap(el)
|
||||
}
|
||||
|
||||
export function wrap(dom) {
|
||||
|
@ -96,7 +93,7 @@ export class Fragment {
|
|||
}
|
||||
|
||||
export class Snap {
|
||||
static _ = { $ }
|
||||
static _ = {}
|
||||
|
||||
/*
|
||||
**
|
||||
|
@ -294,7 +291,7 @@ export class Snap {
|
|||
}
|
||||
if (h == null) {
|
||||
try {
|
||||
w = doc.querySelector(String(w))
|
||||
w = doc.querySelector(w)
|
||||
return wrap(w)
|
||||
} catch (e) {
|
||||
return null
|
||||
|
@ -536,8 +533,7 @@ export function unit2px(el, name, value) {
|
|||
out = {},
|
||||
mgr = svg.querySelector('.svg---mgr')
|
||||
if (!mgr) {
|
||||
mgr = $('rect')
|
||||
$(mgr, {
|
||||
mgr = h('rect', {
|
||||
x: -9e9,
|
||||
y: -9e9,
|
||||
width: 10,
|
||||
|
@ -554,7 +550,7 @@ export function unit2px(el, name, value) {
|
|||
if (val == +val) {
|
||||
return val
|
||||
}
|
||||
$(mgr, { width: val })
|
||||
h(mgr, { width: val })
|
||||
try {
|
||||
return mgr.getBBox().width
|
||||
} catch (e) {
|
||||
|
@ -568,7 +564,7 @@ export function unit2px(el, name, value) {
|
|||
if (val == +val) {
|
||||
return val
|
||||
}
|
||||
$(mgr, { height: val })
|
||||
h(mgr, { height: val })
|
||||
try {
|
||||
return mgr.getBBox().height
|
||||
} catch (e) {
|
||||
|
@ -672,23 +668,25 @@ setInterval(function () {
|
|||
}, 1e4)
|
||||
|
||||
export class Paper {
|
||||
constructor(w, h) {
|
||||
let res, desc, defs
|
||||
if (w && w.tagName && w.tagName.toLowerCase() == 'svg') {
|
||||
if (w.snap in hub) {
|
||||
return hub[w.snap]
|
||||
constructor(width, height) {
|
||||
let dom, res, desc, defs
|
||||
if (width && width.nodeType) {
|
||||
dom = width
|
||||
}
|
||||
if (dom) {
|
||||
if (dom.snap in hub) {
|
||||
return hub[dom.snap]
|
||||
}
|
||||
let doc = w.ownerDocument
|
||||
res = new SnapElement(w)
|
||||
desc = w.getElementsByTagName('desc')[0]
|
||||
defs = w.getElementsByTagName('defs')[0]
|
||||
let doc = dom.ownerDocument
|
||||
res = new SnapElement(dom)
|
||||
desc = dom.querySelector('desc')
|
||||
defs = dom.querySelector('defs')
|
||||
if (!desc) {
|
||||
desc = $('desc')
|
||||
desc.appendChild(doc.createTextNode('Created with Snap'))
|
||||
desc = h('desc', null, 'Created with @bytedo/snapsvg')
|
||||
res.node.appendChild(desc)
|
||||
}
|
||||
if (!defs) {
|
||||
defs = $('defs')
|
||||
defs = h('defs')
|
||||
res.node.appendChild(defs)
|
||||
}
|
||||
res.defs = defs
|
||||
|
@ -696,9 +694,9 @@ export class Paper {
|
|||
res.paper = res.root = res
|
||||
} else {
|
||||
res = make('svg', doc.body)
|
||||
$(res.node, {
|
||||
width: w,
|
||||
height: h,
|
||||
h(res.node, {
|
||||
width,
|
||||
height,
|
||||
version: 1.1,
|
||||
xmlns
|
||||
})
|
||||
|
@ -858,18 +856,8 @@ export class Paper {
|
|||
| let pth = paper.path("M10,10L100,100");
|
||||
| t1.attr({textpath: pth});
|
||||
\*/
|
||||
text(x, y, text) {
|
||||
let attr = {}
|
||||
if (is(x, 'object')) {
|
||||
attr = x
|
||||
} else if (x != null) {
|
||||
attr = {
|
||||
x: x,
|
||||
y: y,
|
||||
text: text || ''
|
||||
}
|
||||
}
|
||||
return this.el('text', attr)
|
||||
text(x = 0, y = 0, text = '') {
|
||||
return this.el('text', { x, y }, text)
|
||||
}
|
||||
/*\
|
||||
**
|
||||
|
@ -961,10 +949,8 @@ export class Paper {
|
|||
| r: 10
|
||||
| });
|
||||
*/
|
||||
el(name, attr) {
|
||||
let el = make(name, this.node)
|
||||
attr && el.attr(attr)
|
||||
return el
|
||||
el(name, attr, children) {
|
||||
return make(name, this.node, attr, children)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1067,13 +1053,13 @@ export class Paper {
|
|||
set.height = height
|
||||
} else {
|
||||
preload(src, function () {
|
||||
$(el.node, {
|
||||
h(el.node, {
|
||||
width: this.offsetWidth,
|
||||
height: this.offsetHeight
|
||||
})
|
||||
})
|
||||
}
|
||||
$(el.node, set)
|
||||
h(el.node, set)
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
@ -1145,15 +1131,14 @@ export class Paper {
|
|||
if (paper.type !== 'svg') {
|
||||
paper = paper.paper
|
||||
}
|
||||
let f = Snap.parse(String(filstr)),
|
||||
let f = Snap.parse(filstr),
|
||||
id = uuid((this.type || '') + 'S'),
|
||||
width = paper.node.offsetWidth,
|
||||
height = paper.node.offsetHeight,
|
||||
filter = $('filter')
|
||||
$(filter, {
|
||||
id: id,
|
||||
filterUnits: 'userSpaceOnUse'
|
||||
})
|
||||
filter = h('filter', {
|
||||
id,
|
||||
filterUnits: 'userSpaceOnUse'
|
||||
})
|
||||
filter.appendChild(f.node)
|
||||
paper.defs.appendChild(filter)
|
||||
return new SnapElement(filter)
|
||||
|
@ -1167,7 +1152,7 @@ export class Paper {
|
|||
res
|
||||
f.appendChild(d)
|
||||
d.appendChild(svg)
|
||||
$(svg, { xmlns: 'http://www.w3.org/2000/svg' })
|
||||
h(svg, { xmlns: 'http://www.w3.org/2000/svg' })
|
||||
res = d.innerHTML
|
||||
return res
|
||||
}
|
||||
|
@ -1215,12 +1200,9 @@ export class SnapElement {
|
|||
if (svg) {
|
||||
this.paper = new Paper(svg)
|
||||
}
|
||||
/*\
|
||||
* SnapElement.type
|
||||
[ property (string) ]
|
||||
**
|
||||
/**
|
||||
* SVG tag name of the given element.
|
||||
\*/
|
||||
*/
|
||||
this.type = el.tagName || el.nodeName
|
||||
let id = (this.id = uuid((this.type || '') + 'S'))
|
||||
this.anims = {}
|
||||
|
@ -1260,34 +1242,28 @@ export class SnapElement {
|
|||
* (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+`
|
||||
* and `-`: `"+=2em"`.
|
||||
*/
|
||||
attr(params, value) {
|
||||
attr(key, value) {
|
||||
let node = this.node
|
||||
let out = {}
|
||||
|
||||
if (!params) {
|
||||
if (node.nodeType != 1) {
|
||||
return {
|
||||
text: node.nodeValue
|
||||
if (key) {
|
||||
if (is(key, 'string')) {
|
||||
if (value === void 0) {
|
||||
return node.getAttribute(key)
|
||||
} else {
|
||||
key = { [key]: value }
|
||||
}
|
||||
}
|
||||
let attr = node.attributes,
|
||||
out = {}
|
||||
for (let i = 0, ii = attr.length; i < ii; i++) {
|
||||
out[attr[i].nodeName] = attr[i].nodeValue
|
||||
}
|
||||
h(node, key)
|
||||
|
||||
return out
|
||||
return this
|
||||
}
|
||||
if (is(params, 'string')) {
|
||||
if (value !== void 0) {
|
||||
params = { [params]: value }
|
||||
} else {
|
||||
return eve('snap.util.getattr.' + params, this).firstDefined()
|
||||
}
|
||||
|
||||
for (let it of Array.from(node.attributes)) {
|
||||
out[it.nodeName] = it.nodeValue
|
||||
}
|
||||
for (let att in params) {
|
||||
eve('snap.util.attr.' + att, this, params[att])
|
||||
}
|
||||
return this
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1296,12 +1272,7 @@ export class SnapElement {
|
|||
= (array) array of Elements
|
||||
*/
|
||||
children() {
|
||||
let out = [],
|
||||
ch = this.node.childNodes
|
||||
for (let i = 0, ii = ch.length; i < ii; i++) {
|
||||
out[i] = new Snap(ch[i])
|
||||
}
|
||||
return out
|
||||
return Array.from(this.node.childNodes).map(n => new Snap(n))
|
||||
}
|
||||
|
||||
/*\
|
||||
|
@ -1321,7 +1292,7 @@ export class SnapElement {
|
|||
}
|
||||
|
||||
equal(name, b) {
|
||||
return eve('snap.util.equal', this, name, b).firstDefined()
|
||||
// return eve('snap.util.equal', this, name, b).firstDefined()
|
||||
}
|
||||
|
||||
addClass(value) {
|
||||
|
@ -1385,31 +1356,3 @@ export class SnapElement {
|
|||
return this.transform('' + this.getAlign(way))
|
||||
}
|
||||
}
|
||||
|
||||
// default
|
||||
eve.on('snap.util.getattr', function () {
|
||||
let key = eve.nt().split('.').at(-1)
|
||||
let css = key.replace(/[A-Z]/g, function (letter) {
|
||||
return '-' + letter.toLowerCase()
|
||||
})
|
||||
if (CSS_ATTR[css]) {
|
||||
return this.node.ownerDocument.defaultView
|
||||
.getComputedStyle(this.node, null)
|
||||
.getPropertyValue(css)
|
||||
} else {
|
||||
return $(this.node, key)
|
||||
}
|
||||
})
|
||||
|
||||
eve.on('snap.util.attr', function (value) {
|
||||
let key = eve.nt().split('.').at(-1)
|
||||
|
||||
let css = key.replace(/[A-Z]/g, function (letter) {
|
||||
return '-' + letter.toLowerCase()
|
||||
})
|
||||
if (CSS_ATTR[css]) {
|
||||
this.node.style[css] = value == null ? E : value
|
||||
} else {
|
||||
$(this.node, { [css]: value })
|
||||
}
|
||||
})
|
||||
|
|
69
src/utils.js
69
src/utils.js
|
@ -10,6 +10,20 @@ export function uuid(prefix = '') {
|
|||
return prefix + Math.random().toString(16).slice(-8)
|
||||
}
|
||||
|
||||
//驼峰转换为连字符线风格
|
||||
export function hyphen(target) {
|
||||
return target.replace(/([a-z\d])([A-Z]+)/g, '$1-$2').toLowerCase()
|
||||
}
|
||||
|
||||
//连字符转换为驼峰风格
|
||||
export function camelize(target) {
|
||||
//提前判断,提高效率
|
||||
if (target.indexOf('-') < 0) {
|
||||
return target
|
||||
}
|
||||
return target.replace(/\-([a-z])/g, (m, s) => s.toUpperCase())
|
||||
}
|
||||
|
||||
export function is(o, type) {
|
||||
type = String(type).toLowerCase()
|
||||
let _type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase()
|
||||
|
@ -54,21 +68,7 @@ export function $(el, attr) {
|
|||
}
|
||||
}
|
||||
if (el.nodeType == 1) {
|
||||
for (let key in attr)
|
||||
if (attr.hasOwnProperty(key)) {
|
||||
let val = String(attr[key])
|
||||
if (val) {
|
||||
if (key.slice(0, 6) == 'xlink:') {
|
||||
el.setAttributeNS(xlink, key.slice(6), val)
|
||||
} else if (key.slice(0, 4) == 'xml:') {
|
||||
el.setAttributeNS(xmlns, key.slice(4), val)
|
||||
} else {
|
||||
el.setAttribute(key, val)
|
||||
}
|
||||
} else {
|
||||
el.removeAttribute(key)
|
||||
}
|
||||
}
|
||||
h(el, attr)
|
||||
} else if ('text' in attr) {
|
||||
el.nodeValue = attr.text
|
||||
}
|
||||
|
@ -78,6 +78,45 @@ export function $(el, attr) {
|
|||
return el
|
||||
}
|
||||
|
||||
export function h(el, props = null, children) {
|
||||
if (typeof el === 'string') {
|
||||
el = doc.createElementNS(xmlns, el)
|
||||
}
|
||||
|
||||
if (props) {
|
||||
for (let key in props) {
|
||||
let val = props[key]
|
||||
key = hyphen(key)
|
||||
if (val === null) {
|
||||
el.removeAttribute(key)
|
||||
} else {
|
||||
if (key.slice(0, 6) == 'xlink:') {
|
||||
el.setAttributeNS(xlink, key.slice(6), val)
|
||||
} else if (key.slice(0, 4) == 'xml:') {
|
||||
el.setAttributeNS(xmlns, key.slice(4), val)
|
||||
} else {
|
||||
el.setAttribute(key, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (children) {
|
||||
if (Array.isArray(children)) {
|
||||
let f = doc.createDocumentFragment()
|
||||
for (let it of children) {
|
||||
f.appendChild(h('tspan', null, it))
|
||||
}
|
||||
el.appendChild(f)
|
||||
} else {
|
||||
el.appendChild(doc.createTextNode(children))
|
||||
}
|
||||
|
||||
el.normalize()
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
export function clone(obj) {
|
||||
if (typeof obj == 'function' || Object(obj) !== obj) {
|
||||
return obj
|
||||
|
|
Loading…
Reference in New Issue