<template>       
   <canvas id="myCanvas">您的浏览器不支持canvas.请升级您的浏览器</canvas>
</template>

<script>

import  { Component,Core }  from 'eye-core';

export default Component({

  name: "see",

  props: {
    // canvas 的默认宽高
    cwidth: {
      type: Number,
      default: function() {
        return window.innerWidth;
      }
    },
    cheight: {
      type: Number,
      default: function() {
        return window.innerHeight - 4;
      }
    }
  },

  data() {
    return {
      width: 0,
      height: 0,
      ctx: null,
      scale: 1
    };
  },
  
  watch:{
    cheight(){
      this.height = this.cheight;
    },
    cwidth(){
      this.width = this.cwidth;
    }
  },
  onInit() {
    this.width = this.cwidth;
    this.height = this.cheight;
  },

  methods: {
    // 创建canvas画布，初始化一些信息
    start() {
      this.width = this.cwidth;
      this.height = this.cheight;
      this.ctx = this.getContext();
      let canvas = this.getCanvas();
      // 高清屏处理参照https://blog.csdn.net/anmoran/article/details/54343380
      let devicePixelRatio = window.devicePixelRatio || 1;
      let backingStoreRatio =
        this.ctx.webkitBackingStorePixelRatio ||
        this.ctx.mozBackingStorePixelRatio ||
        this.ctx.msBackingStorePixelRatio ||
        this.ctx.oBackingStorePixelRatio ||
        this.ctx.backingStorePixelRatio || 1;
      this.scale = devicePixelRatio / backingStoreRatio;
        
      canvas.width = this.width * this.scale;
      canvas.height = this.height * this.scale;

      canvas.style.width = this.width + "px";
      canvas.style.height = this.height + "px";
      this.ctx.scale(this.scale, this.scale);
      this._drawQueue = [];

      return this;
    },
    // 拿到对象
    getCanvas() {
      return document.getElementById("myCanvas");
    },
    // 拿到上下文
    getContext() {
      return this.getCanvas().getContext("2d");
    },
    // 设置写字的各种参数
    drawText(options) {
      options = Core._.apply(
        {
          type: "text",
          selfColor: "",
          selfFont: "",
          textAlign: "",
          marginLeft: 0,
          marginRight: 0,
          x: 0,
          y: 0
        },
        options || {}
      );
      // 先不渲染，放入到队列
      this._drawQueue.push(
        new Promise((resolve, reject) => {
          resolve(options);
        })
      );

      // 支持链式表达
      return this;
    },
    // 设置背景图的宽高
    drawBgImg(options) {
      options.w = this.width;
      options.h = this.height;
      this.drawImg(options);

      return this;
    },
    // 设置画本地或者网络图片的参数
    drawImg(options) {
      options = Core._.apply(
        {
          align: "",
          cw: this.width,
          type: "img",
          mode: "rect", // 正方形 rect   圆形circle
          strokeStyle: "#fff",
          strokeWidth: 0,
          x: 0,
          y: 0,
          w: 0,
          h: 0
        },
        options || {}
      );

      // 有图片地址才预加载
      if (options.src) {
        this._drawQueue.push(this.queue(options));
      }

      // 支持链式表达
      return this;
    },
    // 预加载图片
    queue(option) {
      let self = this;
      return new Promise((resolve, reject) => {
        let img = new Image();
        option["img"] = img;
        // 允许canvas跨域下载图片
        img.crossOrigin = "Anonymous";
        img.onload = () => resolve(option);
        // 图片加载失败
        img.onerror = () => {
          option.error = true;
          // 利用一个Promise只返回一次resolve就冻结
          resolve(option);
        };
        img.src = option.src;
      });
    },
    end() {
      // 队列渲染所需的资源。
      Promise.all(this._drawQueue)
        .then(list => {
          list.forEach(data => {
            // 画之前保存
            this.ctx.save();
            // 去画图
            this.doDraw(data);
            //
            this.ctx.restore();
          });
          this.save();
        })
        .catch(e => {
          this.save();
        });
      return this;
    },
    // 只负责写各种文字
    _drawText(options) {
      this.ctx.font = options.font;
      this.ctx.fillStyle = options.fillStyle;
      let lineWidth = this.ctx.measureText(options.text + "").width || 0;
      // 如果设置了字体对齐的方式为center，就默认为水平居中
      if (options.textAlign == "center") {
        if (this.width > lineWidth) {
          // X轴水平居中
          options.x = (this.width - lineWidth) * 0.5;
        }
      } else if (options.textAlign == "left") {
        //左对齐
        options.x = options.marginLeft;
      } else if (options.textAlign == "right") {
        //右对齐
        options.x = this.width - lineWidth - options.marginRight;
      }
      this.ctx.fillText(options.text, options.x, options.y);
    },
    // 只负责画图片
    _drawImage(options) {
      // 图片加载失败，抛弃这次的渲染，接着渲染其他业务
      if (options.error) {
        return this;
      }

      // console.log(`宽${options.img.width} 高${options.img.height} 地址URL${options.src}`)
      if (options.mode == "rect") {
        options.w = options.w ? options.w : options.img.width;
        options.h = options.h ? options.h : options.img.height;
        if (options.align == "center" && options.w <= options.cw) {
          options.x = (options.cw - options.w) * 0.5;
        }
        if (options.strokeWidth) {
          this.ctx.fillStyle = options.strokeStyle;
          this.ctx.lineWidth = options.strokeWidth;
          this.ctx.beginPath();
          this.ctx.fillRect(options.x, options.y, options.w, options.h);
          this.ctx.closePath();
        }

        this.ctx.drawImage(
          options.img,
          options.x + options.strokeWidth,
          options.y + options.strokeWidth,
          options.w - options.strokeWidth * 2,
          options.h - options.strokeWidth * 2
        );
      } else if (options.mode == "circle") {
        let cx = options.cw * 0.5;
        let x = options.align == "center" ? cx : options.x;
        let r = options.w * 0.5;
        this.ctx.beginPath();
        this.ctx.arc(x, options.y, r, 0, 2 * Math.PI);
        this.ctx.closePath();
        // 区域裁剪
        this.ctx.clip();
        // 画完圆开始画图
        this.ctx.drawImage(
          options.img,
          x - options.w * 0.5,
          options.y - options.h * 0.5,
          options.w,
          options.h
        );
      }
    },
    // 操作分发
    doDraw(option) {
      switch (option.type) {
        case "text": {
          this._drawText(option);
          break;
        }
        case "img": {
          this._drawImage(option);
          break;
        }
      }
    },
    save() {
      // 先设置下图片的格式
      let baseType = "image/jpeg";
      let baseData = this.getCanvas().toDataURL(baseType);
      console.log("图片渲染完成");
      this.$emit("loaded", baseData);
    }
  }
});
</script>