Your Name 2 gadus atpakaļ
vecāks
revīzija
4bb186e606

+ 4
- 0
src/app.less Parādīt failu

@@ -3,6 +3,10 @@
3 3
   height: 100vh;
4 4
 }
5 5
 
6
+.flex {
7
+  display: flex;
8
+}
9
+
6 10
 .v-flex {
7 11
   display: flex;
8 12
   flex-direction: column;

Binārs
src/assets/images/avatar.png Parādīt failu


+ 205
- 0
src/pages/index/components/avatar-change.vue Parādīt failu

@@ -0,0 +1,205 @@
1
+<template>
2
+  <view class="v-flex">
3
+    <view class="flex-1 flex">
4
+      <view class="flex-0 avatar-preview-box">
5
+        <view class="avatar-preview">
6
+          <image class="avatar-poster" :src="poster || defaultAvatar"></image>
7
+          <image v-if="attach" :class="posCls" :src="attach.url"></image>
8
+        </view>
9
+      </view>
10
+      <view class="flex-1 setting-act">
11
+        <button @tap="getUserProfile">获取头像</button>
12
+        <button @tap="onChoose">自定义上传</button>
13
+        <button @tap="onSave">预览保存</button>
14
+      </view>
15
+    </view>
16
+    <view class="flex-0 avatar-slider-box">
17
+      <avatar-slider @change="onChange"/>
18
+    </view>
19
+  </view>
20
+</template>
21
+
22
+<script>
23
+import { computed, ref } from 'vue';
24
+import defaultAvatar from '@/assets/images/avatar.png';
25
+import avatarSlider from './avatar-slider.vue';
26
+import useCanvas from '../useCanvas';
27
+
28
+export default {
29
+  components: {
30
+    'avatar-slider': avatarSlider,
31
+  },
32
+  setup () {
33
+    const avatarSize = 160;
34
+    const smallSize = 60;
35
+
36
+    const [drawImage, toDataURL, toTempFile, clearCanvas] = useCanvas(avatarSize);
37
+    const attach = ref();
38
+    const poster = ref();
39
+    
40
+    const posCls = computed(() => attach.value ? `pos-${attach.value.pos}` : '');
41
+
42
+    const getUserProfile = () => {
43
+      wx.getUserProfile({
44
+        desc: '用于设置头像',
45
+        success: (res) => {
46
+          poster.value = res.userInfo.avatarUrl;
47
+        },
48
+        fail: (err) => {
49
+          console.error(err);
50
+        }
51
+      });
52
+    };
53
+
54
+    const onChange = (val) => {
55
+      attach.value = val;
56
+    }
57
+
58
+    const onChoose = () => {
59
+      wx.chooseMedia({
60
+        count: 1,
61
+        mediaType: ['image'],
62
+        success: ({ tempFiles }) => {
63
+          const tempFile = tempFiles[0];
64
+          poster.value = tempFile.tempFilePath;
65
+        }
66
+      });
67
+    };
68
+
69
+    const onSave = () => {
70
+      if (!poster.value || !attach.value) {
71
+        wx.showToast({
72
+          title: '无头像或小标',
73
+          icon: 'none'
74
+        });
75
+        return ;
76
+      }
77
+
78
+      wx.showLoading({
79
+        title: '请稍候...',
80
+      });
81
+
82
+      const onError = (err) => {
83
+        console.error(err);
84
+        wx.hideLoading();
85
+        wx.showToast({
86
+          title: '操作失败, 请重试',
87
+          icon: 'none'
88
+        });
89
+      }
90
+
91
+      clearCanvas();
92
+
93
+      // poster
94
+      drawImage(poster.value, 0, 0, avatarSize, avatarSize).then(() => {
95
+        // 头标
96
+        let p = undefined;
97
+        const url = attach.value.url;
98
+        switch (attach.value.pos) {
99
+          case 'lf':
100
+            p = drawImage(url, 0, 0, avatarSize, avatarSize);
101
+            break;
102
+          case 'rb':
103
+          default:
104
+            const startPos = avatarSize - smallSize - 10;
105
+            p = drawImage(url, startPos, startPos, smallSize, smallSize);
106
+            break;
107
+        }
108
+
109
+        p.then(() => {
110
+          toTempFile({
111
+            success(res) {
112
+              console.log(res);
113
+              wx.previewImage({ urls: [res] });
114
+            },
115
+            fail: onError,
116
+            complete: () => {
117
+              wx.hideLoading();
118
+            }
119
+          });
120
+        }).catch(onError);
121
+      }).catch(onError);
122
+    }
123
+    
124
+    return {
125
+      defaultAvatar,
126
+      poster,
127
+      attach,
128
+      posCls,
129
+      getUserProfile,
130
+      onChange,
131
+      onChoose,
132
+      onSave,
133
+    }
134
+  },
135
+}
136
+</script>
137
+
138
+<style lang="less">
139
+
140
+  // 国旗的两种颜色
141
+  @color1: #EE1C25;
142
+  @color2: #FFFD00;
143
+    
144
+  .setting-act {
145
+    margin-top: 1em;
146
+    display: flex;
147
+    flex-direction: column;
148
+    justify-content: center;
149
+
150
+    button {
151
+      width: 8em;
152
+      font-size: 1em;
153
+      background: #f1c472;
154
+      color: #fff;
155
+
156
+      & + button {
157
+        margin-top: 1em;
158
+      }
159
+    }
160
+  }
161
+
162
+  .avatar-preview-box {
163
+    margin: auto;
164
+    box-sizing: border-box;
165
+    padding: 0 1.2em;
166
+  }
167
+
168
+  .avatar-preview {
169
+    margin: auto;
170
+    width: 320rpx;
171
+    height: 320rpx;
172
+    background: #fecf7a;
173
+    position: relative;
174
+    border: 16rpx solid #e37812;
175
+    border-radius: 16rpx;
176
+    overflow: hidden;
177
+
178
+    .avatar-poster {
179
+      width: 100%;
180
+      height: 100%;
181
+    }
182
+
183
+    .pos-rb {
184
+      position: absolute;
185
+      width: 120rpx;
186
+      height: 120rpx;
187
+      right: 10rpx;
188
+      bottom: 10rpx;
189
+    }
190
+    
191
+    .pos-lf {
192
+      position: absolute;
193
+      width: 100%;
194
+      height: 100%;
195
+      left: 0;
196
+      top: 0;
197
+    }
198
+  }
199
+
200
+  .avatar-slider-box {
201
+    box-sizing: border-box;
202
+    padding: 0.5em;
203
+    background: rgba(0, 0, 0,  .2);
204
+  }
205
+</style>

+ 8
- 3
src/pages/index/components/avatar-slider.vue Parādīt failu

@@ -94,7 +94,7 @@
94 94
 <style lang="less">
95 95
 .avatar-slider {
96 96
   width: 100vw;
97
-  height: 72rpx;
97
+  height: 96rpx;
98 98
   white-space: nowrap;
99 99
 
100 100
   .active {
@@ -102,10 +102,15 @@
102 102
   }
103 103
 
104 104
   image {
105
+    background: rgba(255, 255, 255, .8);
105 106
     display: inline-block;
106
-    width: 72rpx;
107
-    height: 72rpx;
107
+    width: 96rpx;
108
+    height: 96rpx;
108 109
     border: 2px solid transparent;
110
+
111
+    & + image {
112
+      margin-left: .5em;
113
+    }
109 114
   }
110 115
 }
111 116
 </style>

+ 50
- 0
src/pages/index/components/banner.vue Parādīt failu

@@ -0,0 +1,50 @@
1
+<template>
2
+  <view class="index-banner">
3
+    <image :src="banner" />
4
+    <view class="index-title">
5
+      欢度国庆.换出精彩
6
+    </view>
7
+  </view>
8
+</template>
9
+
10
+<script>
11
+  export default {
12
+    setup() {
13
+      const banner = 'http://yz-h5.oss-cn-shanghai.aliyuncs.com/assets/guoqing-miniapp/banner.jpg';
14
+
15
+      return {
16
+        banner
17
+      }
18
+    }
19
+  }
20
+</script>
21
+
22
+<style lang="less">
23
+.index-banner {
24
+  position: relative;
25
+
26
+  @bannerSize: 100vw;
27
+  @bannerHeight: calc(100vw * 130 / 375);
28
+
29
+  image {
30
+    width: @bannerSize;
31
+    height: @bannerHeight;
32
+  }
33
+
34
+  .index-title {
35
+    width: @bannerSize;
36
+    height: @bannerHeight;
37
+    position: absolute;
38
+    top: 0;
39
+    left: 0;
40
+
41
+    text-align: center;
42
+    color: #fdcd77;
43
+    font-size: 1.6em;
44
+    font-weight: bold;
45
+    letter-spacing: 8rpx;
46
+    text-shadow: 4px 6px rgba(0, 0, 0, .6);
47
+    line-height: @bannerHeight;
48
+  }
49
+}
50
+</style>

+ 13
- 175
src/pages/index/index.vue Parādīt failu

@@ -1,25 +1,8 @@
1 1
 <template>
2 2
   <view class="page v-flex">
3 3
     <view class="flex-1 v-flex index-contariner">
4
-      <view class="flex-1">
5
-        <view class="avatar-setting">
6
-          <view class="setting-title">
7
-            快来设置你的头像吧~
8
-          </view>
9
-          <view class="avatar-preview">
10
-            <image v-if="poster" class="avatar-poster" :src="poster"></image>
11
-            <image v-if="attach" :class="posCls" :src="attach.url"></image>
12
-          </view>
13
-          <view class="setting-act">
14
-            <button @tap="getUserProfile">获取头像</button>
15
-            <button @tap="onChoose">自定义上传</button>
16
-            <button @tap="onSave">预览保存</button>
17
-          </view>
18
-        </view>
19
-      </view>
20
-      <view class="flex-0">
21
-        <avatar-slider @change="onChange"/>
22
-      </view>
4
+      <banner class="flex-0" />
5
+      <avatar-change class="flex-1" />
23 6
     </view>
24 7
     <view class="flex-0 footer-ad">
25 8
       <ad unit-id="adunit-134135d609e5c485"></ad>
@@ -28,14 +11,15 @@
28 11
 </template>
29 12
 
30 13
 <script>
31
-import { computed, onMounted, ref } from 'vue';
32
-import Taro, { eventCenter, getCurrentInstance, useReady } from '@tarojs/taro';
33
-import avatarSlider from './components/avatar-slider.vue';
34
-import useCanvas from './useCanvas';
14
+import { ref } from 'vue';
15
+import Taro, { useReady } from '@tarojs/taro';
16
+import banner from './components/banner.vue';
17
+import avatarChange from './components/avatar-change.vue';
35 18
 
36 19
 export default {
37 20
   components: {
38
-    'avatar-slider': avatarSlider,
21
+    'avatar-change': avatarChange,
22
+    banner,
39 23
   },
40 24
   onShareAppMessage() {
41 25
     return {
@@ -48,165 +32,19 @@ export default {
48 32
     }
49 33
   },
50 34
   setup () {
51
-    const avatarSize = 160;
52
-    const smallSize = 60;
53
-
54
-    const [drawImage, toDataURL, toTempFile] = useCanvas('avatar-canvas', avatarSize);
55
-    const attach = ref();
56
-    const poster = ref();
57
-    
58
-    const posCls = computed(() => attach.value ? `pos-${attach.value.pos}` : '');
59
-
60
-    const getUserProfile = () => {
61
-      wx.getUserProfile({
62
-        desc: '用于设置头像',
63
-        success: (res) => {
64
-          poster.value = res.userInfo.avatarUrl;
65
-        },
66
-        fail: (err) => {
67
-          console.error(err);
68
-        }
69
-      });
70
-    };
71
-
72
-    const onChange = (val) => {
73
-      attach.value = val;
74
-    }
75
-
76
-    const onChoose = () => {
77
-      wx.chooseMedia({
78
-        count: 1,
79
-        mediaType: ['image'],
80
-        success: ({ tempFiles }) => {
81
-          const tempFile = tempFiles[0];
82
-          poster.value = tempFile.tempFilePath;
83
-        }
84
-      });
85
-    };
86
-
87
-    const onSave = () => {
88
-      if (!poster.value || !attach.value) {
89
-        wx.showToast({
90
-          title: '无头像或小标',
91
-          icon: 'none'
92
-        });
93
-        return ;
94
-      }
95
-
96
-      wx.showLoading({
97
-        title: '请稍候...',
98
-      });
99
-
100
-
101
-      const onError = (err) => {
102
-        console.error(err);
103
-        wx.hideLoading();
104
-        wx.showToast({
105
-          title: '操作失败, 请重试',
106
-          icon: 'none'
107
-        });
108
-      }
109
-
110
-      // poster
111
-      drawImage(poster.value, 0, 0, avatarSize, avatarSize).then(() => {
112
-        // 头标
113
-        let p = undefined;
114
-        const url = attach.value.url;
115
-        switch (attach.value.pos) {
116
-          case 'lf':
117
-            p = drawImage(url, 0, 0, avatarSize, avatarSize);
118
-            break;
119
-          case 'rb':
120
-          default:
121
-            const startPos = avatarSize - smallSize - 10;
122
-            p = drawImage(url, startPos, startPos, smallSize, smallSize);
123
-            break;
124
-        }
125
-
126
-        p.then(() => {
127
-          toTempFile({
128
-            success(res) {
129
-              console.log(res);
130
-              wx.previewImage({ urls: [res] });
131
-            },
132
-            complete: () => {
133
-              wx.hideLoading();
134
-            }
135
-          });
136
-        }).catch(onError);
137
-      }).catch(onError);
138
-    }
139
-    
140
-    return {
141
-      poster,
142
-      attach,
143
-      posCls,
144
-      getUserProfile,
145
-      onChange,
146
-      onChoose,
147
-      onSave,
148
-    }
149 35
   },
150 36
 }
151 37
 </script>
152 38
 
153 39
 <style lang="less">
154 40
 
155
-  @color1: #EE1C25;
156
-  @color2: #FFFD00;
157
-
158 41
   .index-contariner {
159
-    background: linear-gradient(@color1, #fff);
160
-
161
-    .avatar-setting {
162
-
163
-      .setting-title {
164
-        text-align: center;
165
-        font-size: 1.6em;
166
-        padding: 2em 0;
167
-        color: @color2;
168
-      }
169
-
170
-      .setting-act {
171
-        margin-top: 2em;
172
-        display: flex;
173
-        justify-content: center;
42
+    background: #faf4e6;
43
+    background-repeat: no-repeat;
44
+    background-image: url(http://yz-h5.oss-cn-shanghai.aliyuncs.com/assets/guoqing-miniapp/back.jpg);
45
+    background-position: center bottom;
46
+    background-size: 100% auto;
174 47
 
175
-        button {
176
-          background: fade(@color2, 40%);
177
-          color: @color1;
178
-        }
179
-      }
180
-    }
181
-
182
-    .avatar-preview {
183
-      margin: auto;
184
-      width: 320rpx;
185
-      height: 320rpx;
186
-      background: fade(@color2, 20%);
187
-      position: relative;
188
-
189
-      .avatar-poster {
190
-        width: 100%;
191
-        height: 100%;
192
-      }
193
-
194
-      .pos-rb {
195
-        position: absolute;
196
-        width: 120rpx;
197
-        height: 120rpx;
198
-        right: 10rpx;
199
-        bottom: 10rpx;
200
-      }
201
-      
202
-      .pos-lf {
203
-        position: absolute;
204
-        width: 100%;
205
-        height: 100%;
206
-        left: 0;
207
-        top: 0;
208
-      }
209
-    }
210 48
   }
211 49
 
212 50
   .footer-ad {

+ 9
- 4
src/pages/index/useCanvas.js Parādīt failu

@@ -1,12 +1,12 @@
1 1
 
2
-import { ref } from 'vue';
3
-import Taro, { useReady } from '@tarojs/taro';
2
+import { ref, onMounted } from 'vue';
3
+// import Taro, { useReady } from '@tarojs/taro';
4 4
 
5
-export default function useCanvas(id, size = 160) {
5
+export default function useCanvas(size = 160) {
6 6
   const cvsRef = ref();
7 7
   const ctxRef = ref();
8 8
 
9
-  useReady(() => {
9
+  onMounted(() => {
10 10
     const canvas = wx.createOffscreenCanvas({type: '2d', width: size, height: size});
11 11
     const ctx = canvas.getContext('2d');
12 12
     
@@ -14,6 +14,10 @@ export default function useCanvas(id, size = 160) {
14 14
     ctxRef.value = ctx;
15 15
   });
16 16
 
17
+  const reset = () => {
18
+    cvsRef.value.height = size;
19
+  }
20
+
17 21
   const drawImage = (url, ...args) => {
18 22
     const canvas = cvsRef.value;
19 23
     const ctx = ctxRef.value;
@@ -79,6 +83,7 @@ export default function useCanvas(id, size = 160) {
79 83
     drawImage,
80 84
     toDataURL,
81 85
     toTempFile,
86
+    reset,
82 87
     cvsRef,
83 88
     ctxRef,
84 89
   ];