|
@@ -1,326 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="painting-detail-for-shuang-gou">
|
|
|
- <div
|
|
|
- class="painting-wrap"
|
|
|
- :style="{
|
|
|
- clipPath: `rect(0 100% ${AnimationProgress.value}% 0)`,
|
|
|
- }"
|
|
|
- >
|
|
|
- <!-- <img
|
|
|
- class=""
|
|
|
- src="@/assets/images/"
|
|
|
- alt=""
|
|
|
- draggable="false"
|
|
|
- > -->
|
|
|
- <Transition name="fade-out">
|
|
|
- <img
|
|
|
- v-show="isAnimating"
|
|
|
- class="bottom-border-for-animation"
|
|
|
- :style="{
|
|
|
- bottom: `${100 - AnimationProgress.value}%`,
|
|
|
- }"
|
|
|
- src="@/assets/images/painting-border-bottom.png"
|
|
|
- alt=""
|
|
|
- draggable="false"
|
|
|
- >
|
|
|
- </Transition>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- ref="descTextEl"
|
|
|
- class="desc-text"
|
|
|
- :style="{
|
|
|
- opacity: isAnimating ? AnimationProgress.value / 100 : 1,
|
|
|
- }"
|
|
|
- >
|
|
|
- <h1>{{ props.title }}</h1>
|
|
|
- <p class="subtitle">
|
|
|
- {{ `${props.author} (${props.age})` }}
|
|
|
- </p>
|
|
|
- <p class="subtitle">
|
|
|
- {{ props.subtitle }}
|
|
|
- </p>
|
|
|
- <p class="subtitle">
|
|
|
- {{ props.location }}
|
|
|
- </p>
|
|
|
- </div>
|
|
|
-
|
|
|
- <OperationTip
|
|
|
- v-if="needOperationTip"
|
|
|
- class="operation-tip"
|
|
|
- text=""
|
|
|
- :is-show="isShowOperationTip"
|
|
|
- />
|
|
|
-
|
|
|
- <BtnBack
|
|
|
- v-if="canClose"
|
|
|
- @click="emit('close')"
|
|
|
- />
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { ref, computed, watch, onMounted, inject, onUnmounted } from "vue"
|
|
|
-import { useRoute, useRouter } from "vue-router"
|
|
|
-import { useStore } from "vuex"
|
|
|
-import useSizeAdapt from "@/useFunctions/useSizeAdapt"
|
|
|
-import TWEEN from '@tweenjs/tween.js'
|
|
|
-import { api as viewerApi } from 'v-viewer'
|
|
|
-
|
|
|
-const route = useRoute()
|
|
|
-const router = useRouter()
|
|
|
-const store = useStore()
|
|
|
-
|
|
|
-const $env = inject('$env')
|
|
|
-
|
|
|
-const emit = defineEmits(['close'])
|
|
|
-
|
|
|
-const {
|
|
|
- windowSizeInCssForRef,
|
|
|
- windowSizeWhenDesignForRef,
|
|
|
-} = useSizeAdapt()
|
|
|
-
|
|
|
-const props = defineProps({
|
|
|
- thumb: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- bigPainting: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- title: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- author: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- // subtitle: {
|
|
|
- // type: String,
|
|
|
- // required: true,
|
|
|
- // },
|
|
|
- age: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- location: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- paintingDesc: {
|
|
|
- type: String,
|
|
|
- default: '',
|
|
|
- },
|
|
|
- authorDesc: {
|
|
|
- type: String,
|
|
|
- default: '',
|
|
|
- },
|
|
|
- canClose: {
|
|
|
- type: Boolean,
|
|
|
- default: true,
|
|
|
- },
|
|
|
- size: {
|
|
|
- type: Object,
|
|
|
- default: () => {
|
|
|
- return {
|
|
|
- width: 1,
|
|
|
- height: 1,
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- needOperationTip: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
-})
|
|
|
-
|
|
|
-/**
|
|
|
- * 操作提示
|
|
|
- */
|
|
|
-const needOperationTip = computed(() => {
|
|
|
- return props.needOperationTip
|
|
|
-})
|
|
|
-const isShowOperationTip = ref(true)
|
|
|
-const descTextEl = ref(null)
|
|
|
-const descTextElScrollTop = ref(0)
|
|
|
-onMounted(() => {
|
|
|
- descTextEl.value.addEventListener('scroll', (e) => {
|
|
|
- descTextElScrollTop.value = descTextEl.value.scrollTop
|
|
|
- })
|
|
|
-
|
|
|
-})
|
|
|
-const unwatch = watch(descTextElScrollTop, (v) => {
|
|
|
- isShowOperationTip.value = false
|
|
|
- unwatch()
|
|
|
-})
|
|
|
-
|
|
|
-const isAnimating = ref(true)
|
|
|
-
|
|
|
-/** 卷轴展开动画的tweening */
|
|
|
-const AnimationProgress = ref({
|
|
|
- value: 7
|
|
|
-})
|
|
|
-const tween = new TWEEN.Tween(AnimationProgress.value)
|
|
|
-tween.to({
|
|
|
- value: 100,
|
|
|
-}, 3000)
|
|
|
-tween.easing(TWEEN.Easing.Cubic.InOut)
|
|
|
-let animationRequestId = null
|
|
|
-const animate = () => {
|
|
|
- animationRequestId = requestAnimationFrame(animate)
|
|
|
- TWEEN.update()
|
|
|
-}
|
|
|
-// tween.onUpdate(function (object) {
|
|
|
-// console.log(object.value)
|
|
|
-// })
|
|
|
-onMounted(() => {
|
|
|
- tween.start()
|
|
|
- animate()
|
|
|
-})
|
|
|
-tween.onComplete(() => {
|
|
|
- isAnimating.value = false
|
|
|
- cancelAnimationFrame(animationRequestId)
|
|
|
-})
|
|
|
-onUnmounted(() => {
|
|
|
- tween.stop()
|
|
|
- cancelAnimationFrame(animationRequestId)
|
|
|
-})
|
|
|
-
|
|
|
-/**
|
|
|
- * 尺寸相关
|
|
|
- */
|
|
|
-const paintingWrapWidth = ref(268)
|
|
|
-const paintingWrapHeight = ref(426)
|
|
|
-let wrapSizeRatio = paintingWrapWidth.value / paintingWrapHeight.value
|
|
|
-if (wrapSizeRatio < 1) {
|
|
|
- wrapSizeRatio = 1 / wrapSizeRatio
|
|
|
-}
|
|
|
-
|
|
|
-let sizeRatio = props.size.width / props.size.height
|
|
|
-if (sizeRatio < 1) {
|
|
|
- sizeRatio = 1 / sizeRatio
|
|
|
-}
|
|
|
-
|
|
|
-const isOversize = ref(sizeRatio > wrapSizeRatio)
|
|
|
-
|
|
|
-const paintingWrap2El = ref(null)
|
|
|
-const paintingEl = ref(null)
|
|
|
-onMounted(() => {
|
|
|
- if (isOversize.value) {
|
|
|
- setTimeout(() => {
|
|
|
- const y = (paintingEl.value.clientHeight - paintingWrap2El.value.clientHeight) / 2
|
|
|
- paintingWrap2El.value.scrollTo({
|
|
|
- top: y,
|
|
|
- // behavior: 'smooth',
|
|
|
- })
|
|
|
- }, 0)
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
-function showBigPainting() {
|
|
|
- viewerApi({
|
|
|
- images: [props.bigPainting],
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="less" scoped>
|
|
|
-.painting-detail-for-shuang-gou{
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- ::-webkit-scrollbar { width: 0; height: 0; }
|
|
|
- >.painting-wrap{
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- transform: translate(-50%, 0);
|
|
|
- width: calc(356 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- height: calc(602 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- overflow: hidden;
|
|
|
- >img.painting-border{
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- >.painting-wrap-2{
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: calc(110 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- transform: translate(-50%, 0);
|
|
|
- width: calc(v-bind('paintingWrapWidth') / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- height: calc(v-bind('paintingWrapHeight') / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- overflow: auto;
|
|
|
- >img.painting{
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: 50%;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- >img.painting.oversize{
|
|
|
- position: static;
|
|
|
- left: initial;
|
|
|
- top: initial;
|
|
|
- transform: initial;
|
|
|
- }
|
|
|
- }
|
|
|
- >img.bottom-border-for-animation{
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
- >.desc-text{
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- bottom: 2%;
|
|
|
- transform: translateX(-50%);
|
|
|
- width: calc(306 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- height: calc(130 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- overflow: auto;
|
|
|
- >h1{
|
|
|
- text-align: center;
|
|
|
- font-family: KaiTi, KaiTi;
|
|
|
- font-weight: 400;
|
|
|
- font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- color: #FFFFFF;
|
|
|
- margin-bottom: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- }
|
|
|
- >p.subtitle{
|
|
|
- text-align: center;
|
|
|
- font-family: KaiTi, KaiTi;
|
|
|
- font-weight: 400;
|
|
|
- font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- color: rgba(255, 255, 255, 0.8);
|
|
|
- line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- margin-bottom: calc(6 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- }
|
|
|
- >h2{
|
|
|
- display: inline-block;
|
|
|
- margin-top: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- font-family: KaiTi, KaiTi;
|
|
|
- color: #FFFFFF;
|
|
|
- margin-top: 2em;
|
|
|
- margin-bottom: 0.5em;
|
|
|
- font-weight: 400;
|
|
|
- font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- }
|
|
|
- >.normal-text{
|
|
|
- font-family: KaiTi, KaiTi;
|
|
|
- color: #FFFFFF;
|
|
|
- font-weight: 400;
|
|
|
- font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
|
|
|
- text-align: justify;
|
|
|
- white-space: pre-line;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|