ToB企服应用市场:ToB评测及商务社交产业平台

标题: 前端canvas的学习和将网页生成canvas图片 [打印本页]

作者: 张裕    时间: 2024-8-27 22:39
标题: 前端canvas的学习和将网页生成canvas图片
目的


第一个canvas

  1. <body>
  2.   <canvas
  3.     id="c"
  4.     width="300"
  5.     height="200"
  6.     style="border:1px solid #ccc"
  7.   ></canvas>
  8.   <script>
  9.     //获取canvas元素
  10.     const cnv = document.querySelector('#c');
  11.     //获取canvas上下文环境对象
  12.     const cxt = cnv.getContext('2d');
  13.     //绘制图形
  14.     cxt.moveTo(100,100);//起始点坐标(x,y)
  15.     cxt.lineTo(200,100);//重点坐标(x,y)
  16.     cxt.stroke();//将起点和终点链接起来
  17.   </script>
  18. </body>
复制代码

不能通过css设置画布的宽高


  1. <html lang="en">
  2. <head>
  3.   <meta charset="UTF-8">
  4.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5.   <title>Document</title>
  6.   <style>
  7.     #c{
  8.       width: 400px;
  9.       height: 400px;
  10.     }
  11.   </style>
  12. </head>
  13. <body>
  14.   <canvas
  15.     id="c"
  16.     style="border:1px solid #ccc"
  17.   ></canvas>
  18.   <script>
  19.     //获取canvas元素
  20.     const cnv = document.querySelector('#c');
  21.     //获取canvas上下文环境对象
  22.     const cxt = cnv.getContext('2d');
  23.     //绘制图形
  24.     cxt.moveTo(100,100);//起始点坐标(x,y)
  25.     cxt.lineTo(200,100);//重点坐标(x,y)
  26.     cxt.stroke();//将起点和终点链接起来
  27.     console.log(cnv.width);//输出300
  28.     console.log(cnv.height);//输出150
  29.   </script>
  30. </body>
  31. </html>
复制代码
canvas 的默认宽度是300px,默认高度是150px。
坐标系



W3C 坐标系数学直角坐标系 的 X轴 是一样的,只是 Y轴 的反向相反。
W3C 坐标系 的 Y轴 正方向向下
绘制直线


  1. <body>
  2.   <canvas id="c" style="border:1px solid red"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');
  6.     cxt.moveTo(100,100);//起始点坐标(x,y)
  7.     cxt.lineTo(200,100);//下一个点的坐标(x,y)
  8.     cxt.stroke();//链接起来
  9.   </script>
  10. </body>
复制代码



设置样式



  1. <body>
  2.   <canvas id="c" style="border:1px solid red"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');//获取canvas上下文环境对象
  6.     cxt.moveTo(10,10);//起始点坐标(x,y)
  7.     cxt.lineTo(60,60);
  8.     //设置线条的宽度
  9.     cxt.lineWidth = 20;
  10.     //更改线条的颜色
  11.     cxt.strokeStyle = 'green';
  12.     //修改线帽
  13.     cxt.lineCap = 'round';
  14.     cxt.stroke();//链接起来
  15.   </script>
  16. </body>
复制代码

新开路径


  1. <body>
  2.   <canvas id="c" style="border:1px solid red"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');//获取canvas上下文环境对象
  6.     cxt.moveTo(10,10);//起始点坐标(x,y)
  7.     cxt.lineTo(60,60);
  8.     //设置线条的宽度
  9.     cxt.lineWidth = 20;
  10.     cxt.stroke();//链接起来
  11.     //新开一个路径
  12.     cxt.beginPath();
  13.     //设置新线段的样式
  14.     cxt.lineWidth = 1;
  15.     //更改线条的颜色
  16.     cxt.strokeStyle = 'green';
  17.     //修改线帽
  18.     cxt.lineCap = 'round';
  19.     cxt.moveTo(100,100);//起始点坐标(x,y)
  20.     cxt.lineTo(200,100);//下一个点的坐标(x,y)
  21.     cxt.stroke();//链接起来
  22.   </script>
  23. </body>
