<template>
  <view class="draw-style1">
    <u-top-tips ref="uTips"></u-top-tips>
    <img :src="tempPic" mode="widthFix" :style="{ width: 750 * zoom + 'px' }" />
    <canvas
      canvas-id="firstCanvas"
      class="sty-box"
      @error="canvasIdErrorCallback"
    ></canvas>
  </view>
</template>

<script>
export default {
  props: {
    autoHeight: {
      type: String,
      default: "0",
    },
    images: {
      type: Array,
      default: [],
    },
    bgType: {
      type: Number,
      default: 0,
    },
    bgColor: {
      type: String,
      default: "",
    },
    info: {
      type: Object,
      default: {},
    },
  },
  data() {
    return {
      zoom: 1,
      config: {
        images: [],
        bgType: 1,
        bgColor: "",
        info: {},
        loca_images: [],
      },
      ctx: null,
      tempPic: "",
    };
  },
  watch: {
    images: {
      handler: function (val, oldval) {
        this.config.images = val;
        this.drawCtx();
      },
      deep: true,
    },
    bgType: {
      handler: function (val, oldval) {
        this.config.bgType = val;
        this.drawCtx();
      },
      deep: true,
    },
    bgColor: {
      handler: function (val, oldval) {
        this.config.bgColor = val;
        this.drawCtx();
      },
      deep: true,
    },
    info: {
      handler: function (val, oldval) {
        this.config.info = val;
        this.drawCtx();
      },
      deep: true,
    },
  },
  mounted() {
    this.zoom = (parseFloat(this.autoHeight) / 1344.0).toFixed(2);
    this.config.images = this.images;
    this.config.bgType = this.bgType;
    this.config.bgColor = this.bgColor;
    this.drawCtx();
  },
  onReady: function (e) {},
  methods: {
    colorRgb(color) {
      var sColor = color.toLowerCase();
      //十六进制颜色值的正则表达式
      var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
      // 如果是16进制颜色
      if (sColor && reg.test(sColor)) {
        if (sColor.length === 4) {
          var sColorNew = "#";
          for (var i = 1; i < 4; i += 1) {
            sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
          }
          sColor = sColorNew;
        }
        //处理六位的颜色值
        var sColorChange = [];
        for (var i = 1; i < 7; i += 2) {
          sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
        }
        return sColorChange.join(",");
      }
      return sColor;
    },
    saveImage() {
      uni.showLoading({
        title: "正在生成海报",
      });
      let that = this;
      uni.canvasToTempFilePath(
        {
          canvasId: "firstCanvas",
          success: (res) => {
            uni.hideLoading();
            uni.showLoading({
              title: "正在保存海报",
            });
            uni.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success: function () {
                uni.showToast({
                  title: "保存成功",
                });
              },
              fail: function (e) {
                that.$refs.uTips.show({
                  title: "保存失败，请稍后重试",
                  type: "error",
                  duration: "2300",
                });
              },
              complete: function () {
                uni.hideLoading();
              },
            });
          },
          fail: function (e) {
            console.log(e);
            that.$refs.uTips.show({
              title: "生成失败，请稍后重试",
              type: "error",
              duration: "2300",
            });
          },
        },
        this
      );
    },
    drawCtx() {
      uni.showLoading({
        title: "正在生成海报",
      });
      let ctx = uni.createCanvasContext("firstCanvas", this);
      let that = this;
      if (!this.info.avatar_loca) {
        uni.getImageInfo({
          src: this.info.avatar,
          success: function (image) {
            that.drawBg(ctx);
            that.info.avatar_loca = image.path;
            that.drawAvatar(ctx);
            that.drawTitle(ctx);
            that.drawGoodPicture(ctx);
          },
        });
      } else {
        this.drawBg(ctx);
        this.drawAvatar(ctx);
        this.drawTitle(ctx);
        this.drawGoodPicture(ctx);
      }
    },
    drawGoodPicture(ctx) {
      console.log(this.config.images);
      if (this.config.images.length == 1) {
        this.drawOnePic(ctx);
      } else if (this.config.images.length == 2) {
        this.drawTowPic(ctx);
      } else if (this.config.images.length == 3) {
        this.drawThreePic(ctx);
      } else if (this.config.images.length == 4) {
        this.drawFourPic(ctx);
      } else if (this.config.images.length == 5) {
        this.drawFivePic(ctx);
      }
    },
    drawAvatar(ctx) {
      ctx.save();
      ctx.beginPath();
      ctx.arc(24 + 45, 95 + 45, 45, 0, Math.PI * 2);
      ctx.setFillStyle("#ffffff");
      ctx.fill();
      ctx.clip();
      ctx.drawImage(this.info.avatar_loca, 24, 95, 90, 90);
      ctx.restore();
    },
    drawTitle(ctx) {
      let text = this.info.nickname + "向您推荐一个好物";
      this.roundRect(
        ctx,
        24 + 90 + 20,
        95 + 20,
        text.length * 22+20,
        55,
        55,
        "#f5f5f5"
      );
      ctx.fillStyle = "#000000";
      ctx.font = "20px 'microsoft yahei'";
      ctx.fillText(text, 24 + 134, 95 + 55);
    },
    drawBg(ctx) {
      if (this.config.bgType == 1) {
        ctx.fillStyle = this.config.bgColor;
        ctx.fillRect(0, 0, 750, 1344);
      } else {
        let g = ctx.createLinearGradient(0, 0, 0, 1344);
        g.addColorStop(0, this.config.bgColor);
        console.log(`rgba(${this.colorRgb(this.config.bgColor)},0.3)`);
        g.addColorStop(1, `rgba(${this.colorRgb(this.config.bgColor)},0.3)`);
        ctx.fillStyle = g;
        ctx.fillRect(0, 0, 750, 1344);
      }
    },
    drawQrCode(ctx) {
      let that = this;
      uni.getImageInfo({
        src: this.info.qrcode_url,
        success: function (image) {
          ctx.drawImage(image.path, 480, 975, 215, 215);
          ctx.draw(false, () => {
            uni.canvasToTempFilePath(
              {
                x: 0,
                y: 0,
                width: 750,
                height: 1344,
                destWidth: 750.0 * that.zoom,
                destHeight: 1344.0 * that.zoom,
                canvasId: "firstCanvas",
                success: (res) => {
                  console.log(res);
                  uni.hideLoading();
                  that.tempPic = res.tempFilePath;
                },
                fail(e) {
                  console.log(e);
                },
              },
              that
            );
          });
        },
      });
    },
    drawOnePic(ctx) {
      let that = this;
      if (!this.config.loca_images[0]) {
        uni.getImageInfo({
          src: this.config.images[0],
          success: function (image) {
            that.config.loca_images[0] = image.path;
            ctx.drawImage(image.path, 24, 95 + 130, 702, 702);
            that.otherDraw(ctx);
          },
        });
      } else {
        ctx.drawImage(this.config.loca_images[0], 24, 95 + 130, 702, 702);
        that.otherDraw(ctx);
      }
    },
    drawTowPic(ctx) {
      if (this.config.loca_images.length < 2) {
        let that = this;
        uni.getImageInfo({
          src: this.config.images[this.config.loca_images.length],
          success: function (image) {
            console.log(image);
            that.config.loca_images.push(image);
            that.drawTowPic(ctx);
          },
        });
      } else {
        ctx.fillStyle = "#000";
        ctx.fillRect(24, 95 + 130, 702, 351);
        var imgRect = this.coverImg(
          702,
          351,
          this.config.loca_images[0].width,
          this.config.loca_images[0].height
        );
        ctx.drawImage(
          this.config.loca_images[0].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          24,
          95 + 130,
          702,
          351
        );

        ctx.fillStyle = "#000";
        ctx.fillRect(24, 95 + 481, 702, 351);
        var imgRect = this.coverImg(
          702,
          351,
          this.config.loca_images[1].width,
          this.config.loca_images[1].height
        );
        ctx.drawImage(
          this.config.loca_images[1].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          24,
          95 + 481,
          702,
          351
        );

        this.otherDraw(ctx);
      }
    },
    drawThreePic(ctx) {
      if (this.config.loca_images.length < 3) {
        let that = this;
        uni.getImageInfo({
          src: this.config.images[this.config.loca_images.length],
          success: function (image) {
            that.config.loca_images.push(image);
            that.drawThreePic(ctx);
          },
        });
      } else {
        ctx.fillStyle = "#000";
        ctx.fillRect(24, 95 + 130, 702, 351);
        var imgRect = this.coverImg(
          702,
          351,
          this.config.loca_images[0].width,
          this.config.loca_images[0].height
        );
        ctx.drawImage(
          this.config.loca_images[0].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          24,
          95 + 130,
          702,
          351
        );

        ctx.drawImage(this.config.loca_images[1].path, 24, 95 + 481, 351, 351);

        ctx.drawImage(
          this.config.loca_images[2].path,
          24 + 351,
          95 + 481,
          351,
          351
        );

        this.otherDraw(ctx);
      }
    },
    drawFourPic(ctx) {
      if (this.config.loca_images.length < 4) {
        let that = this;
        uni.getImageInfo({
          src: this.config.images[this.config.loca_images.length],
          success: function (image) {
            that.config.loca_images.push(image);
            that.drawFourPic(ctx);
          },
        });
      } else {
        ctx.drawImage(this.config.loca_images[0].path, 24, 95 + 130, 351, 351);
        ctx.drawImage(
          this.config.loca_images[1].path,
          24 + 351,
          95 + 130,
          351,
          351
        );
        ctx.drawImage(this.config.loca_images[2].path, 24, 95 + 481, 351, 351);
        ctx.drawImage(
          this.config.loca_images[3].path,
          24 + 351,
          95 + 481,
          351,
          351
        );
        this.otherDraw(ctx);
      }
    },
    drawFivePic(ctx) {
      if (this.config.loca_images.length < 5) {
        let that = this;
        uni.getImageInfo({
          src: this.config.images[this.config.loca_images.length],
          success: function (image) {
            console.log(image);
            that.config.loca_images.push(image);
            that.drawFivePic(ctx);
          },
        });
      } else {
        ctx.drawImage(this.config.loca_images[0].path, 24, 95 + 130, 351, 351);
        ctx.drawImage(this.config.loca_images[1].path, 24, 95 + 481, 351, 351);

        ctx.fillStyle = "#000";
        ctx.fillRect(375, 225, 351, 234);
        var imgRect = this.coverImg(
          351,
          234,
          this.config.loca_images[2].width,
          this.config.loca_images[2].height
        );
        ctx.drawImage(
          this.config.loca_images[2].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          375,
          225,
          351,
          234
        );
        ctx.fillStyle = "#000";
        ctx.fillRect(375, 459, 351, 234);
        imgRect = this.coverImg(
          351,
          234,
          this.config.loca_images[3].width,
          this.config.loca_images[3].height
        );
        ctx.drawImage(
          this.config.loca_images[3].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          375,
          459,
          351,
          234
        );
        ctx.fillStyle = "#000";
        ctx.fillRect(375, 693, 351, 234);
        imgRect = this.coverImg(
          351,
          234,
          this.config.loca_images[4].width,
          this.config.loca_images[4].height
        );
        ctx.drawImage(
          this.config.loca_images[4].path,
          imgRect.sx,
          imgRect.sy,
          imgRect.sWidth,
          imgRect.sHeight,
          375,
          693,
          351,
          234
        );
        this.otherDraw(ctx);
      }
    },
    coverImg(box_w, box_h, source_w, source_h) {
      var sx = 0,
        sy = 0,
        sWidth = source_w,
        sHeight = source_h;
      if (source_w > source_h || (source_w == source_h && box_w < box_h)) {
        sWidth = (box_w * sHeight) / box_h;
        sx = (source_w - sWidth) / 2;
      } else if (
        source_w < source_h ||
        (source_w == source_h && box_w > box_h)
      ) {
        sHeight = (box_h * sWidth) / box_w;
        sy = (source_h - sHeight) / 2;
      }
      return {
        sx,
        sy,
        sWidth,
        sHeight,
      };
    },

    otherDraw(ctx) {
      let x = 24;
      let y = 797 + 130;
      let w = 702;
      let h = 310;
      let r = 20;
      if (w < 2 * r) {
        r = w / 2;
      }
      if (h < 2 * r) {
        r = h / 2;
      }

      ctx.beginPath();
      ctx.fillStyle = "#FFF";

      //   ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
      ctx.moveTo(x, y);
      ctx.lineTo(x + w, y);
      //ctx.lineTo(x + w, y + r);

      //ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
      //ctx.lineTo(x + w, y + h - r);
      ctx.lineTo(x + w, y + h);

      ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
      ctx.lineTo(x + r, y + h);
      ctx.lineTo(x, y + h - r);

      ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
      ctx.lineTo(x, y + r);
      ctx.lineTo(x, y);

      ctx.fill();
      ctx.closePath();

      this.showGoodName(ctx);
      this.showGoodPrice(ctx);
      this.showTips(ctx);
      this.drawQrCode(ctx);
    },
    showGoodPrice(ctx) {
      ctx.fillStyle = "#fc4a3b";
      ctx.font = "26px 'microsoft yahei'";
      let x = 54;
      let y = 797 + 235 + 80;
      ctx.fillText("￥", x, y);
      ctx.fillStyle = "#fc4a3b";
      ctx.font = "40px 'microsoft yahei'";
      ctx.fillText(this.info.min_price, x + 30, y);
    },
    showTips(ctx) {
      ctx.fillStyle = "gray";
      ctx.font = "24px 'microsoft yahei'";
      let x = 54;
      let y = 1194;
      ctx.fillText("长按识别小程序码进入", x, y);
    },
    showGoodName(ctx) {
      ctx.fillStyle = "#000000";
      ctx.font = "30px 'microsoft yahei'";
      let maxWidth = 360;
      let n = this.info.goods_name;
      let lines = 2;

      let x = 54;
      let y = 797 + 185;
      for (let i = 0; i < lines; i++) {
        let lineText = "";
        let currentWidth = 0;
        for (let x = 0; x < n.length; x++) {
          currentWidth += ctx.measureText(n[x]).width;
          if (currentWidth > 360) {
            break;
          } else {
            lineText += n[x];
          }
        }
        ctx.fillText(lineText, x, y + i * 55);
        n = n.substring(lineText.length);
        if (n == "") {
          break;
        }
      }
      if (n != "") {
        ctx.fillText("...", x + maxWidth, y + 55);
      }
    },
    roundRect(ctx, x, y, w, h, r, c = "#fff") {
      if (w < 2 * r) {
        r = w / 2;
      }
      if (h < 2 * r) {
        r = h / 2;
      }

      ctx.beginPath();
      ctx.fillStyle = c;

      ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
      ctx.moveTo(x + r, y);
      ctx.lineTo(x + w - r, y);
      ctx.lineTo(x + w, y + r);

      ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
      ctx.lineTo(x + w, y + h - r);
      ctx.lineTo(x + w - r, y + h);

      ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
      ctx.lineTo(x + r, y + h);
      ctx.lineTo(x, y + h - r);

      ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
      ctx.lineTo(x, y + r);
      ctx.lineTo(x + r, y);

      ctx.fill();
      ctx.closePath();
    },
    canvasIdErrorCallback: function (e) {
      console.error(e.detail.errMsg);
    },
  },
};
</script>

<style>
.draw-style1 {
  width: 100%;
  height: 100%;
  background: #fff;
  position: relative;
  overflow: hidden;
  z-index: 2;
}
.draw-style1 .sty-box {
  width: 750px;
  height: 1344px;
  position: absolute;
  top: -1344px;
  left: -750px;
}
</style>
