@@ -28,10 +28,9 @@ export default {
2828
2929<script lang="ts" setup>
3030import wdIcon from ' ../wd-icon/wd-icon.vue'
31- import { ref , watch , nextTick , computed , getCurrentInstance , type CSSProperties } from ' vue'
31+ import { ref , watch , nextTick , computed , getCurrentInstance , type CSSProperties , onMounted , onActivated , onDeactivated , reactive } from ' vue'
3232import { getRect , isArray , isDef , objToStyle } from ' ../common/util'
33- import { noticeBarProps } from ' ./types'
34-
33+ import { type NoticeBarExpose , noticeBarProps } from ' ./types'
3534const $wrap = ' .wd-notice-bar__wrap'
3635const $content = ' .wd-notice-bar__content'
3736
@@ -40,14 +39,27 @@ const emit = defineEmits(['close', 'next', 'click'])
4039
4140const wrapWidth = ref <number >(0 )
4241const show = ref <boolean >(true )
43- const animation = ref <string >(' ' )
44- const currentIndex = ref (0 )
42+ const currentIndex = ref <number >(0 )
4543const textArray = computed (() => (Array .isArray (props .text ) ? props .text : [props .text ]))
4644const currentText = computed (() => textArray .value [currentIndex .value ])
47- const verticalIndex = ref (0 )
45+ const verticalIndex = ref <number >(0 )
46+ const wrapRect = ref <UniApp .NodeInfo | null >(null ) // 外层容器节点信息
47+ const contentRect = ref <UniApp .NodeInfo | null >(null ) // 内容节点信息
4848const isHorizontal = computed (() => props .direction === ' horizontal' )
4949const isVertical = computed (() => props .direction === ' vertical' )
5050
51+ const transitionState = reactive <CSSProperties >({
52+ transitionProperty: ' unset' ,
53+ transitionDelay: ' unset' ,
54+ transitionDuration: ' unset' ,
55+ transform: ' none' ,
56+ transitionTimingFunction: ' linear'
57+ })
58+
59+ const animation = computed (() => {
60+ return objToStyle (transitionState )
61+ })
62+
5163const rootStyle = computed (() => {
5264 const style: CSSProperties = {}
5365 if (isDef (props .color )) {
@@ -79,28 +91,66 @@ const noticeBarClass = computed(() => {
7991const { proxy } = getCurrentInstance () as any
8092
8193watch (
82- [ () => props .text ] ,
94+ () => props .text ,
8395 () => {
84- nextTick (() => scroll () )
96+ reset ( )
8597 },
86- { deep: true , immediate: true }
98+ { deep: true }
8799)
88100
101+ onMounted (() => {
102+ startTransition ()
103+ // #ifdef APP-PLUS
104+ const pages = getCurrentPages ()
105+ const currentPage = pages [pages .length - 1 ]
106+ const currentWebview = currentPage .$getAppWebview !()
107+ currentWebview .addEventListener (' hide' , () => {
108+ stopTransition ()
109+ })
110+ currentWebview .addEventListener (' show' , () => {
111+ startTransition ()
112+ })
113+ // #endif
114+ })
115+
116+ onActivated (() => {
117+ startTransition ()
118+ })
119+
120+ onDeactivated (() => {
121+ stopTransition ()
122+ })
123+
124+ function reset() {
125+ stopTransition ()
126+ startTransition ()
127+ }
128+
129+ function startTransition() {
130+ nextTick (() => scroll ())
131+ }
132+
133+ function stopTransition() {
134+ transitionState .transitionProperty = ' unset'
135+ transitionState .transitionDelay = ' unset'
136+ transitionState .transitionDuration = ' unset'
137+ transitionState .transform = ' none'
138+ transitionState .transitionTimingFunction = ' linear'
139+ currentIndex .value = 0
140+ verticalIndex .value = 0
141+ }
142+
89143function handleClose() {
90144 show .value = false
91145 emit (' close' )
92146}
93147
94- function initAnimation({ duration , delay , translate }: { duration: number ; delay: number ; translate: number }) {
95- const style: CSSProperties = {
96- transitionProperty: ' all' ,
97- transitionDelay: ` ${delay }s ` ,
98- transitionDuration: ` ${duration }s ` ,
99- transform: ` ${props .direction === ' vertical' ? ' translateY' : ' translateX' }(${translate }px) ` ,
100- transitionTimingFunction: ' linear'
101- }
102-
103- return objToStyle (style )
148+ function setTransition({ duration , delay , translate }: { duration: number ; delay: number ; translate: number }) {
149+ transitionState .transitionProperty = ' all'
150+ transitionState .transitionDelay = ` ${delay }s `
151+ transitionState .transitionDuration = ` ${duration }s `
152+ transitionState .transform = ` ${props .direction === ' vertical' ? ' translateY' : ' translateX' }(${translate }px) `
153+ transitionState .transitionTimingFunction = ' linear'
104154}
105155
106156function queryRect() {
@@ -109,30 +159,31 @@ function queryRect() {
109159
110160async function verticalAnimate(height : number ) {
111161 const translate = - (height / (textArray .value .length + 1 )) * (currentIndex .value + 1 )
112- animation . value = initAnimation ({
162+ setTransition ({
113163 duration: height / (textArray .value .length + 1 ) / props .speed ,
114164 delay: props .delay ,
115165 translate
116166 })
117167}
118168
119169async function scroll() {
120- const [wrapRect, contentRect] = await queryRect ()
121- if (! wrapRect .width || ! contentRect .width || ! contentRect .height ) return
122-
123- wrapWidth .value = wrapRect .width
170+ const [wRect, cRect] = await queryRect ()
171+ if (! wRect .width || ! cRect .width || ! cRect .height ) return
172+ wrapRect .value = wRect
173+ contentRect .value = cRect
174+ wrapWidth .value = wRect .width
124175
125176 if (isHorizontal .value ) {
126177 if (props .scrollable ) {
127- animation . value = initAnimation ({
128- duration: contentRect .width / props .speed ,
178+ setTransition ({
179+ duration: cRect .width / props .speed ,
129180 delay: props .delay ,
130- translate: - contentRect .width
181+ translate: - cRect .width
131182 })
132183 }
133184 } else {
134185 if (textArray .value .length > 1 ) {
135- verticalAnimate (contentRect .height )
186+ verticalAnimate (cRect .height )
136187 }
137188 }
138189}
@@ -148,15 +199,15 @@ function next() {
148199
149200function animationEnd() {
150201 if (isHorizontal .value ) {
151- animation . value = initAnimation ({
202+ setTransition ({
152203 duration: 0 ,
153204 delay: 0 ,
154- translate: wrapWidth .value + 1 // +1容错空间,防止露出来一丢丢
205+ translate: wrapWidth .value + 1
155206 })
156207 } else {
157208 if (++ verticalIndex .value >= textArray .value .length ) {
158209 verticalIndex .value = 0
159- animation . value = initAnimation ({
210+ setTransition ({
160211 duration: 0 ,
161212 delay: 0 ,
162213 translate: 0
@@ -168,18 +219,25 @@ function animationEnd() {
168219 next () // 更换下一条文本
169220
170221 nextTick (async () => {
171- // 因为文本会发生变化,所以每一次都需要查询
172- const [_, contentRect] = await queryRect ()
173- if (! contentRect .width || ! contentRect .height ) return
222+ try {
223+ const [wRect, cRect] = await queryRect ()
224+ wrapRect .value = wRect
225+ contentRect .value = cRect
226+ wrapWidth .value = wRect .width || 0
227+ } catch (error ) {
228+ // console.error(error)
229+ }
230+
231+ if (! contentRect .value || ! contentRect .value .width || ! contentRect .value .height ) return
174232
175233 if (isHorizontal .value ) {
176- animation . value = initAnimation ({
177- duration: (wrapWidth .value + contentRect .width ) / props .speed ,
234+ setTransition ({
235+ duration: (wrapWidth .value + contentRect .value . width ) / props .speed ,
178236 delay: props .delay ,
179- translate: - contentRect .width
237+ translate: - contentRect .value . width
180238 })
181239 } else {
182- verticalAnimate (contentRect .height )
240+ verticalAnimate (contentRect .value . height )
183241 }
184242 })
185243
@@ -199,6 +257,8 @@ function handleClick() {
199257 }
200258 emit (' click' , result )
201259}
260+
261+ defineExpose <NoticeBarExpose >({ reset })
202262 </script >
203263
204264<style lang="scss" scoped>
0 commit comments