Kaynağa Gözat

feat: bambooHot

chenlei 1 yıl önce
ebeveyn
işleme
115f86998e

+ 1 - 0
.eslintrc.js

@@ -16,6 +16,7 @@ module.exports = {
     parser: '@babel/eslint-parser'
   },
   rules: {
+    'vue/multi-word-component-names': 'off',
     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     'semi': ['error', 'never'],

+ 33 - 0
mobile/index.html

@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+    <link rel="icon" href="<%= BASE_URL %>logo.ico">
+    <title>无尽藏</title>
+    <style>
+      .scroller{
+        touch-action: manipulation;
+      }
+      html,body,#app,.home{
+        touch-action: none;
+      }
+      .home{
+        position: relative;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- <script src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script> -->
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+
+    <script>
+      // new VConsole()
+    </script>
+  </body>
+</html>

+ 8 - 0
mobile/main.js

@@ -0,0 +1,8 @@
+import { createApp } from 'vue'
+import App from './views/MobileView.vue'
+import "@/assets/style/reset.css"
+import "@/assets/style/my-reset.css"
+
+const app = createApp(App)
+
+app.mount('#app')

+ 17 - 0
mobile/views/MobileView.vue

@@ -0,0 +1,17 @@
+<template>
+  <iframe
+    class="mobile-view"
+    src="/"
+  />
+</template>
+
+<style lang="less" setup>
+.mobile-view {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  width: 500px;
+  height: 100%;
+  transform: translateX(-50%);
+}
+</style>

+ 2 - 0
src/main.js

@@ -50,6 +50,8 @@ if (uaInfo.browser && uaInfo.browser.name === 'Safari') {
 }
 if (uaInfo.device.type === 'mobile') {
   app.provide('$isMobile', true)
+} else if (process.env.NODE_ENV === 'production') {
+  window.location.href = '/mobile.html'
 }
 
 // 处理resize事件

+ 1 - 1
src/router/index.js

@@ -7,7 +7,7 @@ import PaintingList from '../views/PaintingList.vue'
 import PaintingDetailList from '../views/PaintingDetailList.vue'
 import GameView from '../views/GameView.vue'
 import BambooBookView from '../views/BambooBookView.vue'
-import BambooHotView from '../views/BambooHotView.vue'
+import BambooHotView from '../views/BambooHotView2/index.vue'
 import ShuanggouDetail from '../views/ShuangGouSheSeDetail.vue'
 import ShuanggouPaintingDetail from '../views/ShuanggouPaintingDetail.vue'
 import OnlineSceneView from '../views/OnlineSceneView.vue'

BIN
src/views/BambooHotView2/images/bamboo1.png


BIN
src/views/BambooHotView2/images/bamboo10.png


BIN
src/views/BambooHotView2/images/bamboo11.png


BIN
src/views/BambooHotView2/images/bamboo12.png


BIN
src/views/BambooHotView2/images/bamboo13.png


BIN
src/views/BambooHotView2/images/bamboo14.png


BIN
src/views/BambooHotView2/images/bamboo2.png


BIN
src/views/BambooHotView2/images/bamboo3.png


BIN
src/views/BambooHotView2/images/bamboo4.png


BIN
src/views/BambooHotView2/images/bamboo5.png


BIN
src/views/BambooHotView2/images/bamboo6.png


BIN
src/views/BambooHotView2/images/bamboo7.png


BIN
src/views/BambooHotView2/images/bamboo8.png


BIN
src/views/BambooHotView2/images/bamboo9.png


BIN
src/views/BambooHotView2/images/bg.png


BIN
src/views/BambooHotView2/images/btn_start-min.png


BIN
src/views/BambooHotView2/images/grass.png


BIN
src/views/BambooHotView2/images/hot.png


BIN
src/views/BambooHotView2/images/leaf.png


BIN
src/views/BambooHotView2/images/leaf2.png


+ 592 - 0
src/views/BambooHotView2/index.vue

@@ -0,0 +1,592 @@
+<template>
+  <div style="height: 100%">
+    <div
+      v-if="hotVisible"
+      class="bamboo-hot2-hot"
+    >
+      <div class="bamboo-hot2-hot__title">
+        {{ ITEM_INFO_MAP[checkedHotId].label }}
+      </div>
+
+      <div
+        class="bamboo-hot2-hot__inner"
+        v-html="ITEM_INFO_MAP[checkedHotId].info"
+      />
+    </div>
+
+    <div
+      ref="bambooWrap"
+      class="bamboo-hot2"
+      :class="{
+        'wrap-hide': hotVisible
+      }"
+      @touchstart="handleTouchstart"
+      @touchmove="handleTouchmove"
+      @touchend="handleTouchend"
+    >
+      <div
+        class="bamboo-hot2-b1"
+        :class="{
+          hide: hotVisible && checkedHotId !== 1
+        }"
+      >
+        <img src="./images/bamboo1.png">
+
+        <div
+          class="bamboo-hot2__hot"
+          :class="{
+            hide: hotVisible
+          }"
+          @click="handleHot(1)"
+        >
+          <p>水竹</p>
+        </div>
+      </div>
+
+      <div
+        class="bamboo-hot2-b2"
+        :class="{
+          hide: hotVisible && checkedHotId !== 2
+        }"
+      >
+        <img src="./images/bamboo2.png">
+      </div>
+      <div
+        class="bamboo-hot2__hot b2"
+        :class="{
+          hide: hotVisible
+        }"
+        @click="handleHot(2)"
+      >
+        <p>紫竹</p>
+      </div>
+
+      <div
+        class="bamboo-hot2-b3"
+        :class="{
+          hide: hotVisible && checkedHotId !== 3
+        }"
+      >
+        <img src="./images/bamboo3.png">
+
+        <div
+          class="bamboo-hot2__hot"
+          :class="{
+            hide: hotVisible
+          }"
+          @click="handleHot(3)"
+        >
+          <p>梅鹿竹</p>
+        </div>
+      </div>
+
+      <div
+        class="bamboo-hot2-b4"
+        :class="{
+          hide: hotVisible && checkedHotId !== 4
+        }"
+      >
+        <img src="./images/bamboo4.png">
+
+        <div
+          class="bamboo-hot2__hot"
+          :class="{
+            hide: hotVisible
+          }"
+          @click="handleHot(4)"
+        >
+          <p>楠竹</p>
+        </div>
+      </div>
+
+      <div
+        class="bamboo-hot2-b5"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo5.png">
+      </div>
+
+      <div
+        class="bamboo-hot2-b6"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo6.png">
+      </div>
+
+      <div
+        class="bamboo-hot2-b7"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo7.png">
+      </div>
+
+      <div
+        class="bamboo-hot2-b8"
+        :class="{
+          hide: hotVisible && checkedHotId !== 8
+        }"
+      >
+        <img src="./images/bamboo8.png">
+
+        <div
+          class="bamboo-hot2__hot"
+          :class="{
+            hide: hotVisible
+          }"
+          @click="handleHot(8)"
+        >
+          <p>单竹</p>
+        </div>
+      </div>
+
+      <div
+        class="bamboo-hot2-b9"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo9.png">
+      </div>
+      <div
+        class="bamboo-hot2-b10"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo10.png">
+      </div>
+      <div
+        class="bamboo-hot2-b11"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo11.png">
+      </div>
+      <div
+        class="bamboo-hot2-b12"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo12.png">
+      </div>
+      <div
+        class="bamboo-hot2-b13"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo13.png">
+      </div>
+      <div
+        class="bamboo-hot2-b14"
+        :class="{
+          hide: hotVisible
+        }"
+      >
+        <img src="./images/bamboo14.png">
+      </div>
+
+      <div
+        ref="bambooWrapBg"
+        class="bamboo-hot2-bg-wrap"
+      >
+        <img
+          class="bamboo-hot2__grass"
+          :class="{
+            hide: hotVisible
+          }"
+          src="./images/grass.png"
+        >
+
+        <img
+          class="bamboo-hot2__bg"
+          src="./images/bg.png"
+        >
+      </div>
+    </div>
+
+    <div class="system-btns">
+      <BtnBack @click="goBack" />
+      <OperationTip
+        id="operationH"
+        class="operation-h"
+        text=""
+        direction="h"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+import useSizeAdapt from "@/useFunctions/useSizeAdapt"
+
+const ITEM_SCROLL_MAP = {
+  1: 10,
+  2: 166,
+  3: 231,
+  4: 420,
+  8: 958
+}
+const ITEM_INFO_MAP = {
+  1: {
+    label: '水竹',
+    info: `
+      <p>篷耳小,形状为卵形或长椭圆形。</p>
+      <p>锋舌边缘生有短白纤毛。</p>
+      <p>筝片直立,呈三角形至狭长三角形。</p>
+    `
+  },
+  2: {
+    label: '紫竹',
+    info: `
+      <p>紫竹幼竿绿色,覆盖细柔毛和白粉,</p>
+      <p>幕环有毛,籍鞘背面红褐色或绿色加深。</p>
+      <p>叶片小而薄,窄披针形。</p>
+    `
+  },
+  3: {
+    label: '梅鹿竹',
+    info: `
+      <p>梅鹿竹斑纹相连,圆形,</p>
+      <p>外轮廓深色,斑心发白。</p>
+      <p>竹地上有兽斑状斑痕,酷似梅花鹿的花纹。</p>
+    `
+  },
+  4: {
+    label: '楠竹',
+    info: `
+      <p>单轴散生型常绿乔木状竹类植物,</p>
+      <p>呈直立状,</p>
+      <p>竹叶深绿,</p>
+      <p>呈披针形</p>
+    `
+  },
+  8: {
+    label: '单竹',
+    info: `
+      <p>竹质细腻,纤维韧性极强,</p>
+      <p>可制成薄如蝉翼的竹篾丝,</p>
+      <p>编织成绸似、绢似的精美竹编工艺品。</p>
+    `
+  },
+}
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt()
+const router = useRouter()
+let startX = 0
+let lastStartX = 0
+const bambooWrap = ref()
+const bambooWrapBg = ref()
+
+const hotVisible = ref(false)
+const checkedHotId = ref(0)
+
+const handleHot = (id) => {
+  checkedHotId.value = id
+  hotVisible.value = true
+
+  bambooWrap.value.scrollTo({
+    left: ITEM_SCROLL_MAP[id],
+    behavior: 'smooth'
+  })
+
+  lastStartX = ITEM_SCROLL_MAP[id]
+}
+
+const handleTouchstart = (v) => {
+  if (hotVisible.value) return
+
+  startX = v.changedTouches[0].pageX
+}
+const handleTouchmove = (v) => {
+  v.preventDefault()
+  if (hotVisible.value) return
+
+  const wrapWidth = bambooWrapBg.value.scrollWidth - window.innerWidth
+  const moveX = startX - v.changedTouches[0].pageX
+
+  bambooWrap.value.scrollTo({
+    left: Math.min(moveX + lastStartX, wrapWidth),
+    behavior: 'instant'
+  })
+}
+const handleTouchend = (v) => {
+  if (hotVisible.value) return
+
+  const wrapWidth = bambooWrapBg.value.scrollWidth - window.innerWidth
+  lastStartX = Math.min(Math.max(startX - v.changedTouches[0].pageX + lastStartX, 0), wrapWidth)
+}
+
+const goBack = () => {
+  if (hotVisible.value) {
+    hotVisible.value = false
+    checkedHotId.value = 0
+    return
+  }
+
+  router.push({
+    name: 'MoreContent',
+    query: {
+      anchorIdx: 0,
+    }
+  })
+}
+</script>
+
+<style lang="less" scoped>
+::-webkit-scrollbar {
+  display: none;
+}
+
+img {
+  pointer-events: none;
+}
+
+.hide {
+  opacity: 0 !important;
+}
+
+[class^="bamboo-hot2-b"] {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  z-index: 3;
+
+  img {
+    height: 100%;
+  }
+}
+
+.bamboo-hot2-hot {
+  display: flex;
+  position: fixed;
+  top: 50%;
+  right: calc(70 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+  transform: translateY(-50%);
+  color: white;
+  font-family: KaiTi;
+  writing-mode: vertical-rl;
+  white-space: nowrap;
+  z-index: 999;
+
+  &__title {
+    position: relative;
+    margin-bottom: calc(90 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    font-weight: bold;
+    letter-spacing: 5px;
+    font-size: calc(38 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: calc(-2 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      right: calc(25 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      width: calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      height: calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      border-radius: 50%;
+      border: 1px solid #F8DD86;
+      z-index: -1;
+    }
+  }
+  &__inner {
+    letter-spacing: 3px;
+    line-height: calc(40 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    font-size: calc(20 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+  }
+}
+
+.bamboo-hot2 {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  perspective: calc(100 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+  transform-style: preserve-3d;
+  overflow-x: auto;
+
+  > * {
+    opacity: 1;
+    transition: all linear .2s;
+  }
+  &__hot {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: absolute;
+    color: white;
+    font-size: 12px;
+    font-family: KaiTi;
+    writing-mode: vertical-rl;
+
+    &::before {
+      content: '';
+      display: block;
+      margin-bottom: calc(5 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      width: 20px;
+      height: 20px;
+      background: url('./images/hot.png') no-repeat center / contain;
+    }
+  }
+  &-b1 {
+    left: calc(50 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+
+    .bamboo-hot2__hot {
+      top: calc(340 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      right: calc(40 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    }
+  }
+  &-b2 {
+    left: calc(250 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+    z-index: 2;
+  }
+  .bamboo-hot2__hot.b2 {
+    top: calc(200 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    left: calc(305 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+    z-index: 4;
+  }
+  &-b3 {
+    left: calc(155 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(5px);
+
+    .bamboo-hot2__hot {
+      top: calc(300 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      right: calc(110 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    }
+  }
+  &-b4 {
+    left: calc(600 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(5px);
+
+    .bamboo-hot2__hot {
+      top: calc(220 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      right: calc(14 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    }
+  }
+  &-b5 {
+    left: calc(1050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+  }
+  &-b6 {
+    left: calc(1170 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(15px);
+  }
+  &-b7 {
+    left: calc(1050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+    z-index: 2;
+  }
+  &-b8 {
+    left: calc(1180 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(5px);
+
+    .bamboo-hot2__hot {
+      top: calc(320 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+      right: calc(110 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    }
+  }
+  &-b9 {
+    left: calc(1480 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+  }
+  &-b10 {
+    left: calc(1810 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+  }
+  &-b11 {
+    left: calc(1790 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(5px);
+    z-index: 2;
+  }
+  &-b12 {
+    left: calc(1600 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(15px);
+    z-index: 2;
+  }
+  &-b13 {
+    left: calc(2050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(15px);
+    z-index: 2;
+  }
+  &-b14 {
+    left: calc(2220 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(10px);
+  }
+  &.wrap-hide {
+    &::before,
+    &::after {
+      opacity: 0;
+    }
+  }
+  &::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: calc(457 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    height: calc(330 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    background: url('./images/leaf.png') no-repeat center / contain;
+    opacity: 1;
+    transition: opacity linear .2s;
+    z-index: 3;
+  }
+  &::after {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: calc(1600 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    width: calc(689 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    height: calc(276 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    background: url('./images/leaf2.png') no-repeat center / contain;
+    opacity: 1;
+    transition: opacity linear .2s;
+    z-index: 3;
+  }
+  &-bg-wrap {
+    width: fit-content;
+    height: 100%;
+    position: relative;
+    z-index: 1;
+  }
+  &__grass {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    z-index: 1;
+  }
+  &__bg {
+    height: 100%;
+  }
+}
+
+.system-btns {
+  width: 100%;
+  padding: 0 calc(20 / v-bind(windowSizeWhenDesignForRef) * v-bind(windowSizeInCssForRef));
+  display: flex;
+  // flex-direction: column;
+  justify-content: flex-end;
+  position: absolute;
+  bottom: calc(60 /v-bind(windowSizeWhenDesignForRef) * v-bind(windowSizeInCssForRef));
+  z-index: 2;
+
+  .operation-h {
+    width: calc(36 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transition: opacity 0.5s ease-in-out;
+  }
+}
+</style>

+ 12 - 0
vue.config.js

@@ -8,6 +8,18 @@ const time = dayjs().format('YYYY-M-D HH:mm:ss')
 process.env.VUE_APP_UPDATE_TIME = time
 
 module.exports = defineConfig({
+  pages: {
+    mobile: {
+      template: 'mobile/index.html',
+      entry: 'mobile/main.js',
+      filename: 'mobile.html'
+    },
+    index: {
+      template: 'public/index.html',
+      entry: 'src/main.js',
+      filename: 'index.html'
+    }
+  },
   publicPath: process.env.PUBLIC_PATH,
   productionSourceMap: process.env.VUE_APP_CLI_MODE === 'prod' ? false : true,
   // transpileDependencies: true, // 默认false,表示babel-loader 会忽略所有 node_modules 中的文件