snapsvg/src/utils.js

196 lines
4.5 KiB
JavaScript

/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2024/03/06 09:55:31
*/
import { xlink, xmlns, doc, win } from './lib/constants.js'
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()
if (type === 'finite') {
return isFinite(o)
}
if (type === 'array' && Array.isArray(o)) {
return true
}
return (
(type === 'null' && o === null) ||
(type === typeof o && o !== null) ||
(type === 'object' && o === Object(o)) ||
_type === type
)
}
export function $(el, attr) {
if (attr) {
if (el === '#text') {
el = doc.createTextNode(attr.text || attr['#text'] || '')
}
if (el === '#comment') {
el = doc.createComment(attr.text || attr['#text'] || '')
}
if (typeof el === 'string') {
el = $(el)
}
if (typeof attr === 'string') {
if (el.nodeType === 1) {
if (attr.slice(0, 6) === 'xlink:') {
return el.getAttributeNS(xlink, attr.slice(6))
}
if (attr.slice(0, 4) === 'xml:') {
return el.getAttributeNS(xmlns, attr.slice(4))
}
return el.getAttribute(attr)
} else if (attr == 'text') {
return el.nodeValue
} else {
return null
}
}
if (el.nodeType == 1) {
h(el, attr)
} else if ('text' in attr) {
el.nodeValue = attr.text
}
} else {
el = doc.createElementNS(xmlns, 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
}
window.h = h
export function clone(obj) {
if (typeof obj == 'function' || Object(obj) !== obj) {
return obj
}
let res = new obj.constructor()
for (let key in obj)
if (obj.hasOwnProperty(key)) {
res[key] = clone(obj[key])
}
return res
}
export function preload(src, f) {
let img = new Image()
img.onload = function () {
f.call(img)
}
img.src = src
}
function repush(arr, item) {
let l = arr.length - 1 // 要减1, 最后如果本身在最后, 不用变
for (let i = 0; i < l; i++) {
if (arr[i] === item) {
;[arr[i], arr[l]] = [arr[l], arr[i]]
break
}
}
}
export function cacher(fn, scope, postprocessor) {
function newf(...args) {
let key = args.join('\u2400'),
cache = (newf.cache = newf.cache || {}),
count = (newf.count = newf.count || [])
if (cache.hasOwnProperty(key)) {
repush(count, key)
return postprocessor ? postprocessor(cache[key]) : cache[key]
}
count.length >= 1e3 && delete cache[count.shift()]
count.push(key)
cache[key] = fn.apply(scope, args)
return postprocessor ? postprocessor(cache[key]) : cache[key]
}
return newf
}
export function jsonFiller(root, o) {
for (let i = 0, ii = root.length; i < ii; i++) {
let item = {
type: root[i].type,
attr: root[i].attr()
},
children = root[i].children()
o.push(item)
if (children.length) {
jsonFiller(children, (item.childNodes = []))
}
}
}
export function extend(origin, target) {
let methods = Object.getOwnPropertyNames(target).filter(
n => n !== 'constructor'
)
for (let k of methods) {
Object.defineProperty(origin, k, { value: target[k] })
}
}
export function url(id) {
return "url('#" + id + "')"
}
JavaScript 100%