diff --git a/package.json b/package.json index 2303fc3..969ff18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bd/core", - "version": "1.7.1", + "version": "1.8.0", "type": "module", "description": "百搭UI组件库的核心", "main": "dist/index.js", diff --git a/src/anim.js b/src/anim.js new file mode 100644 index 0000000..7c0d8e3 --- /dev/null +++ b/src/anim.js @@ -0,0 +1,35 @@ +/** + * {} + * @author yutent + * @date 2023/03/29 10:28:16 + */ + +export function animate(duration = 200, fromto = [], out = false) { + if (out === false) { + this.style.display = '' + } + let res = this.animate(fromto, { + duration, + direction: out ? 'reverse' : 'normal', + fill: 'forwards' + }) + if (out) { + res.addEventListener( + 'finish', + _ => { + this.style.display = 'none' + }, + { once: true } + ) + } +} +export const MODES = { + fade: [{ opacity: 0 }, { opacity: 1 }], + scale: [{ transform: 'scale(0)' }, { transform: 'scale(1)' }], + bounce: [ + { transform: 'scale(0)' }, + { transform: 'scale(1.25)' }, + { transform: 'scale(1)' } + ], + rotate: [{ transform: 'rotate(0)' }, { transform: 'rotate(360deg)' }] +} diff --git a/src/html.js b/src/html.js index bbf622a..f7f2397 100644 --- a/src/html.js +++ b/src/html.js @@ -1,4 +1,5 @@ import { boolMap, WC_PART, NO_CHANGE, NOTHING } from './constants.js' +import { animate, MODES } from './anim.js' const boundAttributeSuffix = '$wc$' const marker = `wc$${String(Math.random()).slice(9)}$` @@ -168,7 +169,7 @@ class Template { realName.toLowerCase() + boundAttributeSuffix ) let statics = value.split(marker) - let m = /([:@])?(.*)/.exec(realName) + let m = /([#:@])?(.*)/.exec(realName) parts.push({ type: ATTRIBUTE_PART, @@ -178,6 +179,8 @@ class Template { ctor: m[1] === ':' ? PropertyPart + : m[1] === '#' && m[2] === 'animation' + ? AnimPart : m[1] === '@' ? EventPart : AttributePart @@ -615,6 +618,26 @@ class PropertyPart extends AttributePart { this.element[this.name] = value } } +// 动画属性 +class AnimPart extends AttributePart { + constructor(...args) { + super(...args) + } + + commitValue({ type = 'fade', duration, custom } = {}) { + let fromto = MODES[type] + + if (custom) { + fromto = custom + } + this.element.$anim = { + el: this.element, + start(out = false) { + animate.call(this.el, duration, fromto, out) + } + } + } +} // 事件属性 class EventPart extends AttributePart { diff --git a/src/index.js b/src/index.js index 1b6912a..abe7ef4 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ import { } from './constants.js' import { css, adoptStyles } from './css.js' import { render, html, svg } from './html.js' +import { animate, MODES } from './anim.js' import { nextTick, fire, bind, unbind, hyphen } from './utils.js' export { $, $$, offset, outsideClick, clearOutsideClick } from './utils.js' export { html, css, svg, bind, unbind, nextTick } @@ -86,28 +87,14 @@ export class Component extends HTMLElement { static parseAnim() { if (this.hasOwnProperty('animation')) { - let { type = 'fade', duration = 300 } = this.animation - Object.defineProperty(this.prototype, 'anim', { + let { type = 'fade', duration } = this.animation + Object.defineProperty(this.prototype, '$anim', { get() { return { - type, - duration, - start: () => { - // - this.style.display = '' - this.style.transition = `opacity ${duration}ms ease` - setTimeout(() => { - this.style.transition = '' - }, duration) - }, - end: () => { - this.style.transition = `opacity ${duration}ms ease` - this.style.opacity = 0 - setTimeout(() => { - this.style.display = 'none' - this.style.transition = '' - this.style.opacity = '' - }, duration) + start: out => { + if (this[__mounted__]) { + animate.call(this, duration, MODES[type], out) + } } } }, @@ -188,8 +175,7 @@ export class Component extends HTMLElement { } connectedCallback() { - console.log('created::', this.anim) - if (this.anim) { + if (this.$anim) { this.style.display = 'none' } this.#init() @@ -322,7 +308,6 @@ export class Component extends HTMLElement { // 渲染视图 #render() { let ast = this.render() - this[__children__] = render(ast, this.root, { host: this, isConnected: !this[__mounted__] && this.isConnected