小程序 画布 cavas

<template>
  <view>
    <!-- <img width="100%" height="90vh" :src="showImg" show-menu-by-longpress />
    <button class="saveLocalShow" @click="saveLocal">保存本地</button>   v-show="!showImg"-->
    <canvas canvas-id="mycanvas" class="canvas" id="mycanvas" />
  </view>
</template>

<script>
import { wrapText, roundRect } from "@/utils/canvas";
export default {
  data() {
    return {
      windowWidth: "",
      windowHeight: "",
      showImg: "",
      erweimaCode: "https://res.zhixinren.work/prod/5c19e3ea-397d-4fa4-992a-89b60d6f94df/0b1ffd9d-71cd-4bd5-b8de-a5a328b3877c.png",
      imgBack: "https://res.zhixinren.work/prod/93e10b03-4abf-4a42-bfb8-e9e6021539bb/52df853c-d6d7-4100-b26b-b55b4536af2a.png",
      logo: "https://res.zhixinren.work/prod/efff0f1d-5bd5-449d-a302-d67b0caa1c7f/caf56d6c-eff4-4646-8656-4d084d526052.png"
    };
  },
  methods: {
    previewImage() {
      this.canvasToFilePath(filePath => {
        console.log("123", filePath);
        this.showImg = filePath;
      });
    },
    saveLocal() {
      uni.showLoading({ title: "图片保存中..." });
      this.canvasToFilePath(filePath => {
        console.log(filePath, 555);
        uni.saveImageToPhotosAlbum({
          filePath: filePath,
          success: res => {
            uni.showToast({
              title: "保存成功",
              duration: 2000
            });
            uni.hideLoading();
          },
          fail: err => {
            if (
              err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
              err.errMsg === "saveImageToPhotosAlbum:fail auth deny" ||
              err.errMsg === "saveImageToPhotosAlbum:fail authorize no response"
            ) {
              uni.showModal({
                title: "提示",
                content: "需要您授权保存相册",
                showCancel: false,
                success: modalSuccess => {
                  uni.openSetting({
                    success(settingdata) {
                      console.log(settingdata, 8888);
                      if (settingdata.authSetting["scope.writePhotosAlbum"]) {
                        uni.showToast({
                          title: "保存成功",
                          duration: 2000
                        });
                        console.log("获取权限成功,给出再次点击图片保存到相册的提示。");
                      } else {
                        uni.showToast({
                          title: "获取权限失败",
                          duration: 2000
                        });
                        console.log("获取权限失败,给出不给权限就无法正常使用的提示");
                      }
                    }
                  });
                }
              });
            }
            // 4 不管成功失败都关闭提示信息!!!
            console.log("saveImageToPhotosAlbum 失败");
            uni.hideLoading();
          }
        });
      });
    },
    canvasToFilePath(cb) {
      const width = wx.getSystemInfoSync().windowWidth;
      const height = wx.getSystemInfoSync().windowHeight;

      this.windowWidth = width;
      this.windowHeight = height - 45;
      uni.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: width,
        height: height,
        destWidth: width * this.dpr,
        destHeight: (height - 45) * this.dpr, // * this.dpr
        canvasId: "mycanvas",
        quality: 1,
        success: function(res) {
          cb(res.tempFilePath);
        },
        fail: function(err) {
          console.log("debug log --> ", err);
        }
      });
    },
    canvas(bgPicturePath1, logo, erweimaCode) {
      console.log("bgPicturePath1", bgPicturePath1);
      const _this = this;
      var ctx = wx.createCanvasContext("mycanvas");
      // ctx.scale(this.dpr, this.dpr);
      const { dpr } = this;
      const width = wx.getSystemInfoSync().windowWidth;
      const height = wx.getSystemInfoSync().windowHeight - 45;
      // const bgPicturePath = require("./img/back.png");
      ctx.width = width * dpr;
      ctx.height = height * dpr;
      // ctx.scale(dpr, dpr);
      // 背景
      ctx.drawImage(bgPicturePath1, 0, 0, width, height);
      // 白色框
      roundRect(ctx, 16, 48, width - 16 * 2, 224, 8);
      // this.fillRoundRect(ctx, 16, 58, width - 32, 230, 10, "#fff");
      // 绘制职位信息
      const startW = 16 + 16;
      const startH = 48 + 24;
      const nametxt = "产品经理";
      const nameWidth = ctx.measureText(nametxt).width;
      console.log(nameWidth);
      ctx.font = "normal bold 16px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#3C3D43";
      ctx.fillText(nametxt, startW, startH, nameWidth, 16);

      // 急招标签
      const jzTag = true;
      if (jzTag) {
        // box
        roundRect(ctx, startW + nameWidth + 8, startH, 32, 16, 2, "#FF8657");
        // boxText
        ctx.font = "normal normal 10px sans-serif";
        ctx.textBaseline = "top";
        ctx.fillStyle = "#fff";
        ctx.fillText("急招", startW + nameWidth + 8 + 6, startH + 4, 32, 16);
      }

      // 全职标签
      const qzTag = true;
      if (qzTag) {
        // box
        const qzstartW = jzTag ? startW + nameWidth + 8 + 32 : startW + nameWidth + 8;
        roundRect(ctx, qzstartW + 8, startH, 32, 16, 2, "#fff", 1, "#4686FF");
        // boxText
        ctx.font = "normal normal 10px sans-serif";
        ctx.textBaseline = "top";
        ctx.fillStyle = "#4686FF";
        ctx.fillText("全职", qzstartW + 8 + 6, startH + 4, 32, 16);
      }

      // 城市
      const cityTxt = "山东省 青岛市";
      const cityWidth = ctx.measureText(cityTxt).width;
      const citystartW = width - 16 - 16 - cityWidth;
      ctx.font = "normal normal 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#ACAFC5";
      ctx.fillText(cityTxt, citystartW, startH + 4, cityWidth, 16);

      // 钱数money
      const moneystartH = startH + 16 + 12;
      const moneyTxt = "6000-7000元";
      const moneyWidth = ctx.measureText(moneyTxt).width;
      ctx.font = "normal bold 18px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#3070FF";
      ctx.fillText(moneyTxt, startW, moneystartH, moneyWidth, 18);

      // 第三行 年限等
      const yearstartH = moneystartH + 18 + 12;
      const yearTxt = "3-5年wqe";
      const yearWidth = ctx.measureText(yearTxt).width;
      ctx.font = "normal normal 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#767885";
      ctx.fillText(yearTxt, startW, yearstartH, yearWidth, 12);

      // |
      ctx.font = "normal normal 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#767885";
      ctx.fillText("|", startW + yearWidth - 9, yearstartH, 1, 12);
      // 学历
      const xueliTxt = "专科以上";
      const xueliWidth = ctx.measureText(xueliTxt).width;
      ctx.font = "normal normal 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#767885";
      ctx.fillText(xueliTxt, startW + yearWidth + 8 + 1, yearstartH, xueliWidth, 12);
      // 五险一金标签;
      const wxyjTag = true;
      const wxyjArr = ["五险一金", "定期体检", "管吃管住"];
      if (wxyjTag) {
        let TapNum = -ctx.measureText(wxyjArr[0]).width;
        wxyjArr.map((i, index) => {
          // const Tap = ctx.measureText(i).width;
          const TapBox = ctx.measureText(i).width + 8 + 8;
          TapNum += TapBox;
          // boxText
          ctx.font = "normal normal 12px sans-serif";
          ctx.textBaseline = "top";
          ctx.fillStyle = "#4686FF";
          ctx.fillText(i, startW + 8 + TapNum, startH + 83 + 5, 48, 20);
          // box
          roundRect(ctx, startW + TapNum, yearstartH + 12 + 12, TapBox, 22, 2, "rgba(70, 134, 255, 0.1)", 1, "rgba(70, 134, 255, 0.6)");
        });
      }

      // 横线
      roundRect(ctx, startW, yearstartH + 12 + 12 + 22 + 12, width - 16 * 4, 0.5, 0, "#E3E6F1");

      // 公司信息
      const companystartH = yearstartH + 12 + 12 + 22 + 12 + 16;
      ctx.drawImage(this.erweimaCode, startW, companystartH, 48, 48);
      // const companyImg = canvas.createImage();
      // companyImg.src = this.erweimaCode;
      // companyImg.onload = () => {
      //   ctx.drawImage(companyImg, startW, companystartH, 48, 48);
      // };
      // 公司名称
      const companyTxt = "网络科技有限公司";
      const companyWidth = ctx.measureText(companyTxt).width;
      ctx.font = "normal 500 14px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#55565D";
      ctx.fillText(companyTxt, startW + 48 + 8, companystartH + 5, companyWidth, 14);
      // 行业
      const industryTxt = "青岛市 互联网";
      const industryWidth = ctx.measureText(industryTxt).width;
      ctx.font = "normal 400 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#767885";
      ctx.fillText(industryTxt, startW + 48 + 8, companystartH + 5 + 14 + 12, industryWidth, 14);
      //
      const enterpriseTxt = "企业服务";
      const enterpriseWidth = ctx.measureText(enterpriseTxt).width;
      ctx.font = "normal 400 12px sans-serif";
      ctx.textBaseline = "top";
      ctx.fillStyle = "#767885";
      ctx.fillText(enterpriseTxt, startW + 48 + 8 + industryWidth + 5, companystartH + 5 + 14 + 12, enterpriseWidth, 14);

      // Logo
      // const logoImg = canvas.createImage();
      // logoImg.src = "/shareCanvas/img/logo.png";
      // logoImg.onload = () => {
      //   ctx.drawImage(logoImg, 16, height - 114, 86, 28);
      // };
      ctx.drawImage(erweimaCode, width - 16 - 188, height - 170, 166, 166);
      //
      // 调用draw()开始绘制
      ctx.draw();
      this.previewImage();
    },
    circleImg(ctx, img, x, y, r) {
      ctx.save();
      var d = 2 * r;
      var cx = x + r;
      var cy = y + r;
      ctx.arc(cx, cy, r, 0, 2 * Math.PI);
      ctx.clip();
      ctx.drawImage(img, x, y, d, d);
      ctx.restore();
    },
    // 二维码图片
    handleNetImg(imageUrl) {
      const that = this;
      return new Promise((resolve, reject) => {
        // console.log("imageUrl1", imageUrl);
        uni.getImageInfo({
          src: imageUrl,
          success: function(res) {
            resolve(res);
          },
          fail: function(err) {
            reject(err);
          }
        });
      });
    },
    fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
      // 圆的直径必然要小于矩形的宽高
      if (2 * radius > width || 2 * radius > height) {
        return false;
      }

      cxt.save();
      cxt.translate(x, y);
      // 绘制圆角矩形的各个边
      this.drawRoundRectPath(cxt, width, height, radius);
      cxt.fillStyle = fillColor || "#000"; // 若是给定了值就用给定的值否则给予默认值
      cxt.fill();
      cxt.restore();
    },
    drawRoundRectPath(cxt, width, height, radius) {
      cxt.beginPath(0);
      // 从右下角顺时针绘制,弧度从0到1/2PI
      cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
      // 矩形下边线
      cxt.lineTo(radius, height);
      // 左下角圆弧,弧度从1/2PI到PI
      cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
      // 矩形左边线
      cxt.lineTo(0, radius);
      // 左上角圆弧,弧度从PI到3/2PI
      cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);
      // 上边线
      cxt.lineTo(width - radius, 0);
      // 右上角圆弧
      cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
      // 右边线
      cxt.lineTo(width, height - radius);
      cxt.closePath();
    },
    async goCanvas() {
      const code = await this.handleNetImg(`${this.imgBack}`);
      const logo = await this.handleNetImg(`${this.logo}`);
      const erweimaCode = await this.handleNetImg(`${this.erweimaCode}`);

      this.canvas(code.path, logo.path, erweimaCode.path);
    }
  },
  mounted() {
    this.dpr = wx.getSystemInfoSync().pixelRatio;
    this.goCanvas();
  },
  onLoad() {}
};
</script>

<style scoped>
img {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  z-index: 999;
  bottom: 70px;
  width: 100% !important;
  height: 90vh !important;
}
.canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 100vw;
  height: 100vh;
}
.saveLocalShow {
  position: absolute;
  bottom: 0px;
  z-index: 7777777;
  width: 100%;
  color: #3070ff;
}
</style>

 

posted on 2021-10-08 09:50  阿政kris*  阅读(100)  评论(0编辑  收藏  举报