88 <slot v-else name =" prefix" ></slot >
99 <view class =" wd-notice-bar__wrap" >
1010 <view class =" wd-notice-bar__content" :animation =" animation" @transitionend =" animationEnd" >
11- <slot >{{ currentText }}</slot >
11+ <template v-if =" direction === ' vertical' " >
12+ <slot v-for =" (item, i) in textArray" :key =" item" :name =" `vertical-${i}`" >
13+ <view >{{ item }}</view >
14+ </slot >
15+ <slot v-if =" textArray.length > 1" name =" vertical-0" >
16+ <view >{{ textArray[0] }}</view >
17+ </slot >
18+ </template >
19+ <slot v-else >{{ currentText }}</slot >
1220 </view >
1321 </view >
1422 <wd-icon v-if =" closable" custom-class =" wd-notice-bar__suffix" size =" 18px" name =" close-bold" @click =" handleClose" ></wd-icon >
@@ -46,6 +54,9 @@ const noticeBarClass = ref<string>('')
4654const currentIndex = ref (0 )
4755const textArray = computed (() => (Array .isArray (props .text ) ? props .text : [props .text ]))
4856const currentText = computed (() => textArray .value [currentIndex .value ])
57+ const verticalIndex = ref (0 )
58+ const isHorizontal = computed (() => props .direction === ' horizontal' )
59+ const isVertical = computed (() => props .direction === ' vertical' )
4960
5061const { proxy } = getCurrentInstance () as any
5162watch (
@@ -71,10 +82,17 @@ onBeforeMount(() => {
7182const emit = defineEmits ([' close' , ' next' ])
7283
7384function computedClass() {
74- const { type, wrapable, scrollable } = props
85+ const { type, wrapable, scrollable, direction } = props
86+
7587 let noticeBarClasses: string [] = []
7688 type && noticeBarClasses .push (` is-${type } ` )
77- ! wrapable && ! scrollable && noticeBarClasses .push (' wd-notice-bar--ellipse' )
89+
90+ if (isHorizontal .value ) {
91+ ! wrapable && ! scrollable && noticeBarClasses .push (' wd-notice-bar--ellipse' )
92+ } else {
93+ noticeBarClasses .push (' wd-notice-bar--ellipse' )
94+ }
95+
7896 wrapable && ! scrollable && noticeBarClasses .push (' wd-notice-bar--wrap' )
7997 noticeBarClass .value = noticeBarClasses .join (' ' )
8098}
@@ -83,29 +101,50 @@ function handleClose() {
83101 emit (' close' )
84102}
85103
86- function initAnimation(duration : number , delay : number , translate : number ) {
104+ function initAnimation({ duration , delay , translate } : { duration : number ; delay: number ; translate: number } ) {
87105 const ani = uni
88106 .createAnimation ({
89107 duration ,
90108 delay
91109 })
92- . translateX (translate )
110+ [ isHorizontal . value ? ' translateX' : ' translateY ' ] (translate )
93111 ani .step ()
94112 return ani .export ()
95113}
96114
97- function scroll() {
98- Promise .all ([getRect ($wrap , false , proxy ), getRect ($content , false , proxy )]).then ((rects ) => {
99- const [wrapRect, contentRect] = rects
100- if (! wrapRect || ! contentRect || ! wrapRect .width || ! contentRect .width ) return
115+ function queryRect() {
116+ return Promise .all ([getRect ($wrap , false , proxy ), getRect ($content , false , proxy )])
117+ }
118+
119+ async function verticalAnimate(height : number ) {
120+ const translate = - (height / (textArray .value .length + 1 )) * (currentIndex .value + 1 )
121+
122+ animation .value = initAnimation ({
123+ duration: props .speed * 1000 ,
124+ delay: props .delay * 1000 ,
125+ translate
126+ })
127+ }
128+
129+ async function scroll() {
130+ const [wrapRect, contentRect] = await queryRect ()
131+ if (! wrapRect .width || ! contentRect .width || ! contentRect .height ) return
132+
133+ wrapWidth .value = wrapRect .width
101134
102- const wrapWidthTemp = wrapRect .width
103- const contentWidthTemp = contentRect .width
135+ if (isHorizontal .value ) {
104136 if (props .scrollable ) {
105- animation .value = initAnimation ((contentWidthTemp / props .speed ) * 1000 , props .delay * 1000 , - contentWidthTemp )
106- wrapWidth .value = wrapWidthTemp
137+ animation .value = initAnimation ({
138+ duration: (contentRect .width / props .speed ) * 1000 ,
139+ delay: props .delay * 1000 ,
140+ translate: - contentRect .width
141+ })
107142 }
108- })
143+ } else {
144+ if (textArray .value .length > 1 ) {
145+ verticalAnimate (contentRect .height )
146+ }
147+ }
109148}
110149
111150function next() {
@@ -118,17 +157,40 @@ function next() {
118157}
119158
120159function animationEnd() {
121- animation .value = initAnimation (0 , 0 , wrapWidth .value )
160+ if (isHorizontal .value ) {
161+ animation .value = initAnimation ({
162+ duration: 0 ,
163+ delay: 0 ,
164+ translate: wrapWidth .value + 1 // +1容错空间,防止露出来一丢丢
165+ })
166+ } else {
167+ if (++ verticalIndex .value >= textArray .value .length ) {
168+ verticalIndex .value = 0
169+ animation .value = initAnimation ({
170+ duration: 0 ,
171+ delay: 0 ,
172+ translate: 0
173+ })
174+ }
175+ }
122176
123177 const timer = setTimeout (() => {
124178 next () // 更换下一条文本
125179
126- nextTick (() => {
127- // 因为文本会发生变化,所以contentWidth每一次都需要查询
128- getRect ($content , false , proxy ).then ((rect ) => {
129- if (! rect ) return
130- animation .value = initAnimation (((wrapWidth .value + rect .width ! ) / props .speed ) * 1000 , props .delay * 1000 , - rect .width ! )
131- })
180+ nextTick (async () => {
181+ // 因为文本会发生变化,所以每一次都需要查询
182+ const [_, contentRect] = await queryRect ()
183+ if (! contentRect .width || ! contentRect .height ) return
184+
185+ if (isHorizontal .value ) {
186+ animation .value = initAnimation ({
187+ duration: ((wrapWidth .value + contentRect .width ) / props .speed ) * 1000 ,
188+ delay: props .delay * 1000 ,
189+ translate: - contentRect .width
190+ })
191+ } else {
192+ verticalAnimate (contentRect .height )
193+ }
132194 })
133195
134196 clearTimeout (timer )
0 commit comments