From 363a2ce6238bd2693773c1c7eed408bf1d7f4ed7 Mon Sep 17 00:00:00 2001 From: yutent Date: Wed, 29 Mar 2023 12:08:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=A8=E7=94=BB=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81,=20=E5=B9=B6=E5=86=85=E7=BD=AE4=E7=A7=8D?= =?UTF-8?q?=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/anim.js | 35 +++++++++++++++++++++++++++++++++++ src/html.js | 25 ++++++++++++++++++++++++- src/index.js | 31 ++++++++----------------------- 4 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 src/anim.js 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