|
|
@@ -0,0 +1,393 @@
|
|
|
+<template>
|
|
|
+ <view class="qiqb-ctx" v-bind:class="{ on: show == true }">
|
|
|
+ <view class="qiqb-ctx-box">
|
|
|
+ <text @click="close"></text>
|
|
|
+ <canvas
|
|
|
+ canvas-id="ctx"
|
|
|
+ style="width: 230px; height: 430px"
|
|
|
+ v-show="img_show"
|
|
|
+ ></canvas>
|
|
|
+ </view>
|
|
|
+ <view class="qiqb-ctx-btns u-border-bottom">
|
|
|
+ <view>点击下方按钮保存至相册</view>
|
|
|
+ <view></view>
|
|
|
+ <view>
|
|
|
+ <!-- <text @click="shareFriend">微信好友</text> -->
|
|
|
+ <!-- <text @click="shareTimeline">分享朋友圈</text> -->
|
|
|
+ <text @click="down">保存图片</text></view
|
|
|
+ >
|
|
|
+ </view>
|
|
|
+ <view class="qiqb-ctx-close" @click="close">取消</view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: "share",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ show: false,
|
|
|
+ img_show: true,
|
|
|
+ mode: "img",
|
|
|
+ opt: {
|
|
|
+ qrcode: "",
|
|
|
+ goods: {},
|
|
|
+ type: "",
|
|
|
+ },
|
|
|
+ userinfo: uni.getStorageSync("userinfo"),
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init(opt) {
|
|
|
+ console.log(opt, "===");
|
|
|
+ this.opt = opt;
|
|
|
+ let ctx = uni.createCanvasContext("ctx", this);
|
|
|
+
|
|
|
+ // 绘制背景
|
|
|
+ this.drawBg(ctx, 230, 430, 1, "#fff");
|
|
|
+
|
|
|
+ // 下载图片(⚠️ 注意:域名要在小程序后台配置 downloadFile 合法域名)
|
|
|
+ uni.downloadFile({
|
|
|
+ url: opt.goods.original_img,
|
|
|
+ success: (res1) => {
|
|
|
+ let img = res1.tempFilePath;
|
|
|
+ uni.downloadFile({
|
|
|
+ url: "https://teaclub.oss-cn-chengdu.aliyuncs.com/static/home.png",
|
|
|
+ success: (res2) => {
|
|
|
+ let photo = res2.tempFilePath;
|
|
|
+ uni.downloadFile({
|
|
|
+ url: opt.qrcode,
|
|
|
+ success: (res3) => {
|
|
|
+ let qrcode = res3.tempFilePath;
|
|
|
+
|
|
|
+ // 绘制图片
|
|
|
+ this.drawImg(ctx, photo, 10, 8, 30, 30, 0);
|
|
|
+ this.drawImg(ctx, img, 0, 45, 230, 230, 0);
|
|
|
+ this.drawImg(ctx, qrcode, 80, 358, 65, 65, 0);
|
|
|
+
|
|
|
+ // 绘制文字
|
|
|
+ // this.drawTxtOne(ctx, '茶付宝', 60, 24, 80, '#222', 13, true)
|
|
|
+ this.drawTxtOne(
|
|
|
+ ctx,
|
|
|
+ "推荐一个好物给你,请查收",
|
|
|
+ 45,
|
|
|
+ 28,
|
|
|
+ 200,
|
|
|
+ "#666",
|
|
|
+ 12,
|
|
|
+ false
|
|
|
+ );
|
|
|
+ this.drawTxtOne(ctx, "¥", 15, 295, 11, "#ED3327", 11, false);
|
|
|
+ this.drawTxtOne(
|
|
|
+ ctx,
|
|
|
+ opt.goods.cost_price,
|
|
|
+ 25,
|
|
|
+ 295,
|
|
|
+ 200,
|
|
|
+ "#ED3327",
|
|
|
+ 16,
|
|
|
+ true
|
|
|
+ );
|
|
|
+ this.drawTxtOne(
|
|
|
+ ctx,
|
|
|
+ "价格具有时效性,具体请以商详为主",
|
|
|
+ 15,
|
|
|
+ 313,
|
|
|
+ 200,
|
|
|
+ "#666",
|
|
|
+ 11,
|
|
|
+ false
|
|
|
+ );
|
|
|
+ this.drawTxtTwo(
|
|
|
+ ctx,
|
|
|
+ opt.goods.goods_name,
|
|
|
+ 15,
|
|
|
+ 330,
|
|
|
+ 190,
|
|
|
+ 20,
|
|
|
+ "#000",
|
|
|
+ 12
|
|
|
+ );
|
|
|
+
|
|
|
+ // 必须调用 draw 才能生效
|
|
|
+ ctx.draw(false, () => {
|
|
|
+ this.show = true;
|
|
|
+ this.img_show = true;
|
|
|
+ uni.hideLoading();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ close() {
|
|
|
+ this.show = false;
|
|
|
+ this.img_show = false;
|
|
|
+ },
|
|
|
+ down() {
|
|
|
+ uni.showLoading({ title: "生成中" });
|
|
|
+ uni.canvasToTempFilePath(
|
|
|
+ {
|
|
|
+ canvasId: "ctx",
|
|
|
+ quality: 1,
|
|
|
+ success: (res) => {
|
|
|
+ uni.hideLoading();
|
|
|
+ console.log(res);
|
|
|
+ this.$emit("down", res);
|
|
|
+ this.show = false;
|
|
|
+ this.img_show = false;
|
|
|
+ // 保存到相册 自定义实现
|
|
|
+ uni.saveImageToPhotosAlbum({
|
|
|
+ filePath: res.tempFilePath,
|
|
|
+ success: () => {
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: "已保存到相册",
|
|
|
+ icon: "success",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error("保存失败", err);
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: "保存失败",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error("生成失败", err);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ this
|
|
|
+ );
|
|
|
+ },
|
|
|
+ // 绘制背景 宽度 高度 圆角 颜色
|
|
|
+ drawBg(ctx, w, h, r, color) {
|
|
|
+ let x = 0;
|
|
|
+ let y = 0;
|
|
|
+ ctx.setFillStyle(color);
|
|
|
+ ctx.save();
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(x + r, y);
|
|
|
+ ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
|
+ ctx.arcTo(x + w, y + h, x, y + h, r);
|
|
|
+ ctx.arcTo(x, y + h, x, y, r);
|
|
|
+ ctx.arcTo(x, y, x + w, y, r);
|
|
|
+ ctx.closePath();
|
|
|
+ ctx.fill();
|
|
|
+ },
|
|
|
+ // 绘制图片 图片地址 距离左边 距离上边 宽度 高度 圆角
|
|
|
+ drawImg(ctx, img, x, y, w, h, r) {
|
|
|
+ let self = this;
|
|
|
+ ctx.save();
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
|
|
|
+ ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
|
|
|
+ ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
|
|
|
+ ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
|
|
|
+ ctx.clip();
|
|
|
+ ctx.drawImage(img, x, y, w, h);
|
|
|
+ ctx.restore();
|
|
|
+ },
|
|
|
+ // 绘制单行文字 图片地址 距离左边 距离上边 宽度 颜色 字号 加粗
|
|
|
+ drawTxtOne(ctx, text, x, y, maxWidth, color, size, bold) {
|
|
|
+ ctx.save();
|
|
|
+ ctx.beginPath();
|
|
|
+ let chr = text.split("");
|
|
|
+ let temp = "";
|
|
|
+ let row = [];
|
|
|
+ ctx.setFontSize(size);
|
|
|
+ ctx.setFillStyle(color);
|
|
|
+ for (let a = 0; a < chr.length; a++) {
|
|
|
+ if (ctx.measureText(temp).width < maxWidth) {
|
|
|
+ temp += chr[a];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ row.push(temp);
|
|
|
+ if (ctx.measureText(temp).width > maxWidth) row[0] = row[0] + "...";
|
|
|
+
|
|
|
+ for (var b = 0; b < row.length; b++) {
|
|
|
+ ctx.fillStyle = color;
|
|
|
+ if (bold) {
|
|
|
+ ctx.font = "normal bold " + size + "px sans-serif";
|
|
|
+ } else {
|
|
|
+ ctx.font = "normal " + size + "px sans-serif";
|
|
|
+ }
|
|
|
+ ctx.fillText(row[b], x, y);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 绘制两行文字 图片地址 距离左边 距离上边 宽度 行高 颜色 字号
|
|
|
+ drawTxtTwo(ctx, text, x, y, maxWidth, lineHeight, color, size) {
|
|
|
+ ctx.save();
|
|
|
+ ctx.beginPath();
|
|
|
+ let chr = text.split("");
|
|
|
+ let temp = "";
|
|
|
+ let row = [];
|
|
|
+ ctx.setFontSize(size);
|
|
|
+ ctx.setFillStyle(color);
|
|
|
+ for (let a = 0; a < chr.length; a++) {
|
|
|
+ if (ctx.measureText(temp).width < maxWidth) {
|
|
|
+ temp += chr[a];
|
|
|
+ } else {
|
|
|
+ a--;
|
|
|
+ row.push(temp);
|
|
|
+ temp = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ row.push(temp);
|
|
|
+ if (row.length > 2) {
|
|
|
+ let rowCut = row.slice(0, 2);
|
|
|
+ let rowPart = rowCut[1];
|
|
|
+ let test = "";
|
|
|
+ let empty = [];
|
|
|
+ for (var a = 0; a < rowPart.length; a++) {
|
|
|
+ if (ctx.measureText(test).width < maxWidth) {
|
|
|
+ test += rowPart[a];
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ empty.push(test);
|
|
|
+ var group = empty[0] + "...";
|
|
|
+ rowCut.splice(1, 1, group);
|
|
|
+ row = rowCut;
|
|
|
+ }
|
|
|
+ for (var b = 0; b < row.length; b++) {
|
|
|
+ ctx.fillStyle = color;
|
|
|
+ ctx.font = "normal " + size + "px sans-serif";
|
|
|
+ ctx.fillText(row[b], x, y + b * lineHeight, 300);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 绘制删除线文字 图片地址 距离左边 距离上边 行高 颜色 字号 加粗
|
|
|
+ drawTxtDel(ctx, txt, x, y, h, color, size) {
|
|
|
+ ctx.fillStyle = color;
|
|
|
+ ctx.font = "normal " + size + "px sans-serif";
|
|
|
+ ctx.fillText(txt, x, y);
|
|
|
+
|
|
|
+ ctx.beginPath();
|
|
|
+ let width = ctx.measureText(txt).width;
|
|
|
+ ctx.rect(x, y - h, width, 1);
|
|
|
+ ctx.fillStyle = color;
|
|
|
+ ctx.fill();
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.qiqb-ctx {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: -1;
|
|
|
+ display: flex;
|
|
|
+ background: rgba(0, 0, 0, 0.6);
|
|
|
+ opacity: 0;
|
|
|
+ transition: all 0.3s;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-end;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+.qiqb-ctx.on {
|
|
|
+ z-index: 2000;
|
|
|
+ opacity: 99999999;
|
|
|
+}
|
|
|
+.qiqb-ctx-box {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ padding: 30upx 0 40upx;
|
|
|
+ width: 750upx;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+.qiqb-ctx-box text {
|
|
|
+ position: absolute;
|
|
|
+ top: -40upx;
|
|
|
+ right: 145upx;
|
|
|
+ display: inline-flex;
|
|
|
+ width: 47upx;
|
|
|
+ height: 47upx;
|
|
|
+ background: url(https://teaclub.oss-cn-chengdu.aliyuncs.com/img/icon_917/close.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns {
|
|
|
+ display: flex;
|
|
|
+ width: 750upx;
|
|
|
+ height: 280upx;
|
|
|
+ border-radius: 20upx 20upx 0 0;
|
|
|
+ background: #fff;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(1) {
|
|
|
+ display: flex;
|
|
|
+ padding-top: 10upx;
|
|
|
+ height: 80upx;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 30upx;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(2) {
|
|
|
+ height: 80upx;
|
|
|
+ color: #666;
|
|
|
+ font-size: 24upx;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(3) {
|
|
|
+ display: flex;
|
|
|
+ padding-bottom: 30upx;
|
|
|
+ font-size: 26upx;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(3) text {
|
|
|
+ display: flex;
|
|
|
+ width: 250upx;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(3) text:nth-child(1)::before {
|
|
|
+ display: inline-flex;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ width: 86upx;
|
|
|
+ height: 86upx;
|
|
|
+ background: url(https://teaclub.oss-cn-chengdu.aliyuncs.com/img/icon_917/3.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ content: "";
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(3) text:nth-child(2)::before {
|
|
|
+ display: inline-flex;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ width: 86upx;
|
|
|
+ height: 86upx;
|
|
|
+ background: url(https://teaclub.oss-cn-chengdu.aliyuncs.com/img/icon_917/3.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ content: "";
|
|
|
+}
|
|
|
+.qiqb-ctx-btns view:nth-child(3) text:nth-child(3)::before {
|
|
|
+ display: inline-flex;
|
|
|
+ margin-bottom: 20upx;
|
|
|
+ width: 86upx;
|
|
|
+ height: 86upx;
|
|
|
+ background: url(https://teaclub.oss-cn-chengdu.aliyuncs.com/img/icon_917/3.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ content: "";
|
|
|
+}
|
|
|
+.qiqb-ctx-close {
|
|
|
+ display: flex;
|
|
|
+ padding-bottom: 50upx;
|
|
|
+ width: 100%;
|
|
|
+ height: 150upx;
|
|
|
+ background: #fff;
|
|
|
+ font-size: 32upx;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+</style>
|