10c6d284 by simon

默认提交

1 parent 302e3d6b
...@@ -28,6 +28,7 @@ module.exports = { ...@@ -28,6 +28,7 @@ module.exports = {
28 */ 28 */
29 areaQuery: 'https://api.k.wxpai.cn/bizproxy/kdapi/area', // post 区域查询 29 areaQuery: 'https://api.k.wxpai.cn/bizproxy/kdapi/area', // post 区域查询
30 30
31 uploadFile: '/kdapi/file/upload' //上传图片通用接口 31 wxacodeGet: "/mzcfsapi/qrcode/createV2", // 通用上传 ?path=/pages/index/index?pa=1
32 uploadFile: '/kdapi/file/upload', //上传图片通用接口
32 33
33 } 34 }
......
1 {
2 "component": true
3 }
...\ No newline at end of file ...\ No newline at end of file
1 <!--index.wxml-->
2 <view class="container">
3 <canvas canvas-id='canvasid' class="canvas {{debug ? 'debug' : 'pro'}}" style='width: {{pxWidth}}px; height: {{pxHeight}}px;'></canvas>
4 </view>
1 .canvas {
2 width: 750rpx;
3 height: 750rpx;
4 }
5 .canvas.pro {
6 position: absolute;
7 bottom: 0;
8 left: 0;
9 transform: translate3d(-9999rpx, 0, 0);
10 }
11 .canvas.debug {
12 position: absolute;
13 bottom: 0;
14 left: 0;
15 border: 1rpx solid #ccc;
16 }
...\ No newline at end of file ...\ No newline at end of file
1 Component({
2 properties: {
3 config: {
4 type: Object,
5 value: {},
6 },
7 preload: { // 是否预下载图片资源
8 type: Boolean,
9 value: false,
10 },
11 hideLoading: { // 是否隐藏loading
12 type: Boolean,
13 value: false,
14 }
15 },
16 ready() {
17 if (this.data.preload) {
18 const poster = this.selectComponent('#poster');
19 this.downloadStatus = 'doing';
20 poster.downloadResource(this.data.config.images).then(() => {
21 this.downloadStatus = 'success';
22 this.trigger('downloadSuccess');
23 }).catch((e) => {
24 this.downloadStatus = 'fail';
25 this.trigger('downloadFail', e);
26 });
27 }
28 },
29 methods: {
30 trigger(event, data) {
31 if (this.listener && typeof this.listener[event] === 'function') {
32 this.listener[event](data);
33 }
34 },
35 once(event, fun) {
36 if (typeof this.listener === 'undefined') {
37 this.listener = {};
38 }
39 this.listener[event] = fun;
40 },
41 downloadResource(reset) {
42 return new Promise((resolve, reject) => {
43 if (reset) {
44 this.downloadStatus = null;
45 }
46 const poster = this.selectComponent('#poster');
47 if (this.downloadStatus && this.downloadStatus !== 'fail') {
48 if (this.downloadStatus === 'success') {
49 resolve();
50 } else {
51 this.once('downloadSuccess', () => resolve());
52 this.once('downloadFail', (e) => reject(e));
53 }
54 } else {
55 poster.downloadResource(this.data.config.images)
56 .then(() => {
57 this.downloadStatus = 'success';
58 resolve();
59 })
60 .catch((e) => reject(e));
61 }
62 })
63 },
64 onCreate(reset = false) {
65 !this.data.hideLoading && wx.showLoading({ mask: true, title: '生成中' });
66 return this.downloadResource(typeof reset === 'boolean' && reset).then(() => {
67 !this.data.hideLoading && wx.hideLoading();
68 const poster = this.selectComponent('#poster');
69 poster.create(this.data.config);
70 })
71 .catch((err) => {
72 !this.data.hideLoading && wx.hideLoading();
73 wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' });
74 console.error(err);
75 this.triggerEvent('fail', err);
76 })
77 },
78 onCreateSuccess(e) {
79 const { detail } = e;
80 this.triggerEvent('success', detail);
81 },
82 onCreateFail(err) {
83 console.error(err);
84 this.triggerEvent('fail', err);
85 }
86 }
87 })
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "component": true,
3 "usingComponents": {
4 "we-canvas": "../index/index"
5 }
6 }
...\ No newline at end of file ...\ No newline at end of file
1 <view bindtap='onCreate'>
2 <slot/>
3 </view>
4 <we-canvas id="poster" bind:success="onCreateSuccess" bind:fail="onCreateFail"/>
...\ No newline at end of file ...\ No newline at end of file
1 const defaultOptions = {
2 selector: '#poster'
3 };
4
5 function Poster(options = {}) {
6 options = {
7 ...defaultOptions,
8 ...options,
9 };
10
11 const pages = getCurrentPages();
12 const ctx = pages[pages.length - 1];
13
14 const poster = ctx.selectComponent(options.selector);
15 delete options.selector;
16
17 return poster;
18 };
19
20 Poster.create = (reset = false) => {
21 const poster = Poster();
22 if (!poster) {
23 console.error('请设置组件的id="poster"!!!');
24 } else {
25 return Poster().onCreate(reset);
26 }
27 }
28
29 export default Poster;
...\ No newline at end of file ...\ No newline at end of file
...@@ -4,6 +4,7 @@ import { ...@@ -4,6 +4,7 @@ import {
4 } from '../../utils/util'; 4 } from '../../utils/util';
5 5
6 import Dialog from '../../ui/vant-weapp/dialog/dialog'; 6 import Dialog from '../../ui/vant-weapp/dialog/dialog';
7 import Poster from '../../miniprogram_dist/poster/poster';
7 8
8 const back = wx.getBackgroundAudioManager(); 9 const back = wx.getBackgroundAudioManager();
9 10
...@@ -41,7 +42,9 @@ Page({ ...@@ -41,7 +42,9 @@ Page({
41 isPlayingBgm: false, 42 isPlayingBgm: false,
42 isMore: false, 43 isMore: false,
43 44
44 // shortcutPics:["red-package2","more-bless"] 45 imageUrl: "", // 海报图
46 posterVisible: false,
47 wxCodeUrl: "", // 微信小程序码
45 }, 48 },
46 onShareAppMessage(res) { 49 onShareAppMessage(res) {
47 let shareType = "" 50 let shareType = ""
...@@ -128,7 +131,6 @@ Page({ ...@@ -128,7 +131,6 @@ Page({
128 */ 131 */
129 initData() {}, 132 initData() {},
130 playBgm() { 133 playBgm() {
131 return;
132 let _this = this; 134 let _this = this;
133 let { 135 let {
134 detailData 136 detailData
...@@ -192,11 +194,273 @@ Page({ ...@@ -192,11 +194,273 @@ Page({
192 } 194 }
193 }, 195 },
194 196
197 onHidePosterHandler() {
198 this.setData({
199 posterVisible: false
200 })
201 },
202
203 /**
204 * 图片查看
205 */
206 onPreviewImageHandler(evt) {
207 let current = this.data.imageUrl;
208 let urls = [current];
209 wx.previewImage({
210 current: current,
211 urls: urls
212 })
213 },
214
215 /**
216 * 保存图片到本地
217 */
218 saveImageToPhotosAlbum() {
219 let _this = this;
220 wx.saveImageToPhotosAlbum({
221 filePath: _this.data.imageUrl,
222 success(res) {
223 wx.showToast({
224 title: '保存成功',
225 icon: 'success'
226 });
227 },
228 fail(err) {
229 wx.getSetting({
230 success: (res) => {
231 if (!res.authSetting['scope.writePhotosAlbum']) {
232 // 未授权
233 wx.showModal({
234 title: '提示',
235 content: '小程序请求访问相册权限',
236 confirmText: '前往授权',
237 success(res) {
238 if (res.confirm) {
239 wx.openSetting({
240 success(res) {}
241 })
242 } else if (res.cancel) {}
243 }
244 })
245 }
246 }
247 })
248 }
249 })
250 },
251
252 // 配置小程序码
253 getWxCode() {
254 let {
255 detailData
256 } = this.data;
257 let memberCode = app.store.getItem("memberCode");
258 let wxCodePath = `pages/blessing/blessing?c=${detailData.blessCode}&m=${memberCode}`;
259
260 return new Promise((resolve, reject) => {
261 // 先获取小程序码
262 app.get({
263 mode: "common",
264 url: app.api.wxacodeGet,
265 data: {
266 path: encodeURIComponent(wxCodePath)
267 }
268 }).then((result) => {
269 this.setData({
270 wxCodeUrl: result
271 })
272 resolve(result);
273 })
274 });
275
276 },
277
195 /** 278 /**
196 * 分享图片祝福 279 * 分享图片祝福
197 * 生成海报 280 * 生成海报
198 */ 281 */
199 onPosterHandler(){ 282 onPosterHandler() {
283 console.log("onPosterHandler");
284
285 // 先获取小程序码
286 this.getWxCode().then((result) => {
287 let posterData = this.getPosterConfig();
288 this.onCreatePoster(posterData);
289 });
290 },
291
292 onPosterSuccess(e) {
293 wx.hideLoading();
294 const {
295 detail
296 } = e;
297 console.log("detail:", detail)
298 this.setData({
299 imageUrl: detail,
300 posterVisible: true,
301 })
302 },
303
304 onPosterFail(err) {
305 wx.hideLoading();
306 console.error(err);
307 },
308
309 /**
310 * 异步生成海报
311 */
312 onCreatePoster(posterConfig) {
313 console.log("posterConfig:", posterConfig);
314 this.setData({
315 posterConfig: posterConfig
316 }, () => {
317 Poster.create(true); // 入参:true为抹掉重新生成
318 });
319 },
320
321 // 获取海报数据
322 getPosterConfig() {
323 let {
324 detailData,
325 ownerMember,
326 memberList,
327 wxCodeUrl
328 } = this.data;
329 let avatarWid = 120;
330 let nickname = ownerMember.memberName;
331 let avatar = ownerMember.memberHead;
332 let desc = "";
333 if (detailData.type == 1) {
334 // 组队
335 if (detailData.count > 0) {
336 desc = `携${detailData.familyName}${detailData.count}人`
337 } else {
338 desc = `携${detailData.familyName}`
339 }
340 } else {
341 // 单人
342 desc = `向各位亲朋好友`
343 }
344 let blocks = []
345 let images = [
346 // 背景图
347 {
348 x: 0,
349 y: 0,
350 width: 750,
351 height: 1334,
352 url: "../../image/poster/poster_c1.png",
353 },
354 // 头像
355 {
356 x: 184,
357 y: 186,
358 width: avatarWid,
359 height: avatarWid,
360 borderRadius: avatarWid,
361 zIndex: 22,
362 url: avatar,
363 },
364 // 小程序码
365 {
366 width: 100,
367 height: 100,
368 x: 586,
369 y: 1198,
370 url: wxCodeUrl,
371 zIndex: 31
372 }
373 ];
374 let lines = [];
375 let texts = [
376 // 房主昵称
377 {
378 x: 53,
379 y: 460,
380 fontSize: 60,
381 color: "#fee085",
382 textAlign: "left",
383 zIndex: 11,
384 text: nickname,
385 },
386 // 文案
387 {
388 x: 53,
389 y: 540,
390 fontSize: 60,
391 color: "#fee085",
392 textAlign: "left",
393 zIndex: 11,
394 text: desc,
395 }
396 ];
397
398 // 组队补充
399 if (detailData.type == 1) {
400 // 头像昵称取出3人
401 let member1 = memberList[0] || null;
402 let member2 = memberList[1] || null;
403 let member3 = memberList[2] || null;
404
405 let memberDrawList = [];
406 if (member1) memberDrawList.push(member1);
407 if (member2) memberDrawList.push(member2);
408 if (member3) memberDrawList.push(member3);
409 let endX = 630;
410 let wid = 160;
411 let startY = 800;
412 memberDrawList.forEach((element, idx) => {
413 // blocks.push({
414 // x: endX - (idx * wid) - ((wid - 92)),
415 // y: startY,
416 // width: 92,
417 // height: 92,
418 // borderRadius: 92,
419 // zIndex: 90,
420 // borderColor: "#fee085",
421 // })
422 images.push({
423 x: endX - (idx * wid) - ((wid - 92) / 2) - 4,
424 y: startY + 2,
425 width: 92,
426 height: 92,
427 borderRadius: 92,
428 zIndex: 101,
429 url: avatar,
430 })
431 texts.push({
432 x: endX - (idx * wid),
433 y: startY + 136,
434 width: wid,
435 fontSize: 24,
436 color: "#fee085",
437 textAlign: "center",
438 zIndex: 101,
439 text: element.memberName,
440 })
441 });
442
443 texts.push({
444 x: 686,
445 y: startY + 200,
446 fontSize: 48,
447 color: "#fee085",
448 textAlign: "right",
449 zIndex: 11,
450 text: `长按查看全部${detailData.count}人 >>`,
451 })
452 }
453
454 let posterData = {
455 width: 750,
456 height: 1334,
457 debug: false,
458 blocks: blocks,
459 images: images,
460 lines: lines,
461 texts: texts,
462 }
463 return posterData;
200 }, 464 },
201 465
202 // 显示更新用户信息 466 // 显示更新用户信息
......
1 {} 1 {
2 "usingComponents": {
3 "poster": "/miniprogram_dist/poster/index"
4 }
5 }
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
5 font-size: 36rpx; 5 font-size: 36rpx;
6 } 6 }
7 7
8 .van-popup {
9 background-color: transparent !important;
10 }
11
8 // 用户头像 12 // 用户头像
9 .portrait { 13 .portrait {
10 position: relative; 14 position: relative;
...@@ -65,6 +69,24 @@ ...@@ -65,6 +69,24 @@
65 text-align: center; 69 text-align: center;
66 } 70 }
67 71
72 .poster {
73 width: 540px;
74 }
75
76 .save-btn {
77 margin: 24px auto;
78 @include btc(290px, 76px);
79 color: #fee085;
80 font-size: 36px;
81 border-radius: 8px;
82 box-shadow: 5.9px 5.5px 18px 0 rgba(26, 36, 91, 0.73);
83 background-image: linear-gradient(to top, #b41d36, #bb2634);
84
85 color: #940023;
86 box-shadow: 5.9px 5.5px 18px 0 rgba(26, 36, 91, 0.73);
87 background-image: linear-gradient(to top, #f4b44d, #e8b976, #ffebb5);
88 }
89
68 .page { 90 .page {
69 padding-bottom: 200px; 91 padding-bottom: 200px;
70 92
...@@ -321,7 +343,7 @@ ...@@ -321,7 +343,7 @@
321 position: fixed; 343 position: fixed;
322 bottom: 0; 344 bottom: 0;
323 width: 100%; 345 width: 100%;
324 z-index: 101; 346 z-index: 21;
325 347
326 .bottom-bg { 348 .bottom-bg {
327 width: 750px; 349 width: 750px;
...@@ -362,7 +384,7 @@ ...@@ -362,7 +384,7 @@
362 position: fixed; 384 position: fixed;
363 right: 24px; 385 right: 24px;
364 top: 24px; 386 top: 24px;
365 z-index: 201; 387 z-index: 31;
366 } 388 }
367 389
368 390
...@@ -403,3 +425,7 @@ ...@@ -403,3 +425,7 @@
403 -webkit-transform: rotate(360deg); 425 -webkit-transform: rotate(360deg);
404 } 426 }
405 } 427 }
428
429 #poster {
430 position: absolute;
431 }
......
1 <poster id="poster" hide-loading="{{true}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster>
1 <view class="page"> 2 <view class="page">
2 <view class="app__bgc bgc" style="background-color: {{detailData.background}};"></view> 3 <view class="app__bgc bgc" style="background-color: {{detailData.background}};"></view>
3 <!-- <view class="app__bg bg " style="background: url('{{detailData.backgroundImage}}')"></view> --> 4 <!-- <view class="app__bg bg " style="background: url('{{detailData.backgroundImage}}')"></view> -->
...@@ -67,7 +68,7 @@ ...@@ -67,7 +68,7 @@
67 <!-- 尾部头像 --> 68 <!-- 尾部头像 -->
68 <view class="portrait"> 69 <view class="portrait">
69 <image class="portrait-inner" mode="scaleToFill" src="{{ownerMember.memberHead}}" /> 70 <image class="portrait-inner" mode="scaleToFill" src="{{ownerMember.memberHead}}" />
70 <image class="portrait-border" mode="scaleToFill" src="{{detailData.headFrame}}" /> 71 <image class="portrait-border ani-rotation" mode="scaleToFill" src="{{detailData.headFrame}}" />
71 </view> 72 </view>
72 <view class="name"> 73 <view class="name">
73 <view class="tt t1">{{ownerMember.memberName}}</view> 74 <view class="tt t1">{{ownerMember.memberName}}</view>
...@@ -185,4 +186,11 @@ ...@@ -185,4 +186,11 @@
185 <view class="t1">邀请你一起加入组队送祝福!</view> 186 <view class="t1">邀请你一起加入组队送祝福!</view>
186 </view> 187 </view>
187 </van-dialog> 188 </van-dialog>
189 <van-popup show="{{ authorizeVisible }}">
190 <authorize-comp bind:evtcomp="evtcomp"></authorize-comp>
191 </van-popup>
192 <van-popup bind:click-overlay="onHidePosterHandler" show="{{ posterVisible }}">
193 <image bindtap="onPreviewImageHandler" class="poster" mode="widthFix" src="{{imageUrl}}" />
194 <view bindtap="saveImageToPhotosAlbum" class="save-btn">一键保存</view>
195 </van-popup>
188 <shortcut2 types="{{[]}}" pics="{{['red-package2','more-bless']}}"></shortcut2> 196 <shortcut2 types="{{[]}}" pics="{{['red-package2','more-bless']}}"></shortcut2>
......