复制代码


  1. <canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
  2. <script>
  3.   const cnv = document.getElementById('c')
  4.   const cxt = cnv.getContext('2d')
  5.   cxt.moveTo(20, 100)
  6.   cxt.lineTo(200, 100)
  7.   cxt.lineWidth = 10
  8.   cxt.strokeStyle = 'pink'
  9.   cxt.stroke()
  10.   cxt.beginPath() // 重新开启一个路径
  11.   cxt.moveTo(20, 120.5)
  12.   cxt.lineTo(200, 120.5)
  13.   cxt.lineWidth = 4
  14.   cxt.strokeStyle = 'red'
  15.   cxt.stroke()
  16. </script>
复制代码
折线(特别的直线)


矩形(rect)


  1. <body>
  2.   <canvas id="c" style="border:1px solid red;height: 300px;width: 300px;"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');//获取canvas上下文环境对象
  6.     cxt.strokeStyle = "green";//必须要写在绘制前面
  7.     cxt.strokeRect(10, 10, 120, 100);//起始点坐标(10,10) 宽120 高100
  8.   </script>
  9. </body>
复制代码



填充矩形


  1. <body>
  2.   <canvas id="c" style="border:1px solid red;height: 300px;width: 300px;"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');//获取canvas上下文环境对象
  6.     cxt.fillStyle = "blue";//必须要写在绘制前面
  7.     cxt.fillRect(10, 10, 120, 100);//起始点坐标(10,10) 宽120 高100
  8.   </script>
  9. </body>
复制代码


  1. <body>
  2.   <canvas id="c" style="border:1px solid red;height: 300px;width: 300px;"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');//获取canvas上下文环境对象
  6.     cxt.fillStyle = "blue";//必须要写在绘制前面
  7.     cxt.fillRect(10, 10, 120, 100);//起始点坐标(10,10) 宽120 高100
  8.     cxt.strokeStyle = "green";
  9.     cxt.strokeRect(10, 10, 120, 100);//起始点坐标(10,10) 宽120 高100
  10.   </script>
  11. </body>
复制代码

使用rect()


  1. <body>
  2.   <canvas id="c" style="border:1px solid red;height: 300px;width: 300px;"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');
  6.     cxt.strokeStyle  = 'pink'
  7.     cxt.fillStyle = 'blue';
  8.    
  9.     cxt.rect(10, 10, 120, 100);
  10.     cxt.stroke();//进行描边操作
  11.     cxt.fill();//进行填充炒作
  12.   </script>
  13. </body>
复制代码

clearRect()


  1. clearRect(x, y, width, height)
复制代码
  1. <body>
  2.   <canvas id="c" style="border:1px solid red;height: 300px;width: 300px;"></canvas>
  3.   <script>
  4.     const canvas = document.querySelector('#c');
  5.     const cxt = canvas.getContext('2d');
  6.     cxt.strokeStyle  = 'pink'
  7.     cxt.fillStyle = 'blue';
  8.    
  9.     cxt.rect(10, 10, 120, 100);
  10.     cxt.stroke();//进行描边操作
  11.     cxt.fill();//进行填充炒作
  12.    
  13.     //清空矩形
  14.     cxt.clearRect(20, 20, 100, 80);
  15.   </script>
  16. </body>
复制代码


  1. const cnv = document.querySelector('#c');
  2. const cxt = cnv.getContext('2d');
  3. cxt.clearRect(0, 0, cnv.width, cnv.height)
复制代码
多边形


三角形

  1. <body>
  2.   <canvas id="canvas" width="400" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.lineWidth=5;//线条粗细
  7.     ctx.moveTo(10,10);
  8.     ctx.lineTo(100,100);
  9.     ctx.lineTo(300,100);
  10.     ctx.closePath();//闭合路径
  11.     ctx.stroke();//绘制路径
  12.   </script>
  13. </body>
复制代码

arc圆

  1. arc(x, y, r, sAngle, eAngle,counterclockwise)
复制代码

  1. <body>
  2.   <canvas id="canvas" width="400" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.beginPath();
  7.     ctx.arc(100,100,50,0,Math.PI * 2);
  8.     ctx.stroke();
  9.     ctx.closePath();
  10.   </script>
  11. </body>
