任一存 1 年之前
父节点
当前提交
b9c6f3239f
共有 10 个文件被更改,包括 176 次插入10 次删除
  1. 1 0
      package.json
  2. 10 1
      src/api.js
  3. 二进制
      src/assets/images/eye.png
  4. 二进制
      src/assets/images/like.png
  5. 二进制
      src/assets/images/liked.png
  6. 8 7
      src/main.js
  7. 9 0
      src/store/index.js
  8. 18 0
      src/utils.js
  9. 125 2
      src/views/CommonDrawList.vue
  10. 5 0
      yarn.lock

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@vueuse/core": "^10.4.1",
+    "animate.css": "^4.1.1",
     "axios": "^1.1.3",
     "clipboard": "^2.0.11",
     "core-js": "^3.8.3",

+ 10 - 1
src/api.js

@@ -1,4 +1,4 @@
-// import axios from "axios"
+import axios from "axios"
 
 // axios({
 //   method: 'post',
@@ -14,4 +14,13 @@
 // })
 
 export default {
+  getViewCount(idx) {
+    return Promise.resolve(625)
+  },
+  getLikeCount(idx) {
+    return Promise.resolve(125)
+  },
+  like(idx) {
+    return Promise.resolve(true)
+  }
 }

二进制
src/assets/images/eye.png


二进制
src/assets/images/like.png


二进制
src/assets/images/liked.png


+ 8 - 7
src/main.js

@@ -9,6 +9,7 @@ import clickOutside from "@/directives/v-click-outside.js"
 import mitt from "mitt"
 import 'viewerjs/dist/viewer.css'
 import VueViewer from 'v-viewer'
+import 'animate.css'
 
 console.log(`version: ${process.env.VUE_APP_VERSION}`)
 console.log(`Build time: ${process.env.VUE_APP_UPDATE_TIME}`)
@@ -79,19 +80,19 @@ app.use(store)
 
 //  you can reset the default options at any other time
 VueViewer.setDefaults({
-  inline: false,
+  backdrop: 'static', // 点击空白区域不会关闭
   button: true,
+  fullscreen: true,
+  inline: false,
+  keyboard: true,
+  movable: true,
   navbar: false,
+  rotatable: false,
   title: false,
   toolbar: false,
   tooltip: false,
-  movable: true,
-  zoomable: true,
-  rotatable: false,
-  // "scalable": true,
   transition: true,
-  fullscreen: true,
-  keyboard: true,
+  zoomable: true,
 })
 
 // 必须在vue根组件挂载之后执行

+ 9 - 0
src/store/index.js

@@ -11,6 +11,15 @@ import engravingPaperUrl from '@/assets/images/engraving-paper.png'
 
 export const hasShownForword = ref(false)
 
+export const likeRecord = ref([
+  false,
+  false,
+  false,
+  false,
+  false,
+  false,
+])
+
 export const toolList = ref([
   {
     name: '笔',

+ 18 - 0
src/utils.js

@@ -67,4 +67,22 @@ export default {
       return fn.apply(context, args)
     }
   },
+  animateCSS(element, animation, prefix = 'animate__') {
+    // We create a Promise and return it
+    return new Promise((resolve, reject) => {
+      const animationName = `${prefix}${animation}`
+      const node = typeof element === 'string' ? document.querySelector(element) : element
+
+      node.classList.add(`${prefix}animated`, animationName)
+
+      // When the animation ends, we clean the classes and resolve the Promise
+      function handleAnimationEnd(event) {
+        event.stopPropagation()
+        node.classList.remove(`${prefix}animated`, animationName)
+        resolve('Animation ended')
+      }
+
+      node.addEventListener('animationend', handleAnimationEnd, { once: true })
+    })
+  },
 }

+ 125 - 2
src/views/CommonDrawList.vue

@@ -25,6 +25,9 @@
           :src="`${imgPrefix}/${drawName}`"
           alt=""
           draggable="false"
+          @show="onViewerShow"
+          @hide="onViewerHide"
+          @inited="onViewerInit"
         >
       </li>
     </ul>
@@ -56,13 +59,42 @@
         name: 'EntryList',
       })"
     />
