Yansen před 2 roky
rodič
revize
a286619d7c

+ 1
- 0
package.json Zobrazit soubor

@@ -10,6 +10,7 @@
10 10
   },
11 11
   "dependencies": {
12 12
     "@splidejs/splide": "^4.1.4",
13
+    "@splidejs/vue-splide": "^0.6.12",
13 14
     "@zjxpcyc/vue-tiny-store": "^1.0.1",
14 15
     "animate.css": "^4.1.1",
15 16
     "axios": "^1.2.1",

binární
public/images/cloud-texture.png Zobrazit soubor


binární
public/images/pg3/1.png Zobrazit soubor


binární
public/images/pg3/1937.png Zobrazit soubor


binární
public/images/pg3/2.png Zobrazit soubor


binární
public/images/pg3/3.png Zobrazit soubor


binární
public/images/pg3/4.png Zobrazit soubor


binární
public/images/pg3/5.png Zobrazit soubor


binární
public/images/pg3/arrow.png Zobrazit soubor


binární
public/images/pg3/btn.png Zobrazit soubor


binární
public/images/pg3/header.png Zobrazit soubor


binární
public/images/pg3/jing.png Zobrazit soubor


binární
public/images/pg3/left-bg.png Zobrazit soubor


binární
public/images/pg3/nan.png Zobrazit soubor


binární
public/images/pg3/right-bg.png Zobrazit soubor


binární
public/images/pg3/stele.png Zobrazit soubor


binární
public/images/pg3/采访1.png Zobrazit soubor


binární
public/images/pg3/采访2.png Zobrazit soubor


binární
public/images/pg3/采访3.png Zobrazit soubor


binární
public/images/pg3/采访4.png Zobrazit soubor


binární
public/images/pg3/采访5.png Zobrazit soubor


+ 3
- 11
src/main.js Zobrazit soubor

@@ -1,5 +1,7 @@
1 1
 import { createApp } from 'vue'
2
+import VueSplide from '@splidejs/vue-splide';
2 3
 import 'animate.css'
4
+import '@splidejs/vue-splide/css/core';
3 5
 
4 6
 import App from './App.vue'
5 7
 import store from './store'
@@ -12,15 +14,5 @@ const app = createApp(App);
12 14
 app.use(store);
13 15
 app.use(router);
14 16
 app.use(i18n);
17
+app.use( VueSplide );
15 18
 app.mount('#app');
16
-
17
-// 播放第一个视频
18
-document.addEventListener('WeixinJSBridgeReady', () => {
19
-  const t = setTimeout(() => {
20
-    const vid = document.querySelector('#firstVideo');
21
-    console.log('-------------->', vid)
22
-    if (vid) {
23
-      vid.play();
24
-    }
25
-  }, 500);
26
-});

+ 111
- 0
src/pages/pg3/Ink.vue Zobrazit soubor

@@ -0,0 +1,111 @@
1
+<template>
2
+  <div class="ink-box">
3
+    <div>
4
+      <canvas class="ink-cover" ref="canvasRef"></canvas>
5
+      <!-- <img class="ink-back" :src="src" alt="" > -->
6
+    </div>
7
+  </div>
8
+</template>
9
+
10
+<script setup>
11
+  import { onBeforeMount, onMounted, ref, watch } from 'vue';
12
+
13
+  const canvasRef = ref();
14
+  const renderRef = ref();
15
+  const props = defineProps({
16
+    src: String,
17
+    active: Boolean,
18
+  })
19
+
20
+  let frameId = null;
21
+  let i = 0;
22
+
23
+  watch(() => props.active, (newVal, oldVal) => {
24
+    if (newVal && !oldVal) {
25
+      if (renderRef.value) {
26
+        i = 0;
27
+        renderRef.value();
28
+      }
29
+    }
30
+  })
31
+
32
+  onMounted(() => {
33
+    const canv = canvasRef.value;
34
+    const ctx = canv.getContext("2d");
35
+    const img = new Image();
36
+    const imgMask = new Image();
37
+    
38
+    img.onload = function() {
39
+      canv.width = img.naturalWidth;
40
+      canv.height = img.naturalHeight;
41
+    }
42
+
43
+    img.src = props.src;
44
+    imgMask.src = './images/cloud-texture.png'
45
+    
46
+    function draw() {
47
+      i += 5;
48
+      
49
+      let maskX = (canv.width - (70 + i)) / 2,
50
+          maskY = (canv.height - (40 + i)) / 2;
51
+      
52
+      ctx.clearRect(0, 0, canv.width, canv.height);
53
+      ctx.globalCompositeOperation = "source-over";
54
+      
55
+      ctx.drawImage(imgMask, maskX, maskY, 70 + i, 40 + i);
56
+      
57
+      ctx.globalCompositeOperation = "source-in";
58
+      ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
59
+      
60
+      frameId = window.requestAnimationFrame(draw);
61
+
62
+      if (i >= 5000) {
63
+        i = 0;
64
+        window.cancelAnimationFrame(frameId);
65
+      }
66
+    }
67
+
68
+    renderRef.value = draw;
69
+
70
+    if (props.active) {
71
+      draw();
72
+    }
73
+  });
74
+
75
+  onBeforeMount(() => {
76
+    if (frameId) {
77
+      window.cancelAnimationFrame(frameId);
78
+    }
79
+  });
80
+
81
+</script>
82
+
83
+<style lang="less" scoped>
84
+.ink-box {
85
+  width: 100%;
86
+  height: 100%;
87
+
88
+  & > div {
89
+    position: relative;
90
+    width: 100%;
91
+    height: 100%;
92
+
93
+    .ink-cover {
94
+      position: absolute;
95
+      width: 100%;
96
+      height: 100%;
97
+      top: 0;
98
+      left: 0;
99
+    }
100
+
101
+    .ink-back {
102
+      display: none;
103
+    }
104
+
105
+    img {
106
+      width: 100%;
107
+      height: 100%;
108
+    }
109
+  }
110
+}
111
+</style>

+ 183
- 39
src/pages/pg3/index.vue Zobrazit soubor

@@ -1,13 +1,59 @@
1 1
 <template>
2 2
   <div class="page pg-bg pg3" ref="pgRef">
3
+    <div class="pg3-bg">
4
+      <div>
5
+        <img class="bg-left abs" src="/images/pg3/left-bg.png" alt="">
6
+        <img class="bg-right abs" src="/images/pg3/right-bg.png" alt="">
7
+      </div>
8
+    </div>
3 9
     <Animate
4 10
       class="header"
5 11
       name="animate__zoomIn"
6 12
       delay="100ms"
7 13
       :ready="show"
8 14
     >
9
-      <img src="/images/pg3/header.png" alt="">
15
+      <p class="txt" style="text-align:center">
16
+        向<br />世<br />界<br />讲<br />述
17
+      </p>
10 18
     </Animate>
19
+    <div class="nanjing">
20
+      <div>
21
+        <Animate
22
+          comp="img"
23
+          src="/images/pg3/nan.png"
24
+          name="animate__zoomIn"
25
+          delay="100ms"
26
+          :ready="show"
27
+        />
28
+        <Animate
29
+          comp="img"
30
+          class="stele abs animate__slow"
31
+          src="/images/pg3/stele.png"
32
+          name="animate__fadeInUp"
33
+          delay="100ms"
34
+          :ready="show"
35
+        />
36
+      </div>
37
+      <div>
38
+        <Animate
39
+          comp="img"
40
+          src="/images/pg3/jing.png"
41
+          name="animate__zoomIn"
42
+          delay="500ms"
43
+          alt=""
44
+          :ready="show"
45
+        />
46
+      </div>
47
+    </div>
48
+    <Animate
49
+      class="nj-1937"
50
+      comp="img"
51
+      src="/images/pg3/1937.png"
52
+      name="animate__zoomIn"
53
+      delay="500ms"
54
+      alt=""
55
+      :ready="show"
56
+    />
11 57
     <div class="content">
12 58
       <Animate
13 59
         class="txt"
@@ -20,96 +66,194 @@
20 66
       </Animate>
21 67
     </div>
22 68
 
23
-    <div class="global-map">
24
-      <Map />
25
-    </div>
69
+    <Splide
70
+      :options="slideOptions"
71
+      :has-track="false"
72
+      @splide:moved="onSlideChange"
73
+    >
74
+      <div class="ink-slider-wrapper">
75
+        <SplideTrack>
76
+          <SplideSlide>
77
+            <Ink class="slide-ink" :active="slideIndexRef == 0" src="./images/pg3/1.png" />
78
+          </SplideSlide>
79
+          <SplideSlide>
80
+            <Ink class="slide-ink" :active="slideIndexRef == 1" src="./images/pg3/2.png" />
81
+          </SplideSlide>
82
+          <SplideSlide>
83
+            <Ink class="slide-ink" :active="slideIndexRef == 2" src="./images/pg3/3.png" />
84
+          </SplideSlide>
85
+          <SplideSlide>
86
+            <Ink class="slide-ink" :active="slideIndexRef == 3" src="./images/pg3/4.png" />
87
+          </SplideSlide>
88
+          <SplideSlide>
89
+            <Ink class="slide-ink" :active="slideIndexRef == 4" src="./images/pg3/5.png" />
90
+          </SplideSlide>
91
+        </SplideTrack>
92
+        <div class="splide__arrows abs" style="left: 0; top: 0">
93
+          <div class="splide__arrow splide__arrow--prev">
94
+            <img src="/images/pg3/arrow.png" alt="" style="transform: rotate(180deg)">
95
+          </div>
96
+        </div>
97
+        <div class="splide__arrows abs" style="right: 0; top: 0">
98
+          <div class="splide__arrow splide__arrow--next">
99
+            <img src="/images/pg3/arrow.png" alt="">
100
+          </div>
101
+        </div>
102
+      </div>
103
+    </Splide >
26 104
 
27 105
     <div class="btn-box">
28
-      <Btn class="btn" @click="showPerson = true">人物采访</Btn>
29
-      <Btn class="btn" @click="onVideo">视频</Btn>
106
+      <img src="/images/pg3/btn.png" alt=""  @click="onBtnClick">
30 107
     </div>
31 108
 
32
-    <Persons v-if="showPerson" @cancel="showPerson = false" />
109
+    <!-- <Persons v-if="showPerson" @cancel="showPerson = false" /> -->
33 110
   </div>
34 111
 </template>
35 112
 
36 113
 <script setup>
37 114
   import { onBeforeUnmount, onMounted, ref } from 'vue';
38 115
   import { useRouter } from 'vue-router';
116
+  import { Splide, SplideSlide, SplideTrack } from '@splidejs/vue-splide';
39 117
   import Bell from '@/components/Bell.vue';
40 118
   import Btn from '@/components/Btn.vue';
41 119
   import Animate from '@/components/Animate.vue';
42 120
   import Persons from './Persons.vue';
43
-  import Map from './Map.vue';
121
+  import Ink from './Ink.vue';
44 122
   import usePageShow from '../usePageShow';
45 123
 
46 124
   const router = useRouter();
47 125
   const [pgRef, show] = usePageShow(0.3);
48 126
   const showPerson = ref(false);
127
+  const slideIndexRef = ref(0);
128
+
129
+  const slideOptions = {
130
+    // arrows: false,
131
+    pagination: false,
132
+    autoplay: true,
133
+    type: 'loop',
134
+    speed: 1000,
135
+    interval: 6000,
136
+  }
49 137
 
50 138
   const onVideo = () => {
51 139
     router.push('/pg4')
52 140
   }
141
+
142
+  const onSlideChange = (slide, newIndex) => {
143
+    slideIndexRef.value = newIndex;
144
+  }
145
+
146
+  const onBtnClick = () => {
147
+    console.log('--------------')
148
+    router.push('/pg4')
149
+  }
53 150
 </script>
54 151
 
55 152
 
56 153
 <style lang="less" scoped>
57 154
 .pg3 {
58
-  min-height: 100vh;
155
+  position: relative;
156
+
157
+  .pg3-bg {
158
+    position: absolute;
159
+    z-index: 0;
160
+    width: 100%;
161
+    height: 100%;
162
+
163
+    & > div {
164
+      position: relative;
165
+      height: 100%;
166
+    }
59 167
 
60
-  .bell {
61
-    right: 30px;
62
-    top: 30px;
168
+    .bg-left {
169
+      width: 40px;
170
+      height: 158px;
171
+      top: 30vh;
172
+      left: 0;
173
+    }
174
+    .bg-right {
175
+      width: 50px;
176
+      height: 80px;
177
+      top: 10vh;
178
+      right: 0;
179
+    }
63 180
   }
64 181
 
182
+
65 183
   .header {
66 184
     width: 30vw;
67 185
     margin: auto;
68 186
     margin-top: 30px;
69 187
     position: relative;
188
+  }
70 189
 
71
-    &::before {
72
-      content: '';
73
-      position: absolute;
74
-      width: 100%;
75
-      height: 100%;
76
-      background-image: url('/images/BG.jpg');
77
-      background-size: 100% 100%;
78
-      background-repeat: no-repeat;
79
-      transform-origin: bottom center;
80
-      animation: erasure 1s linear forwards;
81
-      z-index: 10;
82
-    }
190
+  .nanjing {
191
+    width: 50vw;
192
+    margin: auto;
193
+    display: flex;
194
+    align-items: center;
195
+    justify-content: space-between;
83 196
 
84
-    @keyframes erasure {
85
-      from {
86
-        transform: scaleY(100%);
87
-      }
197
+    & > div {
198
+      position: relative;
199
+    }
88 200
 
89
-      to {
90
-        transform: scaleY(0);
91
-      }
201
+    .stele {
202
+      width: 8vw;
203
+      bottom: 2vw;
204
+      left: 8vw;
92 205
     }
93 206
   }
94 207
 
95
-  .content {
96
-    width: 80vw;
208
+  .nj-1937 {
209
+    width: 16vw;
97 210
     margin: auto;
98 211
   }
99 212
 
100
-  .global-map {
101
-    width: 95vw;
213
+  .content {
214
+    width: 70vw;
102 215
     margin: auto;
216
+    font-size: 14px;
217
+    line-height: 1.2em;
218
+    
219
+    .txt {
220
+      color: #5D4135;
221
+    }
222
+  }
223
+
224
+  .ink-slider-wrapper {
225
+    position: relative;
226
+    z-index: 2;
227
+
228
+    .splide__arrows {
229
+      position: absolute;
230
+      z-index: 10;
231
+      width: 48px;
232
+      height: 54.89vw;
233
+      line-height: 54.89vw;
234
+      text-align: center;
235
+
236
+      img {
237
+        width: 12px;
238
+        display: inline-block;
239
+      }
240
+    }
241
+  }
242
+
243
+  .slide-ink {
244
+    width: 100vw;
245
+    height: 54.89vw;
103 246
   }
104 247
 
105 248
   .btn-box {
106 249
     margin-top: 2em;
107 250
     text-align: center;
251
+    position: relative;
252
+    z-index: 2;
108 253
 
109
-    .btn {
110
-      & + .btn {
111
-        margin-left: 40px;
112
-      }
254
+    img {
255
+      width: 30vw;
256
+      margin: auto;
113 257
     }
114 258
   }
115 259
 

+ 8
- 1
yarn.lock Zobrazit soubor

@@ -55,11 +55,18 @@
55 55
     "@intlify/core-base" "9.2.2"
56 56
     "@intlify/shared" "9.2.2"
57 57
 
58
-"@splidejs/splide@^4.1.4":
58
+"@splidejs/splide@^4.1.3", "@splidejs/splide@^4.1.4":
59 59
   version "4.1.4"
60 60
   resolved "https://registry.npmmirror.com/@splidejs/splide/-/splide-4.1.4.tgz#02d029360569e7d75d28357a9727fc48322015a3"
61 61
   integrity sha512-5I30evTJcAJQXt6vJ26g2xEkG+l1nXcpEw4xpKh0/FWQ8ozmAeTbtniVtVmz2sH1Es3vgfC4SS8B2X4o5JMptA==
62 62
 
63
+"@splidejs/vue-splide@^0.6.12":
64
+  version "0.6.12"
65
+  resolved "https://registry.npmmirror.com/@splidejs/vue-splide/-/vue-splide-0.6.12.tgz#063731cf8ec2d1f9a14ffacbe3a315db63ab6ff2"
66
+  integrity sha512-eQb8pnGMN8Tr0FVaQo1PUMZlMHl8fSqHNXPTx79eeE2dkZqbsvq6jRzXoT9ZF7hFkxdOEmB6qYNp93SUwV684g==
67
+  dependencies:
68
+    "@splidejs/splide" "^4.1.3"
69
+
63 70
 "@vitejs/plugin-vue@^3.0.3":
64 71
   version "3.2.0"
65 72
   resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz#a1484089dd85d6528f435743f84cdd0d215bbb54"