复制代码



  1. <body>
  2.   <canvas id="canvas" width="400" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.beginPath();
  7.     ctx.arc(100,100,50,0,Math.PI );
  8.     ctx.closePath();
  9.     ctx.stroke();
  10.   </script>
  11. </body>
复制代码

弧线


  1. arcTo(cx, cy, x2, y2, radius)
  2. cx: 两切线交点的横坐标
  3. cy: 两切线交点的纵坐标
  4. x2: 结束点的横坐标
  5. y2: 结束点的纵坐标
  6. radius: 半径
复制代码

  1. <body>
  2.   <canvas id="canvas" width="400" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.beginPath();
  7.     ctx.arc(100, 100, 50, 0, 30 * Math.PI / 180, false);
  8.     ctx.stroke();
  9.   </script>
  10. </body>
复制代码

  1. <canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
  2. <script>
  3.   const cnv = document.getElementById('c')
  4.   const cxt = cnv.getContext('2d')
  5.   cxt.moveTo(40, 40)
  6.   cxt.arcTo(120, 40, 120, 120, 80)
  7.   cxt.stroke()
  8. </script>
复制代码


样式设置

stroke(描边)


lineWidth(设置线条宽度)


strokeStyle(描边颜色)


lineCap(设置线帽)


lineJoin(拐角样式)




setLineDash(设置描边虚线)


  1. <body>
  2.   <canvas id="canvas" width="400" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     //基础样式
  7.     ctx.strokeStyle = 'blue';
  8.     ctx.lineWidth = 10;
  9.     ctx.moveTo(10, 10);
  10.     ctx.lineTo(290, 10);
  11.     //设置空白值为10(也就是间隔10px)
  12.     ctx.setLineDash([10])
  13.     ctx.stroke();
  14.     ctx.beginPath();
  15.     //设置线条长度为10px,空白值为5px
  16.     ctx.setLineDash([10, 5])
  17.     ctx.moveTo(10, 40);
  18.     ctx.lineTo(290, 40);
  19.     ctx.stroke();
  20.     ctx.beginPath();
  21.     //设置线条长度为10px,空白值为5px,线条长度为20px,空白值为30px,线条长度为40px,空白值为50px
  22.     ctx.setLineDash([10, 5, 20, 30, 40, 50]);
  23.     ctx.moveTo(10, 70);
  24.     ctx.lineTo(290, 70);
  25.     ctx.stroke();
  26.   </script>
  27. </body>
复制代码

fill(填充)


  1. <canvas id="c" width="300" height="300" style="border: 1px solid #ccc;"></canvas>
  2. <script>
  3.   const cnv = document.getElementById('c')
  4.   const cxt = cnv.getContext('2d')
  5.   cxt.fillStyle = 'pink'
  6.   cxt.rect(50, 50, 200, 100)
  7.   cxt.fill()
  8. </script>
复制代码

非零环绕填充


  1. <body>
  2.   <canvas id="canvas" width="300" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.moveTo(100, 100)
  7.     ctx.lineTo(300, 100)
  8.     ctx.lineTo(300, 300)
  9.     ctx.lineTo(100, 300)
  10.     ctx.closePath()
  11.     //内部的
  12.     ctx.moveTo(150, 150)
  13.     ctx.lineTo(150, 250)
  14.     ctx.lineTo(250, 250)
  15.     ctx.lineTo(250, 150)
  16.     ctx.closePath()
  17.     ctx.fill();
  18.   </script>
  19. </body>
复制代码






文本

strokeText()描边文本和设置文本样式


  1. cxt.font = 'font-style font-variant font-weight font-size/line-height font-family'
复制代码
  1. 如果需要设置字号 font-size,需要同时设置 font-family。
  2. cxt.font = '30px 宋体'
复制代码
  1. <body>
  2.   <canvas id="canvas" width="300" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.font = '60px 宋体';
  7.     ctx.strokeText("你好,世界", 10, 100);
  8.   </script>
  9. </body>