+
+    <div
+      v-show="isViewingBigImage"
+      class="show-on-mask"
+    >
+      <img
+        class="eye"
+        src="@/assets/images/eye.png"
+        alt=""
+        draggable="false"
+      >
+      <div class="view-count">
+        {{ viewCount }}
+      </div>
+      <button
+        class="like"
+        :class="{
+          liked: hasLiked,
+        }"
+        @click="onClickLike"
+      />
+      <div class="like-count">
+        {{ likeCount }}
+      </div>
+      <button
+        class="return"
+        @click="closeViewer"
+      />
+    </div>
   </div>
 </template>
 
 <script setup>
 import { ref, computed, } from "vue"
 import { useRoute, useRouter } from "vue-router"
-import { hasShownForword } from "@/store/index.js"
+import { hasShownForword, likeRecord } from "@/store/index.js"
 import { drawTree } from "@/assets/draw-tree.js"
 
 const {
@@ -86,9 +118,49 @@ const drawList = computed(() => {
 const imgPrefix = computed(() => {
   return `https://4dkk-culture.oss-cn-shenzhen.aliyuncs.com/LiangZhu/draws/${encodeURIComponent(groupL1Name)}/${encodeURIComponent(groupName.value)}`
 })
-</script>
 
+const isViewingBigImage = ref(false)
+function onViewerShow(e) {
+  isViewingBigImage.value = true
+}
+function onViewerHide(e) {
+  isViewingBigImage.value = false
+}
+function closeViewer() {
+  const closeBtn = document.querySelector('.viewer-close')
+  closeBtn.click()
+}
+
+const viewCount = ref(null)
+api.getViewCount(route.query.idx - 1).then((res) => {
+  viewCount.value = res
+})
+
+const likeCount = ref(null)
+api.getLikeCount(route.query.idx - 1).then((res) => {
+  likeCount.value = res
+})
+const hasLiked = computed(() => {
+  return likeRecord.value[route.query.idx - 1]
+})
+function onClickLike(e) {
+  if (hasLiked.value) {
+    return
+  }
+  likeRecord.value[route.query.idx - 1] = true
+  api.like(route.query.idx - 1)
+  setTimeout(() => {
+    utils.animateCSS(e.target, 'heartBeat')
+  }, 0)
+}
+</script>
 
+<style>
+.viewer-button{
+  width: 0 !important;
+  height: 0 !important;
+}
+</style>
 
 <style lang="less" scoped>
 .common-draw-list-view{
@@ -201,5 +273,56 @@ const imgPrefix = computed(() => {
       box-shadow: 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0px rgba(0,0,0,0.25);
     }
   }
+
+  >.show-on-mask{
+    position: absolute;
+    z-index: 2106;
+    right: 0;
+    bottom: 0;
+    width: calc(90 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    >img.eye{
+      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    >.view-count{
+      font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      font-family: Source Han Sans CN-Regular, Source Han Sans CN;
+      font-weight: 400;
+      color: #FFFFFF;
+      line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      margin-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    >button.like{
+      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      background-image: url(@/assets/images/like.png);
+      background-size: contain;
+      background-repeat: no-repeat;
+      background-position: center center;
+    }
+    >button.like.liked{
+      background-image: url(@/assets/images/liked.png);
+    }
+    >.like-count{
+      font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      font-family: Source Han Sans CN-Regular, Source Han Sans CN;
+      font-weight: 400;
+      color: #FFFFFF;
+      line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      margin-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    >button.return {
+      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      background-image: url(@/assets/images/icon_back@2x.png);
+      background-size: contain;
+      background-repeat: no-repeat;
+      background-position: center center;
+      margin-bottom: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+  }
 }
 </style>

+ 5 - 0
yarn.lock

@@ -1958,6 +1958,11 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0:
     require-from-string "^2.0.2"
     uri-js "^4.2.2"
 
+animate.css@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz#614ec5a81131d7e4dc362a58143f7406abd68075"
+  integrity sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==
+
 ansi-colors@^4.1.1:
   version "4.1.3"
   resolved "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"