美文网首页前端小库
canvas生成海报

canvas生成海报

作者: 芸芸众生ing | 来源:发表于2021-09-24 11:53 被阅读0次

    喜欢还请收藏点个小心心

    WEB版的

      <canvas type="2d" id="canvas"></canvas>
    
           // 绘画数据
        const params = [
          // 文字
          { type: "text", text: "这里是文字", left: 100, top: 20, width: 100, textAlign: 'center' },
          // 图片
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", left: 0, top: 40, width: 500, height: 280, },
          // 圆形图片 radius 为 true 
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", radius: true, left: 0, top: 340, width: 150, height: 150, },
          // 圆角图片 radius 为数字
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", radius: 10, left: 270, top: 340, width: 150, height: 150, },
        ]
        // 画布参数
        const option = { dom: "#canvas", params, width: 500, height: 500, dpr: 1 };
    
        // 解析参数 
        async function parseParams(ctx, params) {
          let data = [];
          for (let item of params) {
            let { type, url } = item;
            let obj = { ...item };
            if (type == 'img') {
              // 图片是url地址,需要先下载图片
              obj.img = await downloadImage(obj);
              drawImage(ctx, obj);
            }
            if (type === 'text') drawText(ctx, obj)
          }
          return data;
        }
    
        // 下载图片
        async function downloadImage(item) {
          return new Promise((resolve, reject) => {
            if (!item.url) return;
            // 把图片数据resolve回去,这里是需要做同步处理的。  
            const img = new Image();
            img.onload = () => resolve(img)
            img.src = item.url;
          })
        }
    
        // 绘制文本数据
        function drawText(ctx, item) {
          ctx.save();
          let { text, width, height, left, top, color = "#444", textAlign, font = '20px' } = item;
          // 设置文本颜色
          ctx.fillstyle = color;
          // 设置文本大小
          ctx.font = font;
          // 设置水平对齐方式
          ctx.textAlign = textAlign || "center";
          // 设置垂直对齐方式
          ctx.textBaseline = "middle";
          ctx.fillText(text, left, top);
    
        }
    
        // 绘制图片
        function drawImage(ctx, item) {
          ctx.save()
          let { img, width, height, left, top, radius } = item;
          if (radius === true) {
            ctx.beginPath()
            ctx.arc(width / 2 + left, height / 2 + top, width / 2, 0, Math.PI * 2, false);
            ctx.clip();
          } else if (typeof radius === 'number') {
            // 处理圆角
            let a = { x: left + radius, y: top };
            let b = { x: left + width, y: top };
            let c = { x: left + width, y: top + height };
            let d = { x: left, y: top + height };
            let e = { x: left, y: top };
            ctx.beginPath();
            ctx.moveTo(a.x, a.y);
            ctx.arcTo(b.x, b.y, c.x, c.y, radius);
            ctx.arcTo(c.x, c.y, d.x, d.y, radius);
            ctx.arcTo(d.x, d.y, e.x, e.y, radius);
            ctx.arcTo(e.x, e.y, a.x, a.y, radius);
            ctx.clip();
          }
          ctx.drawImage(img, left, top, width, height);
          ctx.restore()
        }
        // 初始化
        async function onInitCanvas(obj) {
          let ctx = null;
          let { dom, params, width = 500, height = 200, dpr = 1 } = obj;
          if (!ctx) {
            let canvas = document.querySelector('#canvas');
            canvas.width = width * dpr;
            canvas.height = height * dpr;
            canvas.style.width = width + 'px';
            canvas.style.height = height + 'px';
            ctx = canvas.getContext("2d");
          }
          // 解析数据
          if (Array.isArray(params) && params.length) await parseParams(ctx, params);
        }
        onInitCanvas(option)
    

    支付宝小程序canvas生成海报

      <canvas type="2d" id="canvas" style="{{style}}" width="{{width}}" height="{{height}}"></canvas>
    
    Component({
      mixins: [],
      data: {
        style: {},
        width: '',
        height: '',
        dpr: 1,
        option: { dom: '#canvas', width: 750, height: 800, },
        params: [
          // 文字
          { type: "text", text: "这里是文字", left: 100, top: 20, width: 100, textAlign: 'center', color: '#ffffff' },
          // 图片
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", left: 0, top: 40, width: 375, height: 280, },
          // 圆形图片 radius 为 true 
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", radius: true, left: 0, top: 340, width: 50, height: 50, },
          // 圆角图片 radius 为数字
          { type: "img", url: "https://img.alicdn.com/tfs/TB1GvVMj2BNTKJjy0FdXXcPpVXa-520-280.jpg", radius: 10, left: 150, top: 340, width: 150, height: 150, },
        ]
      },
      props: {},
      didMount() {
        let dpr = my.getSystemInfoSync().pixelRatio;
        let { width = 500, height = 200, } = this.data.option;
        this.setData({
          width: width + 'px',
          height: height + 'px',
          dpr,
          style: {
            width: width + 'px', height: height + 'px'
          }
        });
        this.onInitCanvas()
      },
      didUpdate() { },
      didUnmount() { },
      methods: {
        // 解析参数 
        async parseParams(ctx, params, canvas) {
          let data = [];
          for (let item of params) {
            let { type, url } = item;
            let obj = { ...item };
            if (type == 'img') {
              // 图片是url地址,需要先下载图片
              obj.img = await this.downloadImage(obj, canvas);
    
            }
            data.push(obj)
          }
          let timer = setTimeout(() => {
            clearTimeout(timer)
            this.asyncDraw(ctx, data);
          }, 500)
    
        },
        async asyncDraw(ctx, params) {
          params.forEach(e => {
            if (e.type === 'text') this.drawText(ctx, e);
            if (e.type === 'img') this.drawImage(ctx, e);
          })
        },
        // 下载图片
        async downloadImage(item, canvas) {
          return new Promise((resolve, reject) => {
            if (!item.url) return;
            // 把图片数据resolve回去,这里是需要做同步处理的。 
            const img = canvas.createImage();
            img.onload = () => resolve(img)
            img.src = item.url;
          })
        },
        // 绘制文本数据
        drawText(ctx, item) {
          ctx.save();
          let { text, width, height, left, top, color = "#444", textAlign, font = '22px' } = item;
          console.log(font);
    
          // 设置文本颜色
          ctx.fillStyle = color
          // 设置文本大小
          ctx.font = font + ' Arial';
          // 设置水平对齐方式
          ctx.textAlign = textAlign || "center";
          // 设置垂直对齐方式
          ctx.textBaseline = "middle";
          ctx.fillText(text, left, top);
    
        },
        // 绘制图片
        drawImage(ctx, item) {
          ctx.save();
          let { dpr } = this.data;
          let { img, width, height, left, top, radius } = item;
          if (radius === true) {
            ctx.beginPath()
            ctx.arc(width / 2 + left, height / 2 + top, width / 2, 0, Math.PI * 2, false);
            ctx.clip();
          } else if (typeof radius === 'number') {
            // 处理圆角
            let a = { x: left + radius, y: top };
            let b = { x: left + width, y: top };
            let c = { x: left + width, y: top + height };
            let d = { x: left, y: top + height };
            let e = { x: left, y: top };
            ctx.beginPath();
            ctx.moveTo(a.x, a.y);
            ctx.arcTo(b.x, b.y, c.x, c.y, radius);
            ctx.arcTo(c.x, c.y, d.x, d.y, radius);
            ctx.arcTo(d.x, d.y, e.x, e.y, radius);
            ctx.arcTo(e.x, e.y, a.x, a.y, radius);
            ctx.clip();
          }
          ctx.drawImage(img, left, top, width, height);
          ctx.restore()
        },
        // 初始化
        async onInitCanvas() {
          let { option, params } = this.data;
          let { dom = "#canvas" } = option;
          const query = my.createSelectorQuery();
          query.select(dom).node().exec(res => {
            const canvas = res[0].node;
            let ctx = canvas.getContext("2d");
            this.parseParams(ctx, params, canvas);
          })
        }
      },
    });
    

    相关文章

      网友评论

        本文标题:canvas生成海报

        本文链接:https://www.haomeiwen.com/subject/sfczgltx.html