数据可视化-canvas

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <canvas id="canvas" width="800" height="800"></canvas>
    <script>
      const canvas = document.getElementById('canvas'); // 获取 DOM 对象
      const ctx = canvas.getContext('2d'); // 获取 Canvas 对象
      ctx.fillStyle = 'red'; // 填充为红色
      ctx.fillRect(0, 0, 50, 50); // 绘制矩形

      ctx.beginPath(); // 开始绘制路径
      ctx.lineWidth = 1; // 线条宽度
      ctx.strokeStyle = 'blue'; // 线条填充色
      ctx.moveTo(100, 100); // 起点坐标
      ctx.lineTo(250, 75); // 中间点坐标
      ctx.lineTo(300, 100); // 终点坐标
      ctx.stroke(); // 绘制线段

      ctx.beginPath();
      ctx.lineWidth = 2;
      ctx.strokeStyle = 'green'; // 圆形边框色
      ctx.fillStyle = 'red'; // 圆形填充色
      ctx.arc(200, 200, 50, 0, 2 * Math.PI); // 绘制圆形
      ctx.stroke(); // 绘制圆形的边框
      ctx.fill(); // 绘制圆形的填充色

      ctx.beginPath();
      ctx.lineWidth = 1;
      ctx.strokeStyle = 'red';
      ctx.moveTo(300, 300);
      ctx.lineTo(301, 301); // 绘制一个点
      ctx.stroke();
    </script>
  </body>
</html>

思考:你能否总结出 canvas 绘图的流程?

  1. 编写 canvas 标签(注意指定宽高)
  2. 获取 canvas DOM 对象
  3. 获取 Canvas 对象
  4. 设置绘图属性
  5. 调用绘图 API

利用canvas实现图片压缩

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <input type="file" id="upload">
    <script>
      const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']; // 限定图片文件类型
      const MAXSIZE = 1024 * 1024 * 3; // 限定图片最大容量
      const MAXSIZE_STR = '3MB';
      function convertImageToBase64(file, cb) {
      
      
        let reader = new FileReader();
        reader.addEventListener('load', function(e) {
      
      
          const base64Image = e.target.result; // 获取文件内容,等同于 reader.result
          cb(base64Image);
          reader = null;// 让内存去回收reader对象
        });
        reader.readAsDataURL(file); // 读取 file 对象中的内容
      }
      function compress(base64Image, cb) {
      
      
        let maxW = 1024;
        let maxH = 1024;

        const image = new Image();// 建一个图片标签,目的 是获得图片的宽和高
        // 得知宽和高后就可以对图片的宽和高进行压缩,然后调用canvas去绘制这个图像
        //要保证经过压缩后的图片保持和压缩前一致的宽高比。
        image.addEventListener('load', function() {
      
      
          let ratio; // 压缩比
          let needCompress = false; // 是否需要压缩
          if (maxW < image.naturalWidth) {
      
      
            needCompress = true;
            ratio = image.naturalWidth / maxW;
            maxH = image.naturalHeight / ratio;
          }
          if (maxH < image.naturalHeight) {
      
      
            needCompress = true;
            ratio = image.naturalHeight / maxH;
            maxW = image.naturalWidth / ratio;
          }
          if (!needCompress) {
      
      
            maxW = image.naturalWidth;
            maxH = image.naturalHeight;
          }
          const canvas = document.createElement('canvas');
          canvas.setAttribute('id', '__compress__');
          canvas.width = maxW;
          canvas.height = maxH;
          canvas.style.visibility = 'hidden';// 让压缩的过程不被感知
          document.body.append(canvas);

          const ctx = canvas.getContext('2d');
          ctx.clearRect(0, 0, maxW, maxH);
          ctx.drawImage(image, 0, 0, maxW, maxH); // 渲染图片
          const compressImage = canvas.toDataURL('image/jpeg', 0.9); // 
          // 压缩图片  (在这一步获得了压缩的图片)可以比对前后文件流的大小,这个是文件流大小的压缩比,但是图片会失真。发现图片的容量小了很多很多
          cb(compressImage);
          const _image = new Image();
          _image.src = compressImage;
          document.body.appendChild(_image);
          canvas.remove(); // 移除 canvas
          console.log('压缩比-',image.src.length/_image.src.length)
        });
        image.src = base64Image; // 将图片设置到 image 的 src 属性中
        document.body.appendChild(image);
      }
      function uploadImage(compressImage) {
      
      
        console.log('upload image to server...', compressImage);
      }

      const upload = document.getElementById('upload');
      upload.addEventListener('change', function(e) {
      
      
        const file = e.target.files[0];
        console.log(file);
        if (!file) {
      
      
          return;
        }
        const {
      
       type: fileType, size: fileSize } = file;
        // 图片类型检查
        if (!ACCEPT.includes(fileType)) {
      
      
          alert('不支持上传该格式文件!');
          upload.value = '';
          return;
        }
        // 图片大小检查
        if (fileSize > MAXSIZE) {
      
      
          alert('文件超出' + MAXSIZE_STR + '!');
          upload.value = '';// 整个上传会被重置为空
          return;
        }
        // 压缩文件
        convertImageToBase64(file, (base64Image) => compress(base64Image, uploadImage));
      });
    </script>
  </body>
</html>

猜你喜欢

转载自blog.csdn.net/m0_57307213/article/details/130114405