精简优化attr逻辑

master
yutent 2024-03-14 12:55:46 +08:00
parent ca02ac252b
commit 994cb7e010
4 changed files with 169 additions and 130 deletions

View File

@ -277,6 +277,7 @@ eve.on('snap.util.attr.textpath', function (value) {
} }
} }
})(-1) })(-1)
eve.on('snap.util.attr.text', function (value) { eve.on('snap.util.attr.text', function (value) {
if (this.type == 'text') { if (this.type == 'text') {
let i = 0, let i = 0,
@ -303,6 +304,7 @@ eve.on('snap.util.attr.text', function (value) {
} }
eve.stop() eve.stop()
})(-1) })(-1)
function setFontSize(value) { function setFontSize(value) {
eve.stop() eve.stop()
if (value == +value) { if (value == +value) {

55
src/emitter.js Normal file
View File

@ -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)
}
}

View File

@ -4,8 +4,6 @@
* @date 2024/03/08 10:59:09 * @date 2024/03/08 10:59:09
*/ */
import eve from './eve.js'
import { import {
doc, doc,
win, win,
@ -18,7 +16,7 @@ import {
import { Matrix } from './matrix.js' import { Matrix } from './matrix.js'
import { import {
$, h,
is, is,
uuid, uuid,
clone, clone,
@ -36,11 +34,10 @@ let has = 'hasOwnProperty',
objectToString = Object.prototype.toString, objectToString = Object.prototype.toString,
hub = {} hub = {}
export function make(name, parent) { export function make(name, parent = doc.body, attr, children) {
let res = $(name) let el = h(name, attr, children)
parent.appendChild(res) parent.appendChild(el)
let el = wrap(res) return wrap(el)
return el
} }
export function wrap(dom) { export function wrap(dom) {
@ -96,7 +93,7 @@ export class Fragment {
} }
export class Snap { export class Snap {
static _ = { $ } static _ = {}
/* /*
** **
@ -294,7 +291,7 @@ export class Snap {
} }
if (h == null) { if (h == null) {
try { try {
w = doc.querySelector(String(w)) w = doc.querySelector(w)
return wrap(w) return wrap(w)
} catch (e) { } catch (e) {
return null return null
@ -536,8 +533,7 @@ export function unit2px(el, name, value) {
out = {}, out = {},
mgr = svg.querySelector('.svg---mgr') mgr = svg.querySelector('.svg---mgr')
if (!mgr) { if (!mgr) {
mgr = $('rect') mgr = h('rect', {
$(mgr, {
x: -9e9, x: -9e9,
y: -9e9, y: -9e9,
width: 10, width: 10,
@ -554,7 +550,7 @@ export function unit2px(el, name, value) {
if (val == +val) { if (val == +val) {
return val return val
} }
$(mgr, { width: val }) h(mgr, { width: val })
try { try {
return mgr.getBBox().width return mgr.getBBox().width
} catch (e) { } catch (e) {
@ -568,7 +564,7 @@ export function unit2px(el, name, value) {
if (val == +val) { if (val == +val) {
return val return val
} }
$(mgr, { height: val }) h(mgr, { height: val })
try { try {
return mgr.getBBox().height return mgr.getBBox().height
} catch (e) { } catch (e) {
@ -672,23 +668,25 @@ setInterval(function () {
}, 1e4) }, 1e4)
export class Paper { export class Paper {
constructor(w, h) { constructor(width, height) {
let res, desc, defs let dom, res, desc, defs
if (w && w.tagName && w.tagName.toLowerCase() == 'svg') { if (width && width.nodeType) {
if (w.snap in hub) { dom = width
return hub[w.snap] }
if (dom) {
if (dom.snap in hub) {
return hub[dom.snap]
} }
let doc = w.ownerDocument let doc = dom.ownerDocument
res = new SnapElement(w) res = new SnapElement(dom)
desc = w.getElementsByTagName('desc')[0] desc = dom.querySelector('desc')
defs = w.getElementsByTagName('defs')[0] defs = dom.querySelector('defs')
if (!desc) { if (!desc) {
desc = $('desc') desc = h('desc', null, 'Created with @bytedo/snapsvg')
desc.appendChild(doc.createTextNode('Created with Snap'))
res.node.appendChild(desc) res.node.appendChild(desc)
} }
if (!defs) { if (!defs) {
defs = $('defs') defs = h('defs')
res.node.appendChild(defs) res.node.appendChild(defs)
} }
res.defs = defs res.defs = defs
@ -696,9 +694,9 @@ export class Paper {
res.paper = res.root = res res.paper = res.root = res
} else { } else {
res = make('svg', doc.body) res = make('svg', doc.body)
$(res.node, { h(res.node, {
width: w, width,
height: h, height,
version: 1.1, version: 1.1,
xmlns xmlns
}) })
@ -858,18 +856,8 @@ export class Paper {
| let pth = paper.path("M10,10L100,100"); | let pth = paper.path("M10,10L100,100");
| t1.attr({textpath: pth}); | t1.attr({textpath: pth});
\*/ \*/
text(x, y, text) { text(x = 0, y = 0, text = '') {
let attr = {} return this.el('text', { x, y }, text)
if (is(x, 'object')) {
attr = x
} else if (x != null) {
attr = {
x: x,
y: y,
text: text || ''
}
}
return this.el('text', attr)
} }
/*\ /*\
** **
@ -961,10 +949,8 @@ export class Paper {
| r: 10 | r: 10
| }); | });
*/ */
el(name, attr) { el(name, attr, children) {
let el = make(name, this.node) return make(name, this.node, attr, children)
attr && el.attr(attr)
return el
} }
/* /*
@ -1067,13 +1053,13 @@ export class Paper {
set.height = height set.height = height
} else { } else {
preload(src, function () { preload(src, function () {
$(el.node, { h(el.node, {
width: this.offsetWidth, width: this.offsetWidth,
height: this.offsetHeight height: this.offsetHeight
}) })
}) })
} }
$(el.node, set) h(el.node, set)
} }
return el return el
} }
@ -1145,15 +1131,14 @@ export class Paper {
if (paper.type !== 'svg') { if (paper.type !== 'svg') {
paper = paper.paper paper = paper.paper
} }
let f = Snap.parse(String(filstr)), let f = Snap.parse(filstr),
id = uuid((this.type || '') + 'S'), id = uuid((this.type || '') + 'S'),
width = paper.node.offsetWidth, width = paper.node.offsetWidth,
height = paper.node.offsetHeight, height = paper.node.offsetHeight,
filter = $('filter') filter = h('filter', {
$(filter, { id,
id: id, filterUnits: 'userSpaceOnUse'
filterUnits: 'userSpaceOnUse' })
})
filter.appendChild(f.node) filter.appendChild(f.node)
paper.defs.appendChild(filter) paper.defs.appendChild(filter)
return new SnapElement(filter) return new SnapElement(filter)
@ -1167,7 +1152,7 @@ export class Paper {
res res
f.appendChild(d) f.appendChild(d)
d.appendChild(svg) d.appendChild(svg)
$(svg, { xmlns: 'http://www.w3.org/2000/svg' }) h(svg, { xmlns: 'http://www.w3.org/2000/svg' })
res = d.innerHTML res = d.innerHTML
return res return res
} }
@ -1215,12 +1200,9 @@ export class SnapElement {
if (svg) { if (svg) {
this.paper = new Paper(svg) this.paper = new Paper(svg)
} }
/*\ /**
* SnapElement.type
[ property (string) ]
**
* SVG tag name of the given element. * SVG tag name of the given element.
\*/ */
this.type = el.tagName || el.nodeName this.type = el.tagName || el.nodeName
let id = (this.id = uuid((this.type || '') + 'S')) let id = (this.id = uuid((this.type || '') + 'S'))
this.anims = {} this.anims = {}
@ -1260,34 +1242,28 @@ export class SnapElement {
* (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+` * (`+`, `-`, `*` and `/`) could be used. Optionally you can use units for `+`
* and `-`: `"+=2em"`. * and `-`: `"+=2em"`.
*/ */
attr(params, value) { attr(key, value) {
let node = this.node let node = this.node
let out = {}
if (!params) { if (key) {
if (node.nodeType != 1) { if (is(key, 'string')) {
return { if (value === void 0) {
text: node.nodeValue return node.getAttribute(key)
} else {
key = { [key]: value }
} }
} }
let attr = node.attributes, h(node, key)
out = {}
for (let i = 0, ii = attr.length; i < ii; i++) {
out[attr[i].nodeName] = attr[i].nodeValue
}
return out return this
} }
if (is(params, 'string')) {
if (value !== void 0) { for (let it of Array.from(node.attributes)) {
params = { [params]: value } out[it.nodeName] = it.nodeValue
} else {
return eve('snap.util.getattr.' + params, this).firstDefined()
}
} }
for (let att in params) {
eve('snap.util.attr.' + att, this, params[att]) return out
}
return this
} }
/* /*
@ -1296,12 +1272,7 @@ export class SnapElement {
= (array) array of Elements = (array) array of Elements
*/ */
children() { children() {
let out = [], return Array.from(this.node.childNodes).map(n => new Snap(n))
ch = this.node.childNodes
for (let i = 0, ii = ch.length; i < ii; i++) {
out[i] = new Snap(ch[i])
}
return out
} }
/*\ /*\
@ -1321,7 +1292,7 @@ export class SnapElement {
} }
equal(name, b) { equal(name, b) {
return eve('snap.util.equal', this, name, b).firstDefined() // return eve('snap.util.equal', this, name, b).firstDefined()
} }
addClass(value) { addClass(value) {
@ -1385,31 +1356,3 @@ export class SnapElement {
return this.transform('' + this.getAlign(way)) 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 })
}
})

View File

@ -10,6 +10,20 @@ export function uuid(prefix = '') {
return prefix + Math.random().toString(16).slice(-8) 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) { export function is(o, type) {
type = String(type).toLowerCase() type = String(type).toLowerCase()
let _type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase() let _type = Object.prototype.toString.call(o).slice(8, -1).toLowerCase()
@ -54,21 +68,7 @@ export function $(el, attr) {
} }
} }
if (el.nodeType == 1) { if (el.nodeType == 1) {
for (let key in attr) h(el, 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)
}
}
} else if ('text' in attr) { } else if ('text' in attr) {
el.nodeValue = attr.text el.nodeValue = attr.text
} }
@ -78,6 +78,45 @@ export function $(el, attr) {
return el 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) { export function clone(obj) {
if (typeof obj == 'function' || Object(obj) !== obj) { if (typeof obj == 'function' || Object(obj) !== obj) {
return obj return obj