复制代码


  1. <body>
  2.   <canvas id="canvas" width="300" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.font = '60px 宋体';
  7.     ctx.strokeStyle = 'blue';
  8.     ctx.strokeText("你好,世界", 10, 100);
  9.   </script>
  10. </body>
复制代码

fillText-填充文本和fillStyle-填充颜色

  1. <body>
  2.   <canvas id="canvas" width="300" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.font = '60px 宋体';
  7.     ctx.strokeStyle = 'blue';
  8.     // ctx.strokeText("你好,世界", 10, 100);
  9.     ctx.fillStyle = 'red';
  10.     ctx.fillText('你好,世界', 10, 100);
  11.   </script>
  12. </body>
复制代码

measureText() - 获取文本信息

  1. <body>
  2.   <canvas id="canvas" width="300" height="300" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     ctx.font = '60px 宋体';
  7.     ctx.strokeStyle = 'blue';
  8.     // ctx.strokeText("你好,世界", 10, 100);
  9.     ctx.fillStyle = 'red';
  10.     let text = '你好,世界';
  11.     ctx.fillText(text, 10, 100);
  12.     console.log(ctx.measureText(text));
  13.   </script>
  14. </body>
复制代码
  1. {
  2.     "actualBoundingBoxAscent": 49,
  3.     "actualBoundingBoxDescent": 7,
  4.     "actualBoundingBoxLeft": -2,
  5.     "actualBoundingBoxRight": 268,
  6.     "alphabeticBaseline": 0,
  7.     "fontBoundingBoxAscent": 52,
  8.     "fontBoundingBoxDescent": 8,
  9.     "hangingBaseline": 41.6,
  10.     "ideographicBaseline": -8,
  11.     "width": 270
  12. }
复制代码
textAlign 程度对齐方式

使用 textAlign 属性可以设置文字的程度对齐方式,一共有5个值可选



textBaseline 垂直对齐方式





drawImage-渲染图片


  1. drawImage(image,dx,dy,dw,dh);
复制代码

js方式


  1. <body>
  2.   <canvas id="canvas" width="800" height="500" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     const image = new Image();
  7.     image.src = 'https://s2.loli.net/2024/03/08/FmvSfs5TeZh4Bcq.png';
  8.     image.onload = () => {
  9.       //等待图片加载完成
  10.       ctx.drawImage(image,30,30)
  11.     }
  12.   </script>
  13. </body>
复制代码

DOM方式

  1. <body>
  2.   <img src="https://s2.loli.net/2024/03/08/FmvSfs5TeZh4Bcq.png" id="cimg"/>
  3.   <canvas id="canvas" width="800" height="500" style="border: 1px solid red;"></canvas>
  4.   <script>
  5.     const canvas = document.getElementById('canvas');
  6.     const ctx = canvas.getContext('2d');
  7.     const cimgDOM = document.getElementById('cimg');
  8.     ctx.drawImage(cimgDOM,30,30)
  9.   </script>
  10. </body>
复制代码

设置图片宽高

  1. drawImage(image, dx, dy, dw, dh)
复制代码
image、 dx、 dy 的用法和前面一样。
dw 用来界说图片的宽度,dh 界说图片的高度。
截取图片


  1. drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
复制代码

  1. <body>
  2.   <canvas id="canvas" width="400" height="400" style="border: 1px solid red;"></canvas>
  3.   <script>
  4.     const canvas = document.getElementById('canvas');
  5.     const ctx = canvas.getContext('2d');
  6.     const image = new Image();
  7.     image.src = 'https://s2.loli.net/2024/03/08/FmvSfs5TeZh4Bcq.png';
  8.     image.onload = () => {
  9.       //从图像的 (10,10) 位置开始剪切,剪切的大小为 120x300,然后在画布的 (20,30) 位置放置图像,缩放图像的大小为 100x200。
  10.       ctx.drawImage(image, 10,10,120,300,20,30,100,200)
  11.     }
  12.   </script>
  13. </body>
复制代码

  1. const canvas = document.getElementById("canvas");
  2. const ctx = canvas.getContext("2d");
  3. const image = document.getElementById("source");
  4. image.addEventListener("load", (e) => {
  5.   ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
  6. });
