Merge pull request #155 in YR/star-web-components from modify-notification to master

* commit '4117fe769969639290c08f6e1e8e7777b93b131a':
  为通知组件添加动效
This commit is contained in:
汪昌棋 2022-11-19 10:17:16 +08:00
commit 12433f3737
3 changed files with 186 additions and 37 deletions

View File

@ -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;
}
}
`
}

View File

@ -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) {

View File

@ -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;
}
}
`