From ef83670716cc93f84c95e03d2a00377352d27d5b Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Sat, 2 Jul 2022 21:28:04 +0900 Subject: [PATCH] enhance(client): better marquee component --- packages/client/package.json | 1 - packages/client/src/components/marquee.vue | 97 +++++++++++++++++++ .../client/src/pages/welcome.entrance.a.vue | 2 +- packages/client/src/widgets/rss-marquee.vue | 2 +- packages/client/yarn.lock | 15 +-- 5 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 packages/client/src/components/marquee.vue diff --git a/packages/client/package.json b/packages/client/package.json index 5a087a2970..b810abd08a 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -76,7 +76,6 @@ "vanilla-tilt": "1.7.2", "vite": "3.0.0-beta.5", "vue": "3.2.37", - "vue-marquee-text-component": "2.0.1", "vue-prism-editor": "2.0.0-alpha.2", "vuedraggable": "4.0.1", "websocket": "1.0.34", diff --git a/packages/client/src/components/marquee.vue b/packages/client/src/components/marquee.vue new file mode 100644 index 0000000000..2fd76a54f0 --- /dev/null +++ b/packages/client/src/components/marquee.vue @@ -0,0 +1,97 @@ +<script lang="ts"> +import { h, onMounted, onUnmounted, ref } from 'vue'; + +export default { + name: 'MarqueeText', + props: { + duration: { + type: Number, + default: 15, + }, + repeat: { + type: Number, + default: 2, + }, + paused: { + type: Boolean, + default: false, + }, + reverse: { + type: Boolean, + default: false, + }, + }, + setup(props) { + const contentEl = ref(); + + function calc() { + const eachLength = contentEl.value.offsetWidth / props.repeat; + const factor = 3000; + const duration = props.duration / ((1 / eachLength) * factor); + + contentEl.value.style.animationDuration = `${duration}s`; + } + + onMounted(() => { + calc(); + }); + + onUnmounted(() => { + }); + + return { + contentEl, + }; + }, + render({ + $slots, $style, $props: { + duration, repeat, paused, reverse, + }, + }) { + return h('div', { class: [$style.wrap] }, [ + h('span', { + ref: 'contentEl', + class: [ + paused + ? $style.paused + : undefined, + $style.content, + ], + }, Array(repeat).fill( + h('span', { + class: $style.text, + style: { + animationDirection: reverse + ? 'reverse' + : undefined, + }, + }, $slots.default()), + )), + ]); + }, +}; +</script> + +<style lang="scss" module> +.wrap { + overflow: clip; +} +.content { + display: inline-block; + white-space: nowrap; +} +.text { + display: inline-block; + animation-name: marquee; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-duration: inherit; +} +.paused .text { + animation-play-state: paused; +} +@keyframes marquee { + 0% { transform:translateX(0); } + 100% { transform:translateX(-100%); } +} +</style> diff --git a/packages/client/src/pages/welcome.entrance.a.vue b/packages/client/src/pages/welcome.entrance.a.vue index b78a37eab0..8ff7d9057f 100644 --- a/packages/client/src/pages/welcome.entrance.a.vue +++ b/packages/client/src/pages/welcome.entrance.a.vue @@ -47,8 +47,8 @@ <script lang="ts" setup> import { } from 'vue'; import { toUnicode } from 'punycode/'; -import MarqueeText from 'vue-marquee-text-component'; import XTimeline from './welcome.timeline.vue'; +import MarqueeText from '@/components/marquee.vue'; import XSigninDialog from '@/components/signin-dialog.vue'; import XSignupDialog from '@/components/signup-dialog.vue'; import MkButton from '@/components/ui/button.vue'; diff --git a/packages/client/src/widgets/rss-marquee.vue b/packages/client/src/widgets/rss-marquee.vue index d96eadb4e0..2f92c09f38 100644 --- a/packages/client/src/widgets/rss-marquee.vue +++ b/packages/client/src/widgets/rss-marquee.vue @@ -18,8 +18,8 @@ <script lang="ts" setup> import { onMounted, onUnmounted, ref, watch } from 'vue'; -import MarqueeText from 'vue-marquee-text-component'; import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget'; +import MarqueeText from '@/components/marquee.vue'; import { GetFormResultType } from '@/scripts/form'; import * as os from '@/os'; import MkContainer from '@/components/ui/container.vue'; diff --git a/packages/client/yarn.lock b/packages/client/yarn.lock index e5f2e31d7f..a7b46b70d0 100644 --- a/packages/client/yarn.lock +++ b/packages/client/yarn.lock @@ -1221,11 +1221,6 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -core-js@^3.18.0: - version "3.23.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.23.3.tgz#3b977612b15da6da0c9cc4aec487e8d24f371112" - integrity sha512-oAKwkj9xcWNBAvGbT//WiCdOMpb9XQG92/Fe3ABFM/R16BsHgePG00mFOgKf7IsCtfj8tA1kHtf/VwErhriz5Q== - core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -4250,20 +4245,12 @@ vue-eslint-parser@^9.0.1: lodash "^4.17.21" semver "^7.3.6" -vue-marquee-text-component@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vue-marquee-text-component/-/vue-marquee-text-component-2.0.1.tgz#62691df195f755471fa9bdc9b1969f836a922b9a" - integrity sha512-dbeRwDY5neOJcWZrDFU2tJMhPSsxN25ZpNYeZdt0jkseg1MbyGKzrfEH9nrCFZRkEfqhxG+ukyzwVwR9US5sTQ== - dependencies: - core-js "^3.18.0" - vue "^3.2.19" - vue-prism-editor@2.0.0-alpha.2: version "2.0.0-alpha.2" resolved "https://registry.yarnpkg.com/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz#aa53a88efaaed628027cbb282c2b1d37fc7c5c69" integrity sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w== -vue@3.2.37, vue@^3.2.19: +vue@3.2.37: version "3.2.37" resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.37.tgz#da220ccb618d78579d25b06c7c21498ca4e5452e" integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==