复制代码

使用html2canvas


图片为空缺


终极解决-后端设置答应跨域


  1. <body>
  2.   <div id="main" style="width: 500px;height: 500px;display: flex;border: 1px solid red;">
  3.     <img style="width: 90%;height: 90%;" src="https://oss.dreamlove.top/i/2024/03/09/hg7kn6.jpg"  />
  4.     <div style="font-size: 20px;">大家好,我是文字</div>
  5.   </div>
  6.   <button id="clickme">点击我</button>
  7.   <script type="module">
  8.     import html2canvas from 'https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.esm.min.js';
  9.     document.getElementById('clickme').addEventListener('click', () => {
  10.       html2canvas(document.querySelector('#main'),{
  11.         useCORS: true // 【重要】开启跨域配置
  12.       }).then(function (canvas) {
  13.         document.body.append(canvas)
  14.       });
  15.     })
  16.   </script>
  17. </body>
复制代码
练习


  1. <body>
  2.   <div id="wrapper"
  3.     style="position: relative;width: 600px;height: 500px;background-color: red;background-image: url('./image/bg.jpg');">
  4.     <span id="time"
  5.       style="color: blue;position: absolute;bottom: 0;font-size: 30px;left: 50%;transform: translateX(-50%);"></span>
  6.   </div>
  7.   <button id="btnDown">下载</button>
  8.   <script type="module">
  9.     import html2canvas from "https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.esm.min.js";
  10.     function dataURLtoBlob(dataurl) {
  11.       let arr = dataurl.split(','),
  12.         mime = arr[0].match(/:(.*?);/)[1],
  13.         bstr = atob(arr[1]),
  14.         n = bstr.length,
  15.         u8arr = new Uint8Array(n)
  16.       while (n--) {
  17.         u8arr[n] = bstr.charCodeAt(n)
  18.       }
  19.       return new Blob([u8arr], { type: mime })
  20.     }
  21.     function downFile (url) {
  22.       const a = document.createElement('a');
  23.       a.style.display = 'none';
  24.       a.download = 'xx';
  25.       a.href = url;
  26.       document.body.appendChild(a);
  27.       a.click();
  28.       document.body.removeChild(a);
  29.       /*
  30.       * download: HTML5新增的属性
  31.       * url: 属性的地址必须是非跨域的地址
  32.        */
  33.     };
  34.     window.onload = () => {
  35.       const timeDOM = document.querySelector('#time');
  36.       timeDOM.textContent = new Date().toLocaleString();
  37.     }
  38.     document.querySelector('#btnDown').addEventListener('click', () => {
  39.       const shareContent = document.getElementById('wrapper');//需要截图的包裹的(原生的)DOM 对象
  40.       const width = shareContent.offsetWidth; //获取dom 宽度
  41.       const height = shareContent.offsetHeight; //获取dom 高度
  42.       const canvas = document.createElement("canvas"); //创建一个canvas节点
  43.       const scale = 1; //定义任意放大倍数 支持小数
  44.       canvas.width = width * scale; //定义canvas 宽度 * 缩放
  45.       canvas.height = height * scale; //定义canvas高度 *缩放
  46.       canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
  47.       // var rect = shareContent.getBoundingClientRect();//获取元素相对于视察的偏移量
  48.       // canvas.getContext("2d").translate(-rect.left,-rect.top);//设置context位置,值为相对于视窗的偏移量负值,让图片复位
  49.       const opts = {
  50.         scale: scale, // 添加的scale 参数
  51.         canvas: canvas, //自定义 canvas
  52.         logging: true, //日志开关
  53.         width: width, //dom 原始宽度
  54.         height: height, //dom 原始高度
  55.         backgroundColor: 'transparent',
  56.       };
  57.       html2canvas(shareContent, opts).then((canvas) => {
  58.         const base64 = canvas.toDataURL();
  59.         const blob = dataURLtoBlob(base64)
  60.         const href = window.URL.createObjectURL(blob)
  61.         downFile(href,'test.png')
  62.       })
  63.     })
  64.   </script>
  65. </body>
