瀏覽代碼

fix: ipad的适配

lvkun996 2 年之前
父節點
當前提交
eecf7a3190

+ 5 - 0
package-lock.json

@@ -2160,6 +2160,11 @@
       "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz",
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
     },
+    "hammerjs": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
+      "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ=="
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",

+ 1 - 0
package.json

@@ -52,6 +52,7 @@
     "@dcloudio/uni-mp-weixin": "3.0.0-alpha-3061620221230002",
     "@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3061620221230002",
     "@rive-app/canvas": "^1.0.102",
+    "hammerjs": "^2.0.8",
     "js-base64": "^3.7.5",
     "less-loader": "^6.2.0",
     "pinia": "^2.0.33",

二進制
src/assets/block-rect.png


二進制
src/assets/luojigou-dog.png


二進制
src/assets/trumptPng.png


+ 229 - 110
src/components/luojigou-board/luojigou-board.vue

@@ -4,9 +4,9 @@
       <image class="board-img" :src="boardUrl" />
       <view class="board-header" id="game-label">
         <view class="trumpt" @click="emits('playAudio')">
-          <image class="dog" :src="staticImg.trumptDog"   />
+          <!-- <image class="dog" :src="staticImg.trumptDog"   /> -->
           <image
-            class="trumpt-icon"
+            class="trumpt-icon dog"
             :src="props.playLoading ? staticImg.trumptGif : staticImg.trumptPng"
           />
         </view>
@@ -19,19 +19,16 @@
             {{props.cardDesc ? props.cardDesc : "加載中"}}
           </scroll-view>
         </view>
+        <image
+          class="luojigou-dog"
+          :src="staticImg.luojigouDog"
+        />
       </view>
-      <view  class="card" >
-          <view class="ques" ref="quesRef" id="quesRef" >
-            <image :src="props.board.quesUrl" alt="" />
-          </view>
-          <view class="ans" ref="ansRef" id="ansRef">
-            <image :src="props.board.ansUrl" alt="" />
-          </view>
-      </view>
-    </view>
-<!-- 
-      v-show="props.tipsButton === 1" -->
-    <view
+      <view  class="card" :style="{zIndex: viewZindex.quesView}"  >
+        <view class="ques"  id="quesRef" >
+          <image id="ques-url"  :src="props.board.quesUrl" alt=""  />
+        </view>
+        <!-- <view
       class="mark-button"
       :style="{
         width: 357 * rate + 'rpx', 
@@ -56,25 +53,32 @@
           opacity: props.tipsButton === 1 ? 1 : 0
         }"
       />
-    </view>
+        </view> -->
+      </view>
+     
+      <view class="ans"  id="ansRef">
+        <image :src="props.board.ansUrl" alt="" />
+      </view>
 
-    <movable-area 
+      <movable-area 
       v-if="props.cardType !== undefined" 
-      class="movable-area" 
+      class="movable-area"
       id="movableAreaRef" 
-      :style="{ 
-        width: 357 * rate + 'rpx', 
-        height: 466 * rate + 'rpx',
-        top: 102 * rate + 'rpx', 
-        left: '50%', 
-        transform: 'translateX(-50%)'
+      :style="{
+        width: 357 * rate+ 'rpx', 
+        height: 466 * rate  + 'rpx',
+        top: 102 * rate / adaptatio + 'rpx', 
+        left: 50  + '%',
+        transform: `translateX(-${50}%)`,
+        zIndex: viewZindex.moveView,
+        scale: 1 / adaptatio
       }"
     >
       <movable-view
         v-for="item in buttons"
         :key="item.id"
         :disabled="item.disabled"
-        :x="item.x"
+        :x="item.x  "
         :y="item.y"
         damping="100"
         direction="all"
@@ -82,7 +86,7 @@
         :style="{
           zIndex: item.zIndex, 
           width: 46 * rate + 'rpx', 
-          height: 46 * rate + 'rpx',
+          height: 46 * rate+ 'rpx',
         }"
         @touchend="touchend($event, item)"
         @touchstart="touchStart(item)"
@@ -100,17 +104,26 @@
           :src="staticImg.successFlag"
         />
       </movable-view>
