精简优化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)
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) {

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
*/
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 })
}
})

View File

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