template部分

  1. <template>
  2. <div class="container">
  3. <canvas id="canvas" class="canvas" :style="canvasStyle" :width="80*unit" :height="80*unit" hidden></canvas>
  4. <div id="qrcode" hidden></div>
  5. <div id="img_box"></div>
  6. </div>
  7. </template>

说明:创建一个canvas后,为什么style、width、height需要设置为绑定状态?因为画布的width和height是int类型,默认单位为px,在本项目中使用vw单位来实现UI和适配各种机型,所以需要做一个px到vw的转化,在这里设置的width是80vw,height是80vw,unit是绑定变量,后面会提到。style设置为绑定状态,是因为canvas在flex中宽度默认是100%,并且不受width属性影响,所以需要在这里指定style中的width和height,和属性width、height值同步
canvas和div#qrcode中都有hidden属性,都是用于生产海报图片的,海报图片显示在div#img_box中, 所以他们都是隐藏的

script部分

  1. let ctx;
  2. export default {
  3. name: "Index",
  4. data() {
  5. return {
  6. unit: document.body.clientWidth/100, // 将px转撑px unit = vw
  7. canvasStyle: "width:" + document.body.clientWidth*.8 + "px;" + "height:" + document.body.clientWidth*.8 + "px;", // 构建canvas样式
  8. };
  9. },
  10. mounted() {
  11. let canvas = document.querySelector('#canvas'); // 获取画布实例
  12. ctx = canvas.getContext('2d');
  13. this.createImg();
  14. },
  15. methods: {
  16. createImg() {
  17. this.drawBg();
  18. },
  19. // 绘制背景
  20. drawBg() {
  21. ctx.fillStyle = 'pink';
  22. ctx.fillRect(0, 0, canvas.width, canvas.height);
  23. this.drawAvatar(require('../assets/images/avatar.jpg'), 60, 60, 30); // 头像地址,头像位置x, y, 头像半径
  24. },
  25. // 绘制头像
  26. drawAvatar(url, x, y, r) {
  27. let img = new Image();
  28. img.src = url;
  29. img.onload = () => {
  30. ctx.save();
  31. ctx.arc(x+r, y+r, r, 0, 2 * Math.PI); // 绘制圆角头像
  32. ctx.clip();
  33. ctx.drawImage(img, x, y, r*2, r*2);
  34. ctx.restore();
  35. this.drawQrCode();
  36. }
  37. },
  38. // 绘制二维码
  39. drawQrCode() {
  40. // QRCode 类是引入的库,在vue项目index.html中引入库文件,库文件详情:https://code.ciaoca.com/javascript/qrcode/
  41. // 在选择节点中插入二维码图片
  42. let qrcode = new QRCode(document.querySelector('#qrcode'), {
  43. text: 'https://baidu.com',
  44. width: 256,
  45. height: 256,
  46. colorDark : '#000000',
  47. colorLight : '#ffffff',
  48. correctLevel : QRCode.CorrectLevel.H
  49. });
  50. let qrcodeImg = document.querySelector('#qrcode img'); //获取二维码图片节点
  51. qrcodeImg.onload = () => {
  52. ctx.drawImage(qrcodeImg, 240, 240, 60, 60); // 在画布中绘制二维码,参数:二维码图片,二维码位置,二维码宽高
  53. this.drawFont();
  54. }
  55. },
  56. // 绘制文字
  57. drawFont() {
  58. ctx.fillStyle = "red";
  59. ctx.font = "20px '微软雅黑'";
  60. ctx.textAlign = "left";
  61. ctx.shadowBlur = 10;
  62. ctx.shadowOffsetX = 5;
  63. ctx.shadowOffsetY = 5;
  64. ctx.shadowColor = "black";
  65. ctx.fillText("You jump! I jump!", 100, 180);
  66. let dataImg = new Image();
  67. dataImg.src = canvas.toDataURL('image/png'); // 画布转图片
  68. document.querySelector('#img_box').appendChild(dataImg); // 在选中节点中插入图片
  69. }
  70. }
  71. };

全部代码

  1. <template>
  2. <div class="container">
  3. <canvas id="canvas" class="canvas" :style="canvasStyle" :width="80*unit" :height="80*unit" hidden></canvas>
  4. <div id="qrcode" hidden></div>
  5. <div id="img_box"></div>
  6. </div>
  7. </template>
  8. <script>
  9. let ctx;
  10. export default {
  11. name: "Index",
  12. data() {
  13. return {
  14. unit: document.body.clientWidth/100,
  15. canvasStyle: "width:" + document.body.clientWidth*.8 + "px;" + "height:" + document.body.clientWidth*.8 + "px;",
  16. };
  17. },
  18. mounted() {
  19. let canvas = document.querySelector('#canvas');
  20. ctx = canvas.getContext('2d');
  21. this.createImg();
  22. },
  23. methods: {
  24. createImg() {
  25. this.drawBg();
  26. },
  27. // 绘制背景
  28. drawBg() {
  29. ctx.fillStyle = 'pink';
  30. ctx.fillRect(0, 0, canvas.width, canvas.height);
  31. this.drawAvatar(require('../assets/images/avatar.jpg'), 60, 60, 30);
  32. },
  33. // 绘制头像
  34. drawAvatar(url, x, y, r) {
  35. let img = new Image();
  36. img.src = url;
  37. img.onload = () => {
  38. ctx.save();
  39. ctx.arc(x+r, y+r, r, 0, 2 * Math.PI);
  40. ctx.clip();
  41. ctx.drawImage(img, x, y, r*2, r*2);
  42. ctx.restore();
  43. this.drawQrCode();
  44. }
  45. },
  46. // 绘制二维码
  47. drawQrCode() {
  48. let qrcode = new QRCode(document.querySelector('#qrcode'), {
  49. text: 'https://baidu.com',
  50. width: 256,
  51. height: 256,
  52. colorDark : '#000000',
  53. colorLight : '#ffffff',
  54. correctLevel : QRCode.CorrectLevel.H
  55. });
  56. let qrcodeImg = document.querySelector('#qrcode img');
  57. qrcodeImg.onload = () => {
  58. ctx.drawImage(qrcodeImg, 240, 240, 60, 60);
  59. this.drawFont();
  60. }
  61. },
  62. // 绘制文字
  63. drawFont() {
  64. ctx.fillStyle = "red";
  65. ctx.font = "20px '微软雅黑'";
  66. ctx.textAlign = "left";
  67. ctx.shadowBlur = 10;
  68. ctx.shadowOffsetX = 5;
  69. ctx.shadowOffsetY = 5;
  70. ctx.shadowColor = "black";
  71. ctx.fillText("You jump! I jump!", 100, 180);
  72. let dataImg = new Image();
  73. dataImg.src = canvas.toDataURL('image/png');
  74. document.querySelector('#img_box').appendChild(dataImg);
  75. }
  76. }
  77. };
  78. </script>
  79. <style scoped>
  80. .container {
  81. width: 100%;
  82. height: 100vh;
  83. display: flex;
  84. flex-direction: column;
  85. justify-content: start;
  86. }
  87. .canvas {
  88. margin: 5vw auto;
  89. background-color: pink;
  90. }
  91. #img_box {
  92. margin: 5vw auto;
  93. }
  94. </style>