-    </movable-area>
+      </movable-area>
+
+    </view>
+
   </view>
+
+
+  <!-- <audio :src="audioSrc" autoplay ></audio> -->
+
 </template>
 
 
 <script setup lang="ts" name="luojigou-board" >
-import { defineProps, reactive, ref, computed, getCurrentInstance, defineEmits,watch } from 'vue'
+import { defineProps, reactive, ref, computed, getCurrentInstance, defineEmits, watch } from 'vue'
 import { useStaticImg, useSchedulerOnce, useQueryElInfo, useAdaptationIpadAndPhone } from '@/hooks/index'
 import type { CardModeEnum } from '@/enum/constant';
 import { useCalcQuantityStore } from '@/store/index';
 import { AudioController } from '@/controller/AudioController';
+import Hammer from 'hammerjs'
+import { onMounted } from 'vue';
 
 interface Buttons {
   id: number,
@@ -134,6 +147,7 @@ interface IProps {
   playLoading: boolean,
   getExpose: (records: any) => void
   tipsButton: number
+  audioSrc: string
 }
 
 const staticImg = useStaticImg()
@@ -148,9 +162,21 @@ const emits = defineEmits(['playAudio', 'submit'])
 
 const state = reactive({
   zIndex: 0, // 暂存zIndex
-  disabled: false, // 是否禁用moveview
-  correctQuantity: 0, // 正确数量()
-  totalQuantity: 0 // 总数量 (移动按钮数量)
+  scale: 1
+})
+
+const viewZindex = ref({
+  moveView: 30,
+  quesView: 31
+})
+
+
+// 手势操作题卡图片的state
+const hammerState = reactive({
+  x: 0, // 记录水平方向上的偏移量
+  y: 0, // 记录垂直方向上的偏移量
+  scaleCount: 2,
+  scaleIndex: 1
 })
 
 const colorMap = new Map([
@@ -169,17 +195,8 @@ const ansRef = ref<UniApp.NodeInfo>()
 const quesRef = ref<UniApp.NodeInfo>()
 const movableAreaRef = ref<UniApp.NodeInfo>()
 
-useQueryElInfo('#quesRef', (nodeInfo) => {
-  console.log('#quesRef:', nodeInfo);
-  
-  quesRef.value = nodeInfo as UniApp.NodeInfo
-  
-}, getCurrentInstance()!)
-useQueryElInfo('#ansRef', (nodeInfo) => {
-  console.log('ansRef.value:',nodeInfo );
-  
-  ansRef.value = nodeInfo as UniApp.NodeInfo
-}, getCurrentInstance()!)
+useQueryElInfo('#quesRef', (nodeInfo) => quesRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)
+useQueryElInfo('#ansRef', (nodeInfo) =>  ansRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)
 useQueryElInfo('#movableAreaRef', (nodeInfo) => movableAreaRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)
 
 const baseRatio = adaptatio
@@ -202,15 +219,13 @@ const TPos = (x: number, y: number) => {
 }
 
 const getButtonIndex = (_y: number) =>  {
-  console.log(_y, ansItemHeight.value);
+  console.log('ansItemHeight.value', ansItemHeight.value);
   
  return Math.floor(_y / ansItemHeight.value)
 }
 
 const getButtonPosByIndex = (index: number) => {
-
-  console.log("quesRef.value:", quesRef.value?.width);
-  console.log("ansRef.value:", ansRef.value.width);
+  console.log('getButtonPosByIndex:',  ansRef.value?.width!,  quesRef.value?.width! );
   
   const x = ansRef.value?.width! + quesRef.value?.width! 
  
@@ -219,9 +234,6 @@ const getButtonPosByIndex = (index: number) => {
   return { x, y }
 }
 
-
-
-
 const buttonWidth = 46 * windowWidth / 375 * baseRatio
 
 const VSpace = props.cardType === 0 ?Math.floor(windowWidth / 375 * 26) * baseRatio + buttonWidth : Math.floor(windowWidth / 375 * 8) * baseRatio + buttonWidth
@@ -232,12 +244,12 @@ const getX = (index: number) => index * VSpace + Math.floor(windowWidth / 375 *
 
 // 注意一下四钮 用哪几个颜色的按钮
 let buttons = reactive<Buttons[]>([
-  {id: 0, ans: null, x: getX(0), y: Y * rate,disabled: false, initX: getX(0), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.red, color: 'red' },
-  {id: 1, ans: null, x: getX(1), y: Y * rate,disabled: false, initX: getX(1), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.blue, color: 'blue' },
-  {id: 2, ans: null, x: getX(2), y: Y * rate,disabled: false, initX: getX(2), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.green, color: 'green' },
-  {id: 3, ans: null, x: getX(3), y: Y * rate,disabled: false, initX: getX(3), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.orange, color: 'orange' },
-  {id: 4, ans: null, x: getX(4), y: Y * rate,disabled: false, initX: getX(4), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.yellow, color: "yellow" },
-  {id: 5, ans: null, x: getX(5), y: Y * rate,disabled: false, initX: getX(5), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.purple, color: 'purple' },
+  {id: 0, ans: null, x: getX(0), y: Y * rate  , disabled: false, initX: getX(0), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.red, color: 'red' },
+  {id: 1, ans: null, x: getX(1), y: Y * rate  , disabled: false, initX: getX(1), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.blue, color: 'blue' },
+  {id: 2, ans: null, x: getX(2), y: Y * rate  , disabled: false, initX: getX(2), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.green, color: 'green' },
+  {id: 3, ans: null, x: getX(3), y: Y * rate  , disabled: false, initX: getX(3), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.orange, color: 'orange' },
+  {id: 4, ans: null, x: getX(4), y: Y * rate  , disabled: false, initX: getX(4), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.yellow, color: "yellow" },
+  {id: 5, ans: null, x: getX(5), y: Y * rate  , disabled: false, initX: getX(5), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.purple, color: 'purple' },
 ])
 
 buttons.splice(props.cardType == 1 ?  buttons.length : buttons.length - 2, buttons.length)
@@ -251,14 +263,10 @@ const disPatchButtonGoInitPos = (index: number) => {
     buttons[index].index = -1
     buttons[index].ans = null
   })
-
-  useSchedulerOnce(() => {
-    state.disabled = false
-  }, 200)
-
 }
 
 const touchStart = (item: Buttons) => {
+  viewZindex.value.moveView = viewZindex.value.quesView + 1
   useSchedulerOnce(() => {
     state.zIndex ++
     item.zIndex = state.zIndex
@@ -274,7 +282,6 @@ const touchend = (ev: TouchEvent, item: Buttons) => {
 
   console.log("itemY:", itemY);
   
-
   // 返回原点 (没有放在答案区, 按钮回到初始位置)
   if (itemX < quesRef.value?.width! || itemY > ansRef.value?.height! ) {
     disPatchButtonGoInitPos(item.id)
@@ -303,6 +310,9 @@ const touchend = (ev: TouchEvent, item: Buttons) => {
           //   const oldPos = getButtonPosByIndex(item.index)
           //   buttons[isHasIndex].x = oldPos.x
           //   buttons[isHasIndex].y = oldPos.y
+
+
+
           //   buttons[isHasIndex].index = item.index
           // })
         }
@@ -319,6 +329,11 @@ const touchend = (ev: TouchEvent, item: Buttons) => {
 
     }
   }
+
+
+  // 每次松手后把题卡的zIndex提高1
+  viewZindex.value.quesView = viewZindex.value.moveView + 1
+
 }
 
 // 判断答案 (学习计划适用逻辑)
@@ -338,8 +353,11 @@ const checkAns = (index: number, itemData: Buttons) => {
   } else { // 移动到了錯誤位置
 
     AudioController.playWrong()
+
     calcQuantityStore.wrongCount++
 
+    itemData.disabled = true
+
     itemData.ans = null
 
     const rockNode = document.getElementById(`rock-id-${itemData.id}`)
@@ -348,8 +366,8 @@ const checkAns = (index: number, itemData: Buttons) => {
 
     useSchedulerOnce(() => {
       disPatchButtonGoInitPos(itemData.id)
-      
       rockNode?.classList.remove('rock-button-ani')
+      itemData.disabled = false
     }, 1000)
   }
   
@@ -364,6 +382,88 @@ const checkAns = (index: number, itemData: Buttons) => {
   }
 }
 
+
+
+// 让题卡图片支持双指捏合
+const createHammer = () => {
+  var square = document.querySelector('#ques-url');
+  var hammer = new Hammer(square);
+  hammer.get('pinch').set({ enable: true });
+  
+  hammer.on('pinchmove pinchstart pinchin pinchout', (e) => {
+    if (e.type == "pinchstart") { 
+      hammerState.scaleIndex = hammerState.scaleCount || 1
+    }
+    if (hammerState.scaleIndex * e.scale <= 1) {
+      hammerState.scaleCount  = 1
+      hammerState.scaleIndex = 1
+      return
+    }
+  
+    hammerState.scaleCount = hammerState.scaleIndex * e.scale;
+    console.log(hammerState.scaleCount);
+    
+    document.getElementById('quesRef')!.style.transform = `scale(${hammerState.scaleIndex * e.scale})`
+  })
+
+  hammer.on('panright panleft panup pandown', (e) => {
+    document.getElementById('quesRef')!.style.transform = "translateX(" + (e.deltaX + hammerState.x) + "px)" + "translateY(" + (e.deltaY + hammerState.y) + "px)" + "scale(" + (hammerState.scaleCount) + ")"; 
+  });
+
+  hammer.on('doubletap', (e) => {
+    hammerState.x = 0;
+    hammerState.y = 0;
+    hammerState.scaleCount = 1; // 重置缩放比例为1
+    document.getElementById('quesRef')!.style.transform = "translateX(0px) translateY(0px) scale(1)"; // 重置位置和缩放效果
+  });
+
+  hammer.on('panend', (e) => {
+    hammerState.x = e.deltaX + hammerState.x; // 记录水平方向上的偏移量
+    hammerState.y = e.deltaY + hammerState.y; // 记录垂直方向上的偏移量
+    console.log(hammerState.x);
+    
+    const node = document.getElementById('quesRef')
+ 
+    if (hammerState.scaleCount <= 1) {
+ 
+      node!.style.transform = `translateX(0px) translateY(0px) scale(1)`
+      hammerState.x = 0
+      hammerState.y = 0
+      hammerState.scaleCount = 1
+      hammerState.scaleIndex  = 1
+    } else {
+      detectionEdge(0, 0)
+    }
+  });
+
+
+  // 放大后拖拽露出边缘后, 回弹的判定函数 回弹条件是当前放大的倍数 * 题卡的(宽/高)
+  const detectionEdge = (x: number, y: number) => {
+    const node = document.getElementById('quesRef')
+
+    const top = (quesRef.value?.height! * hammerState.scaleCount -  quesRef.value?.height!) / 2
+    const bottom = -top
+    const left = (quesRef.value?.width! * hammerState.scaleCount -  quesRef.value?.width!) / 2
+    const right = -left
+   
+
+    if ( Math.abs(hammerState.y)  > top) {
+      hammerState.y = hammerState.y > 0 ? top: bottom
+    } 
+     if ( Math.abs(hammerState.x)  > left) {
+      hammerState.x = hammerState.x > 0 ? left: right 
+    }
+
+    node!.style.transform = `translateX(${hammerState.x}px) translateY(${hammerState.y}px) scale(${hammerState.scaleCount})`
+   
+  }
+
+}
+
+onMounted(() => {
+  createHammer()
+})
+
 </script>
 
 <style lang="less" scoped >
@@ -404,8 +504,8 @@ const checkAns = (index: number, itemData: Buttons) => {
             z-index: 1;
           }
           .trumpt-icon {
-            width: 40rpx;
-            height: 40rpx;
+            // width: 40rpx;
+            // height: 40rpx;
             position: absolute;
             z-index: 2;
             right: -12rpx;
@@ -423,38 +523,56 @@ const checkAns = (index: number, itemData: Buttons) => {
           top: 50rpx;
           left: 176rpx;
         }
+        .luojigou-dog {
+          width: 84rpx;
+          height: 84rpx;
+          position: absolute;
+          right: 46rpx;
+          top: -48rpx;
+        }
       }
       .card {
-        width: 606rpx;
-        height: 772rpx;
-        border-radius: 40rpx;
-        overflow: hidden;
-        display: flex;
-        justify-content: space-between;
         position: absolute;
         top: 206rpx;
         left: 26rpx;
         z-index: 2;
+        width: 450rpx;
+        height: 772rpx;
+        overflow: hidden;
+        border-top-left-radius: 40rpx;
+        border-bottom-left-radius: 40rpx;
       }
       .ques {
         width: 450rpx;
         height: 772rpx;
         border-right: 2rpx solid #006CAA;
+        border-top-left-radius: 40rpx;
+        border-bottom-left-radius: 40rpx;
+        overflow: hidden;
+        touch-action: none !important;
+        scale: 1;
+        box-sizing: border-box;
         image {
           width: 100%;
           height: 100%;
           display: block;
+          // border-top-left-radius: 40rpx;
+          // border-bottom-left-radius: 40rpx;
         }
       }
       .ans {
-        width: 170rpx;
-        height: 100%;
+        width: 150rpx;
+        height: 772rpx;
         display: flex;
         flex-direction: column;
         border-top-right-radius: 40rpx;
         border-bottom-right-radius: 40rpx;
         overflow: hidden;
         background-color: #fff;
+        position: absolute;
+        top: 206rpx;
+        left: 476rpx;
+        z-index: 2;
         image {
             width: 100%;
             height: 100%;
@@ -477,6 +595,45 @@ const checkAns = (index: number, itemData: Buttons) => {
           top: 0;
         }
       }
+
+      .movable-area {
+        width: 714rpx;
+        height: 984rpx;
+        background-color: transparent;
+        position: absolute;
+        top: 192rpx;
+        z-index: 30;
+        touch-action: none;
+        left: 0px;
+        -moz-transform: none;
+        -webkit-transform: none;
+        -o-transform: none;
+        -ms-transform: none;
+        transform: none;
+        transform-origin: 0% 0%;
+        .movable-view {
+          width: 92rpx;
+          height: 92rpx;
+          touch-action: none;
+          .movable-image {
+            width: 100%;
+            height: 100%;
+            transition: width 0.2s;
+            z-index: 1;
+          }
+
+          .success-flag {
+            width: 36rpx;
+            height: 26rpx;
+            display: block;
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+            z-index: 2;
+          }
+        }
+      }
   }
 
 
@@ -496,45 +653,7 @@ const checkAns = (index: number, itemData: Buttons) => {
   }
   
 
-  .movable-area {
-    width: 714rpx;
-    height: 984rpx;
-    background-color: transparent;
-    position: absolute;
-    top: 192rpx;
-    left: 50%;
-    transform: translateX(-50%);
-    z-index: 30;
-    touch-action: none;
-    left: 0px;
-    -moz-transform: none;
-    -webkit-transform: none;
-    -o-transform: none;
-    -ms-transform: none;
-    transform: none;
-    .movable-view {
-      width: 92rpx;
-      height: 92rpx;
-      touch-action: none;
-      .movable-image {
-        width: 100%;
-        height: 100%;
-        transition: width 0.2s;
-        z-index: 1;
-      }
-      
-      .success-flag {
-        width: 36rpx;
-        height: 26rpx;
-        display: block;
-        position: absolute;
-        top: 50%;
-        left: 50%;
-        transform: translate(-50%, -50%);
-        z-index: 2;
-      }
-    }
-  }
+
 
   .opra {
     width: 100vw;

+ 48 - 14
src/components/rive-ani/rive-ani.vue

@@ -1,5 +1,10 @@
 <template>
   <view class="rive-ani" id="rive-ani" v-if="state.comVisable" >
+
+    <view class="coin-max-tip"  v-if="state.maxTipVisible" :style="{backgroundImage: `url(${staticImg.blockRect})`, top: navbarInfo.top}" >
+      已达上限
+    </view>
+
     <view class="coin-total" :style="{top: navbarInfo.top }" >
       <span>{{wisdomCoinStore.total || 0}}</span>
       <view class="coin-logo" id="coin-logo" :animation="state.heartbeatAni" >
@@ -52,7 +57,8 @@ interface State {
   heartbeatAni: any,
   cointCount: number,
   comVisable: boolean,
-  cardType: 0 | 1
+  cardType: 0 | 1,
+  maxTipVisible: boolean
 }
 
 const state = reactive<Partial<State>>({
@@ -61,7 +67,8 @@ const state = reactive<Partial<State>>({
   heartbeatAni: null,
   cointCount: 0,
   comVisable: false,
-  cardType: 0
+  cardType: 0,
+  maxTipVisible: false
 })
 
 const staticImg = useStaticImg()
@@ -70,8 +77,6 @@ const wisdomCoinStore = useWisdomCoinStore()
 
 const navbarInfo = useNavbarInfo()
 
-const emit = defineEmits(['onEnd'])
-
 const coinLoginRef = ref()
 
 let rive: Rive
@@ -93,17 +98,12 @@ const initHeartbeatAni = () => {
 const initRive = () => {
 
   const canvas = document.createElement('canvas')
-
-  const ctx = canvas.getContext('2d');
-
   // const scale = window.devicePixelRatio;
   const scale = 1;
 
   canvas.width = 375 * scale;
   canvas.height = 375 * scale;
-
-  // ctx!.scale(scale, scale);
-
+  
   canvas.id = 'rive-canvas'
 
   canvas.style.position = 'absolute'
@@ -119,13 +119,16 @@ const initRive = () => {
     onLoad: () => {
       
       rive.resizeToCanvas()
+
+      console.log(rive);
+
       rive.play(AniEnum[state.cointCount! - 1])
       
       for (let i = 0; i < state.cointCount!; i++) {
        
         useSchedulerOnce( () => {
           AudioController.playCoinLight()
-        }, 1000 + i * 50)
+        }, 1200 + i * 100)
 
       }
     
@@ -149,7 +152,13 @@ const createAnimationStep = (animation: UniApp.Animation, count: number) => {
   for (let i = 0; i < count; i++) {
     state.animation.push(animation.step({duration: 400 + i * 200}).export())
     useSchedulerOnce(() => {
-      wisdomCoinStore.total ++
+      if (wisdomCoinStore.remainderWisdomCoin <= 0) {
+        state.maxTipVisible = true
+      } else {
+        wisdomCoinStore.total ++
+        wisdomCoinStore.remainderWisdomCoin--
+      }
+      
       document.getElementById(`coin-item-${i + 1}`)!.style.display = 'none'
       state.heartbeatAni = initHeartbeatAni()
     }, 400 + i * 200)
@@ -194,12 +203,19 @@ const start = async (starCount: number, cardType: 0 | 1) => {
   state.cardType = cardType
 
   if (cardType === 0) {
-    starCount <= 2 ?  AudioController.playFail() :  AudioController.playPass() 
+    starCount <= 2 ? AudioController.playFail() : AudioController.playPass()
   } else {
-    starCount <= 3 ?  AudioController.playFail() :  AudioController.playPass() 
+    starCount <= 3 ? AudioController.playFail() : AudioController.playPass()
   }
 
   useSchedulerOnce(initRive)
+
+
+  if (wisdomCoinStore.remainderWisdomCoin == 0) {
+    state.maxTipVisible = true
+  }
+
+
   
   nextTick(() => useQueryElInfo('#coin-logo', (res) => coinLoginRef.value = res, getCurrentInstance()!, false))
 
@@ -234,6 +250,24 @@ onMounted(() => {
   display: flex;
   align-items: center;
   justify-content: center;
+  .coin-max-tip {
+    width: 88px;
+    height: 33px;
+    background-size: 100%;
+    position: absolute;
+    right: 120px;
+    display: flex;
+    align-items: center;
+    background-repeat: no-repeat;
+    font-size: 14px;
+    font-family: PingFangSC-Semibold, PingFang SC;
+    font-weight: 600;
+    color: #FEFBFB;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-top: 2px;
+  }
   .coin-total {
     height: 36px;
     background: #414141;

+ 2 - 0
src/global.d.ts

@@ -18,4 +18,6 @@ declare global {
   }
 }
 
+
+
 export {}

+ 22 - 8
src/hooks/index.ts

@@ -146,20 +146,34 @@ export const useAudioMange = (src?: string) => {
   audioInstance.value = uni.createInnerAudioContext()
 
   if (src) {
+    console.log('src');
+    
     audioInstance.value.src = src
   }
 
   const destroy = () => audioInstance.value?.stop()
 
-  const repeat = () => {
-    
-  }
-
   const play = (src: string) => {
     audioInstance.value!.src = src
-    audioInstance.value?.play()
+    console.log(src, audioInstance.value);
+    
+    useSchedulerOnce(() => {
+      console.log('play');
+      audioInstance.value?.play()
+    }, 500)
+
   }
 
+  audioInstance.value.autoplay = true
+
+  audioInstance.value!.onCanplay((e) => {
+    console.log('onCanplay:111', e);
+  })
+
+  audioInstance.value?.onError((e) => {
+    console.log(e);
+  })
+
   const onplayend = (cb: Function) => audioInstance.value?.onEnded(() => cb && cb())
 
   onUnmounted(() => {
@@ -185,7 +199,7 @@ export const usePlatform = (): DEVICE.Platform => {
   const { uniPlatform } = uni.getSystemInfoSync()
 
   return uniPlatform as DEVICE.Platform
-  
+
 }
 
 
@@ -198,10 +212,10 @@ export const usePlatform = (): DEVICE.Platform => {
 export const useAdaptationIpadAndPhone = () => {
   
   const { windowWidth, windowHeight } = uni.getSystemInfoSync()
-
+  
   const rate = windowWidth / windowHeight
   
-  if ( rate > 0.6 ) { // 大于0.6 说明是平板
+  if ( rate > 0.5 ) { // 大于0.6 说明是平板 
     return 667 / ( windowHeight )
   } else {
     return 1

+ 1 - 1
src/main.ts

@@ -5,7 +5,7 @@ import staticImg from '@/utils/static'
 import VConsole from "vconsole"
 
 
-// new VConsole()
+new VConsole()
 
 
 export function createApp() {

+ 12 - 7
src/pages/GameView/index.vue

@@ -2,8 +2,9 @@
   <view
     class="game-view"
     id="game-view"
-    :style="`pointer-events: ${state.mode === CardModeEnum.PREVIEW ? 'none' : 'all'}`"
+   
   >
+  <!--  :style="`pointer-events: ${state.mode === CardModeEnum.PREVIEW ? 'none' : 'all'}`" -->
     <navbar
       @goback="goback"
       :="{
@@ -22,6 +23,7 @@
         :tipsButton="state.card.tipsButton"
         :cardDesc="state.card.cardDesc"
         :playLoading="state.playLoading"
+        :audioSrc="state.card.audio"
         @playAudio="playAudio"
         @submit="onSubmitCard"
       />
@@ -80,16 +82,16 @@ const base64 = useBase64()
 onLoad(query => {
 
   let options
-  if (import.meta.env.MODE !== "development") {
+  if (import.meta.env.MODE === "development") {
     state.queryParams = base64.decode<API.P>(query!.p)
     state.opraMode = state.queryParams.data.opraMode
     options = state.queryParams.data
   } else {
     console.log(query);
-    // state.queryParams = base64.decode<API.P>(query!.p)
-    // state.opraMode = state.queryParams.data.opraMode
-    // options = state.queryParams.data
-    options = query!
+    state.queryParams = base64.decode<API.P>(query!.p)
+    state.opraMode = state.queryParams.data.opraMode
+    options = state.queryParams.data
+    // options = query!
   }
   console.log(state.queryParams);
   
@@ -206,14 +208,18 @@ const gameCompleted = async () => {
   const data = await submitlearnPortAns($par, state.queryParams?.submitUrl!)
   
   opraRecordStore.clear()
+
   // 如果opraMode 的是learn 则跳转到app-web页面
   if (state.opraMode == OpraModeEnum.LEARN) {
+
     window.location.href = `https://nginx.test.luojigou.vip/app_web/learn-plan.html#/?from='exercise'`
   }
   
 }
 
 const playAudio = () => {
+  console.log('audio播放');
+  
   state.playLoading = true
   atx.play(state.card?.audio!)
   atx.onplayend(() => state.playLoading = false)
@@ -260,7 +266,6 @@ onMounted(async () => {
   if (state.mode === 'preview') {
     GetCardDetailById()
   } else {
-
     GetCollectionDetailById()
   }
 })

+ 1 - 1
src/service/index.ts

@@ -11,7 +11,7 @@ interface Params {
 }
 
 // const BASEURL = import.meta.env.MODE === 'development' ? 'http://local.luojigou.vip:8888' : 'https://open.api.luojigou.vip'
-const BASEURL = import.meta.env.MODE !== 'development' ? 'http://local.luojigou.vip:8888' : 'https://open.api.luojigou.vip'
+const BASEURL = import.meta.env.MODE === 'development' ? 'https://open.api.luojigou.vip' : 'https://open.api.luojigou.vip'
 //  'https://open.test.luojigou.vip'
 // window.location.href.split('#')[0] + 'zd-api'
 // https://open.test.luojigou.vip

+ 8 - 4
src/store/opraRecords.ts

@@ -1,17 +1,21 @@
 import { ConstantLocalStorage } from '@/utils/constant'
 import { ConstantStore } from '@/utils/constant'
 import { defineStore } from 'pinia'
+import { reactive } from 'vue'
 import { useLocalStorageState } from 'vue-hooks-plus'
 
 export const useOpraRecordStore = defineStore(ConstantStore.OPRARECORDS, () => {
 
-  const [ state, setState ] = useLocalStorageState<API.LearnPlanRecords[]>(ConstantLocalStorage.OPRARECORDS, {
-    defaultValue: []
+  const state = reactive<{value: API.LearnPlanRecords[]}>({value: []
   })
 
-  const _push = (records: any) => setState([...state.value!, records])
+  // const [ state, setState ] = useLocalStorageState<API.LearnPlanRecords[]>(ConstantLocalStorage.OPRARECORDS, {
+  //   defaultValue: []
+  // })
+
+  const _push = (records: any) => state.value.push(records)
   
-  const _clear = () => setState([])
+  const _clear = () => state.value = []
 
   const _get = () => state.value
 

+ 2 - 0
src/typing.d.ts

@@ -121,6 +121,8 @@ declare namespace DEVICE {
   type Platform = 'web' | 'mp-weixin'
 }
 
+declare module "hammerjs"
+
 
 
 

+ 10 - 2
src/utils/static.ts

@@ -19,6 +19,9 @@ import coinAni from '@/assets/coin-ani.png'
 import successFlag from '@/assets/success-flag.png'
 import arowRight from '@/assets/arow_right.png'
 import arowLeft from '@/assets/arowLeft.png'
+import blockRect from '@/assets/block-rect.png'
+import trumptPng from '@/assets/trumptPng.png'
+import luojigouDog from '@/assets/luojigou-dog.png'
 
 
 
@@ -68,6 +71,8 @@ export interface StaticImg {
   successFlag: string,
   arowRight: string,
   arowLeft: string
+  blockRect: string
+  luojigouDog: string
 }
 
 let staticImg: Partial<StaticImg> = {
@@ -89,13 +94,16 @@ let staticImg: Partial<StaticImg> = {
   step5,
   patternBg: 'http://res.training.luojigou.vip/FlizY8LG5PAF7GQyG88hijTsk4I6?imageView2/0/q/50|imageslim',
   trumptGif: 'https://app-resources-luojigou.luojigou.vip/FvTWQ036DVezuqiDuua4y3F9yzTJ',
-  trumptPng: 'https://app-resources-luojigou.luojigou.vip/FnahepHJN1cSRD03VEFLebxL5Br-',
+  // trumptPng: 'https://app-resources-luojigou.luojigou.vip/FnahepHJN1cSRD03VEFLebxL5Br-',
+  trumptPng: trumptPng,
   trumptDog: "https://app-resources-luojigou.luojigou.vip/Fgh59QZy8NO8qG9f8sXMU4Xv4SKW",
   coinTotal,
   coinAni,
   successFlag,
   arowRight,
-  arowLeft
+  arowLeft,
+  blockRect,
+  luojigouDog
 }