From 4117fe769969639290c08f6e1e8e7777b93b131a Mon Sep 17 00:00:00 2001 From: wurou Date: Wed, 16 Nov 2022 20:17:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E9=80=9A=E7=9F=A5=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification-group/notification-group.ts | 87 ++++++++++++++++-- src/components/notification/notification.ts | 88 +++++++++++++------ .../notification/notificationstyle.ts | 48 +++++++++- 3 files changed, 186 insertions(+), 37 deletions(-) diff --git a/src/components/notification-group/notification-group.ts b/src/components/notification-group/notification-group.ts index 4904122..7fbf13f 100644 --- a/src/components/notification-group/notification-group.ts +++ b/src/components/notification-group/notification-group.ts @@ -83,10 +83,7 @@ export class StarNotificationGroup extends LitElement { this.setAttribute('show', 'false') firstChild.setAttribute('notificationType', 'one-notification') firstChild.withArrowUp = false - firstChild.removeEventListener( - 'notification-click', - allNotificationshown - ) + firstChild.removeEventListener('notification-tap', allNotificationshown) } else if (slotLen > 1) { let lastChild = slotElements[slotLen - 1] as StarNotification @@ -106,7 +103,7 @@ export class StarNotificationGroup extends LitElement { } // 仅对一条以上的进行监听处理 - firstChild.addEventListener('notification-click', allNotificationshown) + firstChild.addEventListener('notification-tap', allNotificationshown) let otherChild = Array.from(slotElements as StarNotification[]).filter( (child) => { @@ -122,7 +119,7 @@ export class StarNotificationGroup extends LitElement { ) ;(child as StarNotification).setAttribute('radiusType', '') ;(child as StarNotification).removeEventListener( - 'notification-click', + 'notification-tap', allNotificationshown ) }) @@ -154,20 +151,54 @@ export class StarNotificationGroup extends LitElement { } let isShow = this.getAttribute('show') == 'true' + console.log('hellowq allNotificationshown isShow: ', isShow) if (isShow) { // 当前是展开状态,点击需折叠 - this.setAttribute('show', 'false') + let self = this firstChild.setAttribute('radiusType', 'border-radius') firstChild.withArrowUp = false firstChild.setAttribute('notificationType', 'more-notifiactions-first') + this.slotElements.forEach((element, index) => { + if (element !== firstChild) { + ;(element as StarNotification).classList.add('animation-out') + element.addEventListener('animationend', function tEnd() { + if (index == self.slotElements.length - 1) { + self.setAttribute('show', 'false') + } + ;(element as StarNotification).classList.remove('animation-out') + element.removeEventListener('animationend', tEnd) + }) + } + }) } else { this.setAttribute('show', 'true') + this.slotElements.forEach((element) => { + if (element !== firstChild) { + ;(element as StarNotification).classList.add('animation-in') + element.addEventListener('animationend', function tEnd() { + element.removeEventListener('animationend', tEnd) + ;(element as StarNotification).classList.remove('animation-in') + }) + } + }) firstChild.setAttribute('radiusType', 'top-border-radius') firstChild.withArrowUp = true firstChild.setAttribute('notificationType', 'more-notifiactions') } } + disappearing(callback?: Function) { + this.classList.add('disappearing') + let self = this + this.addEventListener('animationend', function tranEnd() { + self.removeEventListener('animationend', tranEnd) + self.classList.remove('disappearing') + if (callback) { + callback() + } + }) + } + static styles = css` :host { display: block; @@ -187,9 +218,51 @@ export class StarNotificationGroup extends LitElement { display: block; } + :host(.fadein) { + animation: show 0.3s cubic-bezier(0.25, 0.1, 0.25, 1); + } + + :host(.fadeout) { + animation: hide 0.3s cubic-bezier(0.25, 0.1, 0.25, 1); + } + :host([show='true']) ::slotted(:not(:last-child)) { border-bottom: 0.08vw solid rgba(0, 0, 0, 0.09); } + + :host(.disappearing) { + animation: disappearing 0.25s cubic-bezier(0.25, 0.1, 0.25, 1); + } + + @keyframes disappearing { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + scale(0.9); + } + } + + @keyframes show { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } + + @keyframes hide { + from { + opacity: 1; + } + to { + opacity: 0; + } + } ` } diff --git a/src/components/notification/notification.ts b/src/components/notification/notification.ts index 25065ad..3e1ea4d 100644 --- a/src/components/notification/notification.ts +++ b/src/components/notification/notification.ts @@ -1,10 +1,4 @@ -import { - html, - LitElement, - HTMLTemplateResult, - nothing, - CSSResultArray, -} from 'lit' +import {html, HTMLTemplateResult, nothing, CSSResultArray} from 'lit' import { customElement, property, @@ -13,6 +7,7 @@ import { state, } from 'lit/decorators.js' import {sharedStyles} from './notificationstyle.js' +import {StarBaseElement} from '../base' // ONE : 单条通知,notification-group展开时第一条notification类型 // MORE : notification-group中除第一条以外的notification类型 // MORE_FIRST: notification-group折叠时第一条notification类型 @@ -32,7 +27,7 @@ export enum RadiusType { } @customElement('star-notification') -export class StarNotification extends LitElement { +export class StarNotification extends StarBaseElement { // 公共属性 @property({type: String}) id = '' @property({type: String}) _timestamp = '' @@ -60,6 +55,8 @@ export class StarNotification extends LitElement { @property({type: Boolean}) isToast = false @property({type: Boolean}) btnShown = false @property({type: Number}) notificationPosition = 0 + @property({type: Number}) width = 0 + @property({type: Number}) widthleft = 0 @property({type: Number}) velocityThreshold = 0.8 @query('.notification') notification!: HTMLDivElement @query('.btn-tool') btnTool!: HTMLDivElement @@ -92,8 +89,21 @@ export class StarNotification extends LitElement { this._timestamp = value } + constructor() { + super() + this.startGestureDetector() + } + firstUpdated() { + this.updateComplete.then(() => { + this.addEventListener('swipeleft', this) + this.addEventListener('swiperight', this) + this.addEventListener('holdstart', this) + this.addEventListener('holdmove', this) + this.addEventListener('holdend', this) + }) this.notificationPosition = this.getBoundingClientRect().right + this.width = this.getBoundingClientRect().width } render(): HTMLTemplateResult | typeof nothing { @@ -410,6 +420,7 @@ export class StarNotification extends LitElement { self.btnShown = true } ) + this.widthleft = this.width - translateX } else if (touchPosX > 0) { // if (touchPosX > 44) { // (this.btnTool.children[0] as any).style.opacity = 0.6; @@ -443,9 +454,15 @@ export class StarNotification extends LitElement { case 'click': event.stopPropagation() let target = event.target as HTMLElement - this.notification.style.transform = '' switch (target.dataset.icon) { case 'delete': + this.btnTool.classList.add('deletebybtn') + this.notification.style.transform = + 'translateX(-' + this.widthleft + 'px)' + this.btnTool.addEventListener('transitionend', function tEnd() { + self.btnTool.removeEventListener('transitionend', tEnd) + self.btnTool.classList.remove('deletebybtn') + }) target.setAttribute('clicked', 'true') target.addEventListener('transitionend', function tranEnd() { target.removeEventListener('transitionend', tranEnd) @@ -478,30 +495,43 @@ export class StarNotification extends LitElement { }) break default: - this.notification.setAttribute('clicked', 'true') - this.notification.addEventListener( - 'transitionend', - function tranEnd() { - self.notification.removeEventListener( - 'transitionend', - tranEnd - ) - self.notification.removeAttribute('clicked') - self.dispatchEvent( - new CustomEvent('notification-click', { - detail: { - id: self.id, - notification: self, - }, - bubbles: true, - composed: true, - }) - ) - } + this.dispatchEvent( + new CustomEvent('notification-tap', { + detail: { + id: self.id, + notification: self, + }, + bubbles: true, + composed: true, + }) ) break } break + case 'holdstart': + this.notification.classList.add('click-start') + break + case 'holdend': + this.notification.classList.remove('click-start') + this.notification.classList.add('click-end') + this.notification.addEventListener( + 'transitionend', + function tranEnd() { + self.notification.removeEventListener('transitionend', tranEnd) + self.notification.classList.remove('click-end') + self.dispatchEvent( + new CustomEvent('notification-click', { + detail: { + id: self.id, + notification: self, + }, + bubbles: true, + composed: true, + }) + ) + } + ) + break } } else { switch (event.type) { diff --git a/src/components/notification/notificationstyle.ts b/src/components/notification/notificationstyle.ts index a82f00e..1e17761 100644 --- a/src/components/notification/notificationstyle.ts +++ b/src/components/notification/notificationstyle.ts @@ -38,11 +38,18 @@ export const sharedStyles: CSSResult = css` } .notification { - transition: transform 0.6s; + // transition: transform 0.6s; + transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); height: inherit; width: inherit; } + .deletebybtn { + transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); + transform: opacity translateX(-2.5vw); + // animation: notification-disappear 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); + } + .notification[clicked] { transition: transform 0.1s; transform: scale(0.95); @@ -515,4 +522,43 @@ export const sharedStyles: CSSResult = css` color: var(--single-text-color-dm); } } + + @keyframes notification-disappear { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } + } + + .click-start { + transition: transform 0.15s cubic-bezier(0.25, 0.1, 0.25, 1); + transform: scale(0.95); + background: var(--notification-background-active); + } + + .click-end { + transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); + transform: scale(1); + } + + :host(.animation-in) { + animation: show 0.3s cubic-bezier(0.25, 0.1, 0.25, 1); + } + + :host(.animation-out) { + animation: notification-disappear 0.3s cubic-bezier(0.25, 0.1, 0.25, 1); + } + + @keyframes show { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } + } `