이 기사에서는 WeChat 애플릿그림 저장 구성 요소 개발에 대해 이야기하겠습니다. 모든 사람에게 도움이 되기를 바랍니다.
많은 WeChat 미니 프로그램에서는 더 많은 사람들에게 미니 프로그램을 알리기 위해 포스터를 저장하여 활동을 공유할 수 있습니다. 미니 프로그램을 개발할 때 이런 현상을 접한 적이 있을 것입니다. [관련 학습 추천 : 미니 프로그램 개발 튜토리얼]
오늘은 회사에서 만든 작은 프로그램에 포스터를 저장하는 기능을 공유해보겠습니다. 먼저, 이전 회사에서는 어떤 요구사항이 있었는지 먼저 설명하겠습니다. 회사의 온라인 미니 프로그램은 신규 사용자를 홍보하는 장기적인 목적을 가지고 있습니다. 각 사용자는 자신만의 포스터를 가지고 있어야 하며 개인 포스터를 통한 홍보는 간단한 방법입니다.
과제를 받고 먼저 유니버셜 인터넷에 검색을 하러 갔는데, 형이 비슷한 일을 했다고 하더군요. 그냥 과제를 끝내기 위한 것이었기 때문에 코드가 너무 지저분해서 나중에는 다른 프로젝트의 코드에서 찾아보다가 찾았네요~~ 하지만 주어진 시간도 빡빡하고 업무도 무거워서 좀 수정해서 먼저 제출하게 되었습니다. 그 후 온라인 기사를 따라가며 함정을 단계별로 따라가며 포스터를 저장하는 구성요소를 단계별로 구현했습니다.
우선, 그림 그리기, 텍스트 그리기, 포스터 앨범 저장 등의 기본 기능을 구체적으로 구현한 uniapp을 사용한다는 점을 말씀드립니다.
캔버스를 통해 포스터를 그립니다. 그려진 캔버스를 그림으로 변환하려면 uni.canvasToTempFilePath
를 사용하세요. 휴대폰 앨범의 로컬 임시 경로에 사진을 저장하려면 uni.saveImageToPhotosAlbum
을 사용하세요. 내 생각은 사용되는 모든 메소드를 구성요소에 캡슐화하고 상위 구성요소만 사용하여 사용해야 하는 메소드를 호출하고 관련 매개변수를 조정하는 것입니다. 구체적인 사용법은 샘플 코드를 확인하세요uni.canvasToTempFilePath
将绘制好的 canvas转为图片。通过uni.saveImageToPhotosAlbum
将本地临时路径的图片保存至手机相册中。而我的想法是将所有采用的方法全部封装到组件中,只通过父组件去调用需要使用的方法和调整相关的参数即可。 具体使用可以查看示例代码
通过使用promise对象决定绘制海报内容的顺序先后。promise.all()
方法进行canvas最后一步的绘画操作 context.draw()
在绘制图片 和 头像时,组件通过uni.getImageInfo()
promise.all()
메서드는 캔버스 그리기 작업 context.draw()
uni.getImageInfo()
를 통해 그림의 관련 정보를 얻습니다. 이 메서드를 성공적으로 호출하기 위한 전제 조건은 다운로드 도메인 이름과 다운로드 도메인 이름은 WeChat 애플릿 백그라운드에서 구성해야 합니다. 물론 오류를 방지하려면 uploadFile 도메인 이름과 함께 요청 도메인 이름을 구성하는 것이 가장 좋습니다. 하지만 공식적인 팁은 다운로드 도메인 이름 화이트리스트를 구성했지만 이미지 정보를 얻을 수 없다는 것이 큰 함정입니다.
해당 구성이 없으면 디버깅이나 평가판, 정식 버전 등을 수행하는 동안 vconsole 디버깅 도구를 엽니다. uni.getImageInfo()는 이미지 정보를 얻을 수 있습니다. vconsole이 닫히면 uni.getImageInfo()가 실패하며 이는 함정이기도 합니다. 샘플 code
<template> <view> <view class="savePosterItem"> <image v-show="tempFilePath" :src="tempFilePath"></image> <save-poster-com v-show="!tempFilePath" ref="savePoster" :canvasInfo="canvasInfo"></save-poster-com> </view> <button class="savePosterBtn" type="primary" @click="saveBtnFun">保存海报</button> </view> </template> <script> import SavePosterCom from '@/components/SavePosterCom/SavePosterCom.vue' export default { components: { SavePosterCom }, data() { return { canvasInfo: { canvasWidth: 620, canvasHeight: 950, canvasId: 'save-poster' }, tempFilePath: '', canvasBgUrl: 'https://images.pexels.com/photos/4065617/pexels-photo-4065617.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500', avatarUrl: 'https://p9-passport.byteacctimg.com/img/user-avatar/4dbf31fa6dec9c65b78a70d28d843c04~300x300.image' } }, onLoad() { let { drawCanvasImage, drawCircularAvatar, drawText } = this.$refs.savePoster.$options.methods this.$refs.savePoster.canvasInit(({ context, comThis }) => { // 获取画布宽高 let canvasWH = comThis.canvasWH // 绘制海报背景图 let promise_1 = drawCanvasImage(context, this.canvasBgUrl, canvasWH.canvasWidth, canvasWH.canvasHeight) // 必须先绘制玩海报背景图 再去操作其他绘制内容 promise_1.then(res => { let promise_2 = drawCircularAvatar(context, this.avatarUrl, canvasWH.canvasWidth / 2, canvasWH.canvasHeight / 7, 70) let promise_3 = drawText({ context: context, text: '皮皮虾仁', dx: (canvasWH.canvasWidth / 2) + 60, dy: canvasWH.canvasHeight / 4, fontSize: 30, fontColor: '#5D4037' }) let promise_4 = drawCanvasImage(context, this.avatarUrl, 150, 150, (canvasWH.canvasWidth / 2) + 85, (canvasWH.canvasHeight - 165)) this.$refs.savePoster.startDrawToImage(context, [promise_1,promise_2,promise_4], (tempFilePath) => { this.tempFilePath = tempFilePath }) }) }) }, methods: { saveBtnFun() { uni.showModal({ title: '保存海报', content: '海报将被保存至相册中', confirmText: '保存', success: (res) => { if(res.confirm) { this.$refs.savePoster.posterToPhotosAlbum(this.tempFilePath) } } }) } } } </script> <style> .savePosterItem { text-align: center; } .savePosterItem > image { width: 620rpx; height: 950rpx; } .savePosterBtn { margin-top: 40rpx; width: 80%; } </style>