复制代码

动态生成分享图片



微信小程序生成-使用snapshot绘制




  1. <navigation-bar title="Weixin" back="{{false}}" color="black" background="#FFF"></navigation-bar>
  2. <van-popup show="{{ show }}" bind:close="onClose">
  3.   <snapshot class="share" id="downloadWrapper">
  4.     <!-- 用户基本信息 -->
  5.     <view class="share_info">
  6.       <image class="avatar" src="{{info.avatar}}" mode="aspectFill"></image>
  7.       <view class="desc">
  8.         <view class="name">{{info.name}}</view>
  9.         <view class="text">{{info.description}}</view>
  10.       </view>
  11.     </view>
  12.     <!-- 分享背景 -->
  13.     <view class="share_bg">
  14.       <image class="pic" src="{{info.bgURL}}" mode="aspectFill"></image>
  15.     </view>
  16.     <!-- 二维码和价格 -->
  17.     <view class="share_code">
  18.       <view class="price">{{'$' + info.price}}</view>
  19.       <view class="code">
  20.         <image class="pic" src="{{info.codeURL}}" mode="aspectFill"></image>
  21.       </view>
  22.     </view>
  23.   </snapshot>
  24.   <view style="text-align:center;">
  25.     <van-button type="primary" bind:tap="handleDownload">点击下载</van-button>
  26.   </view>
  27. </van-popup>
  28. <van-button type="primary" bind:click="showPopup">点击我生成海报</van-button>
复制代码

  1. const app = getApp()
  2. Page({
  3.   data: {
  4.     show:false,
  5.     info:{
  6.       name: "梦洁",//用户名称
  7.       description: "给你推荐了一个好东西",//描述
  8.       avatar: "https://s2.loli.net/2024/03/09/8tey3JKxCIpg4c7.png",//头像
  9.       codeURL: "https://s2.loli.net/2024/03/09/924jbZViXRUngOh.png",//二维码
  10.       bgURL: "https://s2.loli.net/2024/03/09/QhupvOzgwGmcY58.jpg",//背景图
  11.       price: "29.99"
  12.     }
  13.   },
  14.   onLoad() {
  15.     console.log('代码片段是一种迷你、可分享的小程序或小游戏项目,可用于分享小程序和小游戏的开发经验、展示组件和 API 的使用、复现开发问题和 Bug 等。可点击以下链接查看代码片段的详细文档:')
  16.     console.log('https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html')
  17.   },
  18.   showPopup() {
  19.     this.setData({ show: true });
  20.   },
  21.   onClose() {
  22.     this.setData({ show: false });
  23.   },
  24.   //点击下载
  25.   handleDownload(){
  26.     this.createSelectorQuery().select('#downloadWrapper').node().exec(res => {
  27.       const node = res[0].node;
  28.       //保存海报
  29.       node.takeSnapshot({
  30.         type:'arraybuffer',
  31.         format:"png",
  32.         success:(res) => {
  33.           //不让背景透明,就简单点改了下扩展名
  34.           const filePath = `${wx.env.USER_DATA_PATH}/生成的图片${Math.random()}.jpg`
  35.           const fs = wx.getFileSystemManager();
  36.           //将海报数据写入本地文件
  37.           fs.writeFileSync(filePath,res.data,'binary')
  38.          
  39.           //保存到本地
  40.           wx.saveImageToPhotosAlbum({
  41.             filePath,
  42.           })
  43.         },
  44.         error:(e) => {
  45.           console.log(`出错了${e}`);
  46.         }
  47.       })
  48.     })
  49.   }
  50. })
