update src/component/noticeBar/index.vue.

This commit is contained in:
cool314156 2022-03-17 09:24:07 +00:00 committed by Gitee
parent 797adf2c57
commit a02749d959
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

View File

@ -0,0 +1,194 @@
<template>
<div class="notice-bar" :style="{ background, height: `${height}px` }" v-show="!isMode">
<div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }">
<lay-icon v-if="leftIcon" class="notice-bar-warp-left-icon" :type="leftIcon"></lay-icon>
<div class="notice-bar-warp-text-box" ref="noticeBarWarpRef">
<div class="notice-bar-warp-text" ref="noticeBarTextRef" v-if="!scrollable">{{ text }}</div>
<div class="notice-bar-warp-slot" v-else><slot /></div>
</div>
<lay-icon :type="rightIcon" v-if="rightIcon" class="notice-bar-warp-right-icon" @click="onRightIconClick"></lay-icon>
</div>
</div>
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent, ref, onMounted, nextTick } from 'vue';
export default defineComponent({
name: 'noticeBar',
props: {
// closeable link
mode: {
type: String,
default: () => '',
},
//
text: {
type: String,
default: () => '',
},
//
color: {
type: String,
default: () => 'var(--color-warning)',
},
//
background: {
type: String,
default: () => 'var(--color-warning-light-9)',
},
// px
size: {
type: [Number, String],
default: () => 14,
},
// px
height: {
type: Number,
default: () => 40,
},
// (s)
delay: {
type: Number,
default: () => 1,
},
// (px/s)
speed: {
type: Number,
default: () => 100,
},
//
scrollable: {
type: Boolean,
default: () => false,
},
//
leftIcon: {
type: String,
default: () => '',
},
//
rightIcon: {
type: String,
default: () => '',
},
},
setup(props, { emit }) {
const noticeBarWarpRef = ref();
const noticeBarTextRef = ref();
const state = reactive({
order: 1,
oneTime: 0,
twoTime: 0,
warpOWidth: 0,
textOWidth: 0,
isMode: false,
});
// animation
const initAnimation = () => {
nextTick(() => {
state.warpOWidth = noticeBarWarpRef.value.offsetWidth;
state.textOWidth = noticeBarTextRef.value.offsetWidth;
document.styleSheets[0].insertRule(`@keyframes oneAnimation {0% {left: 0px;} 100% {left: -${state.textOWidth}px;}}`);
document.styleSheets[0].insertRule(`@keyframes twoAnimation {0% {left: ${state.warpOWidth}px;} 100% {left: -${state.textOWidth}px;}}`);
computeAnimationTime();
setTimeout(() => {
changeAnimation();
}, props.delay * 1000);
});
};
// animation
const computeAnimationTime = () => {
state.oneTime = state.textOWidth / props.speed;
state.twoTime = (state.textOWidth + state.warpOWidth) / props.speed;
};
// animation
const changeAnimation = () => {
if (state.order === 1) {
noticeBarTextRef.value.style.cssText = `animation: oneAnimation ${state.oneTime}s linear; opactity: 1;}`;
state.order = 2;
} else {
noticeBarTextRef.value.style.cssText = `animation: twoAnimation ${state.twoTime}s linear infinite; opacity: 1;`;
}
};
// animation
const listenerAnimationend = () => {
noticeBarTextRef.value.addEventListener(
'animationend',
() => {
changeAnimation();
},
false
);
};
// icon
const onRightIconClick = () => {
if (!props.mode) return false;
if (props.mode === 'closeable') {
state.isMode = true;
emit('close');
} else if (props.mode === 'link') {
emit('link');
}
};
//
onMounted(() => {
if (props.scrollable) return false;
initAnimation();
listenerAnimationend();
});
return {
noticeBarWarpRef,
noticeBarTextRef,
onRightIconClick,
...toRefs(state),
};
},
});
</script>
<style>
.notice-bar {
padding: 0 15px;
width: 100%;
border-radius: 4px;
}
.notice-bar .notice-bar-warp {
display: flex;
align-items: center;
width: 100%;
height: inherit;
}
.notice-bar .notice-bar-warp .notice-bar-warp-text-box {
flex: 1;
height: inherit;
display: flex;
align-items: center;
overflow: hidden;
position: relative;
}
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-text {
white-space: nowrap;
position: absolute;
left: 0;
}
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-slot {
width: 100%;
white-space: nowrap;
}
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-slot ::v-deep(.el-carousel__item) {
display: flex;
align-items: center;
}
.notice-bar .notice-bar-warp .notice-bar-warp-left-icon {
width: 24px;
font-size: inherit !important;
}
.notice-bar .notice-bar-warp .notice-bar-warp-right-icon {
width: 24px;
text-align: right;
font-size: inherit !important;
}
.notice-bar .notice-bar-warp .notice-bar-warp-right-icon:hover {
cursor: pointer;
}
</style>