| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <template>
- <view class="createCode" v-if="isShow" @click.stop="isShow=false">
- <view class="content">
- <canvas :style="{ width: canvasW + 'px', height: canvasH + 'px' }" canvas-id="my-canvas"></canvas>
- <view class="save-btn" @click.stop="saveImage" v-if="!isLoading">保存图片</view>
- </view>
- <canvas :style="{ width: canvasW * 2 + 'px', height: canvasH * 2 + 'px' }" canvas-id="big-canvas" class="big-canvas"></canvas>
- </view>
- </template>
- <script>
- import { post } from "@/request/api.js";
- export default {
- props: {},
- data() {
- return {
- canvasW: 0,
- canvasH: 0,
- ctx: null,
- isShow: false,
- isLoading: true,
- title: "草莓千层蛋糕",
- qrcode: 'https://oss.zhangyubk.com/cmqrcode.jpg',
- headerImg: "https://teaclub.oss-cn-chengdu.aliyuncs.com/CloudShop/head_pic/268c896c47298c7c79a8270c36076741e8f15b0fjpg"
- }
- },
- methods: {
- //显示
- showCanvas(da) {
- this.isShow = true
- this.title = da.name
- this.isLoading = true
- uni.showLoading({ title: '加载中...', mask: true })
- this.getQrcode(da)
- },
- // 获取商家码
- async getQrcode(da){
- let res = await post("v1/merchant/xcxqrcode",da)
- if(res.code == 0) {
- console.log(res.data);
- this.qrcode = res.data;
- this.__init()
- }
- },
- //初始化画布
- async __init() {
- this.ctx = uni.createCanvasContext('my-canvas', this)
- this.bigCtx = uni.createCanvasContext('big-canvas', this)
- this.canvasW = uni.upx2px(600);
- this.canvasH = uni.upx2px(820);
- //设置画布背景透明
- this.ctx.setFillStyle('rgba(255, 255, 255, 0)')
- this.bigCtx.setFillStyle('rgba(255, 255, 255, 0)')
- //设置画布大小
- this.ctx.fillRect(0, 0, this.canvasW, this.canvasH)
- this.bigCtx.fillRect(0, 0, this.canvasW * 2, this.canvasH * 2)
- //绘制圆角背景
- this.drawRoundRect(this.ctx, 0, 0, this.canvasW, this.canvasH, uni.upx2px(18), '#FFFFFF')
- this.drawRoundRect(this.bigCtx, 0, 0, this.canvasW * 2, this.canvasH * 2, uni.upx2px(36), '#FFFFFF')
- //获取标题图片
- let headerImg = await this.getImageInfo(this.headerImg)
- //绘制标题图
- this.drawRoundImg(this.ctx, headerImg.path, 0, 0, this.canvasW, this.canvasH, 8)
- this.drawRoundImg(this.bigCtx, headerImg.path, 0, 0, this.canvasW * 2, this.canvasH * 2, 16)
- //绘制标题
- this.ctx.setFontSize(14); //设置标题字体大小
- this.ctx.setFillStyle('#333'); //设置标题文本颜色
- this.ctx.textAlign = 'center';
- this.ctx.fillText(this.title, (this.canvasW / 2), (this.canvasH - uni.upx2px(275)))
- this.bigCtx.setFontSize(28); //设置标题字体大小
- this.bigCtx.setFillStyle('#333'); //设置标题文本颜色
- this.bigCtx.textAlign = 'center';
- this.bigCtx.fillText(this.title, this.canvasW, (this.canvasH * 2 - uni.upx2px(275 * 2)))
- //小程序码
- let qrH = uni.upx2px(316);
- let qrcodeImg = await this.getImageInfo(this.qrcode)
- this.ctx.drawImage(qrcodeImg.path, ((this.canvasW - qrH) / 2), uni.upx2px(190), qrH, qrH)
- this.bigCtx.drawImage(qrcodeImg.path, this.canvasW - qrH, uni.upx2px(190 * 2), qrH * 2, qrH * 2)
- //延迟渲染
- setTimeout(() => {
- this.ctx.draw(true, () => {
- this.isLoading = false
- uni.hideLoading()
- })
- this.bigCtx.draw(true, () => {})
- }, 500)
- },
- //带圆角图片
- drawRoundImg(ctx, img, x, y, width, height, radius) {
- ctx.beginPath()
- ctx.save()
- // 左上角
- ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 1.5)
- // 右上角
- ctx.arc(x + width - radius, y + radius, radius, Math.PI * 1.5, Math.PI * 2)
- // 右下角
- ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI * 0.5)
- // 左下角
- ctx.arc(x + radius, y + height - radius, radius, Math.PI * 0.5, Math.PI)
- ctx.stroke()
- ctx.clip()
- ctx.drawImage(img, x, y, width, height);
- ctx.restore()
- ctx.closePath()
- },
- //圆角矩形
- drawRoundRect(ctx, x, y, width, height, radius, color) {
- ctx.save();
- ctx.beginPath();
- ctx.setFillStyle(color);
- ctx.setStrokeStyle(color)
- ctx.setLineJoin('round'); //交点设置成圆角
- ctx.setLineWidth(radius);
- ctx.strokeRect(x + radius / 2, y + radius / 2, width - radius, height - radius);
- ctx.fillRect(x + radius, y + radius, width - radius * 2, height - radius * 2);
- ctx.stroke();
- ctx.closePath();
- },
- //获取图片
- getImageInfo(imgSrc) {
- return new Promise((resolve, reject) => {
- uni.getImageInfo({
- src: imgSrc,
- success: (image) => {
- resolve(image);
- console.log('获取图片成功', image)
- },
- fail: (err) => {
- reject(err);
- console.log('获取图片失败', err)
- }
- });
- });
- },
- //保存图片到相册
- saveImage() {
- var that = this
- //判断用户授权
- uni.getSetting({
- success(res) {
- console.log('获取用户权限', res.authSetting)
- let wpa = res.authSetting['scope.writePhotosAlbum']
- //判断是否有相册权限
- if (wpa == undefined) that.runSave()
- else if (!wpa) { //打开设置权限
- uni.openSetting({
- success(res) {
- console.log('设置权限', res.authSetting)
- if(res.authSetting['scope.writePhotosAlbum']) that.runSave()
- }
- })
- }
- else that.runSave()
- }
- })
- },
- runSave(){
- var that = this
- uni.canvasToTempFilePath({
- canvasId: 'big-canvas',
- quality: 1,
- complete: (res) => {
- console.log('保存到相册', res);
- uni.saveImageToPhotosAlbum({
- filePath: res.tempFilePath,
- success(res) {
- uni.showToast({
- title: '已保存到相册',
- icon: 'success',
- duration: 2000
- })
- setTimeout(() => {
- that.isShow = false
- }, 2000)
- }
- })
- }
- }, this);
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .createCode{
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- min-height: 100vh;
- overflow: hidden;
- }
- .content {
- background: rgba(0, 0, 0, .4);
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- z-index: 100;
- padding: 100rpx 0;
- min-height: 100vh;
- .save-btn {
- margin-top: 35rpx;
- color: #FFFFFF;
- background: linear-gradient(to right, #018C39, #00B147);
- padding: 15rpx 40rpx;
- border-radius: 50rpx;
- }
- }
- .big-canvas{
- opacity: 0;
- z-index: 0;
- }
- </style>
|