update
parent
d6344dde16
commit
00889573db
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2024/03/26 10:37:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { $, h } from './utils.js'
|
||||||
|
|
||||||
|
export class Component {
|
||||||
|
#node
|
||||||
|
type = null
|
||||||
|
|
||||||
|
constructor(el) {
|
||||||
|
this.#node = el
|
||||||
|
this.type = el.tagName.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
get node() {
|
||||||
|
return this.#node
|
||||||
|
}
|
||||||
|
|
||||||
|
get textContent() {
|
||||||
|
return this.#node.textContent
|
||||||
|
}
|
||||||
|
|
||||||
|
set textContent(val) {
|
||||||
|
this.#node.textContent = val
|
||||||
|
}
|
||||||
|
|
||||||
|
#create(name, attr, child) {
|
||||||
|
let node = h(name, attr, child)
|
||||||
|
this.#node.appendChild(node)
|
||||||
|
return new Component(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
append(...elems) {
|
||||||
|
for (let el of elems) {
|
||||||
|
this.#node.appendChild(el instanceof Component ? el.node : el)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
select(selector) {
|
||||||
|
let node = $(selector, this.#node)
|
||||||
|
if (node) {
|
||||||
|
return new Component(node)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
attr(key, val) {
|
||||||
|
let node = this.node
|
||||||
|
let out = {}
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
if (typeof key === 'string') {
|
||||||
|
if (val === void 0) {
|
||||||
|
return node.getAttribute(key)
|
||||||
|
} else {
|
||||||
|
key = { [key]: val }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h(node, key)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无任何参数时, 返回节点所有的属性
|
||||||
|
for (let it of Array.from(node.attributes)) {
|
||||||
|
out[it.nodeName] = it.nodeValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
g(...args) {
|
||||||
|
let el = this.#create('g')
|
||||||
|
if (args.length) {
|
||||||
|
el.append(...args)
|
||||||
|
}
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
style(content) {
|
||||||
|
let node = this.select('style')
|
||||||
|
if (node === null) {
|
||||||
|
node = this.#create('style')
|
||||||
|
}
|
||||||
|
node.textContent += content
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
rect(x, y, width, height) {
|
||||||
|
return this.#create('rect', { x, y, width, height })
|
||||||
|
}
|
||||||
|
|
||||||
|
text(x = 0, y = 0, text = '') {
|
||||||
|
return this.#create('text', { x, y }, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用foreignObject实现文本自动换行等排版
|
||||||
|
autoText(x = 0, y = 0, width, height, text = '') {
|
||||||
|
return this.#create('foreignObject', { x, y, width, height }, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
path(d) {
|
||||||
|
return this.#create('path', { d })
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2024/03/26 10:07:25
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { $, h, type } from './utils.js'
|
||||||
|
import { xmlns, doc, win } from './lib/constants.js'
|
||||||
|
|
||||||
|
import { Component } from './elem.js'
|
||||||
|
|
||||||
|
export function createSvg(el) {
|
||||||
|
if (el) {
|
||||||
|
if (type(el) === 'string') {
|
||||||
|
el = $(el)
|
||||||
|
}
|
||||||
|
h(el, { xmlns })
|
||||||
|
} else {
|
||||||
|
el = h('svg', { xmlns })
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Component(el)
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* {颜色格式转换}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2024/03/26 10:07:01
|
||||||
|
*/
|
||||||
|
|
||||||
|
// H: 色相, S: 饱和度, B/V: 亮度
|
||||||
|
export function hsb2rgb(hsb) {
|
||||||
|
let h = hsb.h
|
||||||
|
let s = Math.round((hsb.s * 255) / 100)
|
||||||
|
let v = Math.round((hsb.b * 255) / 100)
|
||||||
|
let r = 0
|
||||||
|
let g = 0
|
||||||
|
let b = 0
|
||||||
|
|
||||||
|
if (s === 0) {
|
||||||
|
r = g = b = v
|
||||||
|
} else {
|
||||||
|
let t1 = v
|
||||||
|
let t2 = ((255 - s) * v) / 255
|
||||||
|
let t3 = ((t1 - t2) * (h % 60)) / 60
|
||||||
|
|
||||||
|
//
|
||||||
|
if (h === 360) {
|
||||||
|
h = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h < 60) {
|
||||||
|
r = t1
|
||||||
|
g = t2 + t3
|
||||||
|
b = t2
|
||||||
|
} else if (h < 120) {
|
||||||
|
r = t1 - t3
|
||||||
|
g = t1
|
||||||
|
b = t2
|
||||||
|
} else if (h < 180) {
|
||||||
|
r = t2
|
||||||
|
g = t1
|
||||||
|
b = t2 + t3
|
||||||
|
} else if (h < 240) {
|
||||||
|
r = t2
|
||||||
|
g = t1 - t3
|
||||||
|
b = t1
|
||||||
|
} else if (h < 300) {
|
||||||
|
r = t2 + t3
|
||||||
|
g = t2
|
||||||
|
b = t1
|
||||||
|
} else if (h < 360) {
|
||||||
|
r = t1
|
||||||
|
g = t2
|
||||||
|
b = t1 - t3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r = Math.round(r)
|
||||||
|
g = Math.round(g)
|
||||||
|
b = Math.round(b)
|
||||||
|
|
||||||
|
return { r, g, b }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rgb2hex({ r, g, b }, a) {
|
||||||
|
let hex = [r, g, b].map(it => it.toString(16).padStart(2, '0')).join('')
|
||||||
|
if (a !== void 0) {
|
||||||
|
hex += (~~((a / 100) * 255)).toString(16)
|
||||||
|
}
|
||||||
|
return hex
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hex2rgb(hex) {
|
||||||
|
let r, g, b, a
|
||||||
|
|
||||||
|
hex = hex.replace(/^#/, '')
|
||||||
|
|
||||||
|
switch (hex.length) {
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
r = hex[0].repeat(2)
|
||||||
|
g = hex[1].repeat(2)
|
||||||
|
b = hex[2].repeat(2)
|
||||||
|
a = (hex[3] || 'f').repeat(2)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
r = hex.slice(0, 2)
|
||||||
|
g = hex.slice(2, 4)
|
||||||
|
b = hex.slice(4, 6)
|
||||||
|
a = hex.slice(6, 8) || 'ff'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
r = parseInt(r, 16)
|
||||||
|
g = parseInt(g, 16)
|
||||||
|
b = parseInt(b, 16)
|
||||||
|
a = ~~((parseInt(a, 16) * 100) / 255)
|
||||||
|
|
||||||
|
return { r, g, b, a }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rgb2hsb({ r, g, b }) {
|
||||||
|
let hsb = { h: 0, s: 0, b: 0 }
|
||||||
|
let max = Math.max(r, g, b)
|
||||||
|
let min = Math.min(r, g, b)
|
||||||
|
let delta = max - min
|
||||||
|
|
||||||
|
hsb.b = max
|
||||||
|
hsb.s = max === 0 ? 0 : (delta * 255) / max
|
||||||
|
|
||||||
|
if (hsb.s === 0) {
|
||||||
|
hsb.h = -1
|
||||||
|
} else {
|
||||||
|
if (r === max) {
|
||||||
|
hsb.h = (g - b) / delta
|
||||||
|
} else if (g === max) {
|
||||||
|
hsb.h = 2 + (b - r) / delta
|
||||||
|
} else {
|
||||||
|
hsb.h = 4 + (r - g) / delta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hsb.h *= 60
|
||||||
|
|
||||||
|
if (hsb.h < 0) {
|
||||||
|
hsb.h += 360
|
||||||
|
}
|
||||||
|
|
||||||
|
hsb.s *= 100 / 255
|
||||||
|
hsb.b *= 100 / 255
|
||||||
|
|
||||||
|
return hsb
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hex2hsb(hex) {
|
||||||
|
return rgb2hsb(hex2rgb(hex))
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* {一些常量}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2024/03/06 16:25:01
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const doc = document
|
||||||
|
export const win = window
|
||||||
|
export const xlink = 'http://www.w3.org/1999/xlink'
|
||||||
|
export const xmlns = 'http://www.w3.org/2000/svg'
|
||||||
|
export const xhtmlns = 'http://www.w3.org/1999/xhtml'
|
||||||
|
|
||||||
|
export const HTML_TAGS = ['div', 'span', 'p']
|
||||||
|
|
||||||
|
export const CSS_ATTR = {
|
||||||
|
'alignment-baseline': 1,
|
||||||
|
'baseline-shift': 1,
|
||||||
|
clip: 1,
|
||||||
|
'clip-path': 1,
|
||||||
|
'clip-rule': 1,
|
||||||
|
color: 1,
|
||||||
|
'color-interpolation': 1,
|
||||||
|
'color-interpolation-filters': 1,
|
||||||
|
'color-profile': 1,
|
||||||
|
'color-rendering': 1,
|
||||||
|
cursor: 1,
|
||||||
|
direction: 1,
|
||||||
|
display: 1,
|
||||||
|
'dominant-baseline': 1,
|
||||||
|
'enable-background': 1,
|
||||||
|
fill: 1,
|
||||||
|
'fill-opacity': 1,
|
||||||
|
'fill-rule': 1,
|
||||||
|
filter: 1,
|
||||||
|
'flood-color': 1,
|
||||||
|
'flood-opacity': 1,
|
||||||
|
font: 1,
|
||||||
|
'font-family': 1,
|
||||||
|
'font-size': 1,
|
||||||
|
'font-size-adjust': 1,
|
||||||
|
'font-stretch': 1,
|
||||||
|
'font-style': 1,
|
||||||
|
'font-variant': 1,
|
||||||
|
'font-weight': 1,
|
||||||
|
'glyph-orientation-horizontal': 1,
|
||||||
|
'glyph-orientation-vertical': 1,
|
||||||
|
'image-rendering': 1,
|
||||||
|
kerning: 1,
|
||||||
|
'letter-spacing': 1,
|
||||||
|
'lighting-color': 1,
|
||||||
|
marker: 1,
|
||||||
|
'marker-end': 1,
|
||||||
|
'marker-mid': 1,
|
||||||
|
'marker-start': 1,
|
||||||
|
mask: 1,
|
||||||
|
opacity: 1,
|
||||||
|
overflow: 1,
|
||||||
|
'pointer-events': 1,
|
||||||
|
'shape-rendering': 1,
|
||||||
|
'stop-color': 1,
|
||||||
|
'stop-opacity': 1,
|
||||||
|
stroke: 1,
|
||||||
|
'stroke-dasharray': 1,
|
||||||
|
'stroke-dashoffset': 1,
|
||||||
|
'stroke-linecap': 1,
|
||||||
|
'stroke-linejoin': 1,
|
||||||
|
'stroke-miterlimit': 1,
|
||||||
|
'stroke-opacity': 1,
|
||||||
|
'stroke-width': 1,
|
||||||
|
'text-anchor': 1,
|
||||||
|
'text-decoration': 1,
|
||||||
|
'text-rendering': 1,
|
||||||
|
'unicode-bidi': 1,
|
||||||
|
visibility: 1,
|
||||||
|
'word-spacing': 1,
|
||||||
|
'writing-mode': 1
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2024/03/06 09:55:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { xlink, xmlns, xhtmlns, HTML_TAGS, doc, win } from './lib/constants.js'
|
||||||
|
|
||||||
|
export function uuid(prefix = '') {
|
||||||
|
return prefix + Math.random().toString(16).slice(-8)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function noop() {}
|
||||||
|
|
||||||
|
//驼峰转换为连字符线风格
|
||||||
|
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 type(o) {
|
||||||
|
if (o === null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return Object.prototype.toString.call(o).slice(8, -1).toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function $(selector, container, multi) {
|
||||||
|
let fn = multi ? 'querySelectorAll' : 'querySelector'
|
||||||
|
if (container) {
|
||||||
|
return container[fn](selector)
|
||||||
|
}
|
||||||
|
return document.body[fn](selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function $$(selector, container) {
|
||||||
|
return $(selector, container, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function h(el, props = null, children) {
|
||||||
|
if (typeof el === 'string') {
|
||||||
|
el = doc.createElementNS(HTML_TAGS.includes(el) ? xhtmlns : xmlns, el)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props) {
|
||||||
|
for (let key in props) {
|
||||||
|
let val = props[key]
|
||||||
|
if (val === void 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
children = children.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.tagName.toLowerCase() === 'foreignobject') {
|
||||||
|
let f = h('div', { xmlns: 'http://www.w3.org/1999/xhtml' })
|
||||||
|
let p = h('p', null, children)
|
||||||
|
f.appendChild(p)
|
||||||
|
|
||||||
|
h(el, { xmlns })
|
||||||
|
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 + "')"
|
||||||
|
}
|
Loading…
Reference in New Issue