复制代码

  1. /* page {
  2.   display: flex;
  3.   flex-direction: column;
  4.   height: 100vh;
  5. } */
  6. .scroll-area {
  7.   flex: 1;
  8.   overflow-y: hidden;
  9. }
  10. .intro {
  11.   padding: 30rpx;
  12.   text-align: center;
  13. }
  14. .share {
  15.   border: 1rpx solid red;
  16.   width: 100vw;
  17.   height: 60vh;
  18.   display: flex;
  19.   flex-direction: column;
  20. }
  21. .share_info {
  22.   display: flex;
  23.   align-items: center;
  24. }
  25. .avatar {
  26.   width: 80rpx;
  27.   height: 80rpx;
  28.   border-radius: 50%;
  29. }
  30. .desc {
  31.   font-size: 32rpx;
  32.   margin-left: 40rpx;
  33.   flex: 1;
  34. }
  35. .name {
  36.   font-weight: bold;
  37. }
  38. .text {
  39.   color: gray;
  40. }
  41. .share_bg {
  42.   flex: 1;
  43. }
  44. .share_code {
  45.   display: flex;
  46.   align-items: center;
  47.   justify-content: space-between;
  48. }
  49. .code {
  50.   text-align: right;
  51. }
  52. .code .pic {
  53.   width: 160rpx;
  54.   height: 160rpx;
  55. }
复制代码
使用html2canvas举行转图片


  1. import React, {  useState } from "react";
  2. import { Button } from "@mui/material";
  3. import Share from "./component/share";
  4. const Index = () => {
  5.   const [open,setOpen] = useState(false);
  6.   return (
  7.     <div>
  8.       <Button onClick={() => setOpen(true)}>点击我分享</Button>
  9.       {/*  分享组件 */}
  10.       { open && <Share close={() => setOpen(false)}/> }
  11.     </div>
  12.   );
  13. };
  14. export default Index;
复制代码

  1. import React, { useRef, useState } from "react";
  2. import { Button, Modal } from 'antd';
  3. import html2canvas from 'html2canvas';
  4. import "./share.less";
  5. const Share = ({ close }) => {
  6.   const [info, setInfo] = useState({
  7.     name: "梦洁",//用户名称
  8.     description: "给你推荐了一个好东西",//描述
  9.     avatar: "https://s2.loli.net/2024/03/09/8tey3JKxCIpg4c7.png",//头像
  10.     codeURL: "https://s2.loli.net/2024/03/09/924jbZViXRUngOh.png",//二维码
  11.     bgURL: "https://s2.loli.net/2024/03/09/QhupvOzgwGmcY58.jpg",//背景图
  12.     price: "29.99"
  13.   });
  14.   const wrapperRef = useRef();
  15.   //点击下载
  16.   const handleDownload = () => {
  17.     html2canvas(wrapperRef.current,{
  18.       useCORS:true,//确保可以下载网络图片
  19.     }).then((canvas) => {
  20.       canvas.toBlob((data) => {
  21.         const url = URL.createObjectURL(data);
  22.         const ADOM = document.createElement("a");
  23.         ADOM.href = url;
  24.         ADOM.style.display = "none";
  25.         ADOM.download = "";//避免在当前窗口打开
  26.         document.body.appendChild(ADOM);
  27.         ADOM.click();
  28.         document.body.removeChild(ADOM);
  29.       });
  30.     })
  31.   }
  32.   return (
  33.     <Modal width={"375px"} open={true} footer={null} onCancel={close}>
  34.       <div ref={wrapperRef} className="share">
  35.         {/* 用户基本信息 */}
  36.         <div className="share_info">
  37.           <img className="avatar" src={info.avatar} alt="" />
  38.           <div className="desc">
  39.             <div className="name">{info.name}</div>
  40.             <div className="text">{info.description}</div>
  41.           </div>
  42.         </div>
  43.         {/* 分享背景 */}
  44.         <div className="share_bg">
  45.           <img alt="" src={info.bgURL} />
  46.         </div>
  47.         {/* 二维码和价格 */}
  48.         <div className="share_code">
  49.           <div className="price">{ "$" + info.price }</div>
  50.           <div className='code'>
  51.             <img alt='' src={info.codeURL}/>
  52.           </div>
  53.         </div>
  54.       </div>
  55.       <div style={{textAlign:'center'}}>
  56.         <Button type={'primary'} onClick={handleDownload}>点击下载</Button>
  57.       </div>
  58.     </Modal>
  59.   );
  60. };
  61. export default Share;
复制代码


基础知识点



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4