首页 > 其他分享 >前端实现图片裁剪功能,插件版和原生版

前端实现图片裁剪功能,插件版和原生版

时间:2024-07-15 15:54:22浏览次数:16  
标签:原生 function 插件 const 裁剪 canvas width event

概要

最近遇到了一个需要用到图片裁剪功能,自己找了一些资料,有插件版和原生版的,VUE版本的我就不放了,原理类似,供大家参考。

插件版

Cropper.js 是一个用于裁剪图像的 JavaScript 插件。它可以让用户在浏览器中对图像进行裁剪和编辑操作,具体功能包括但不限于:
1.图像裁剪: 允许用户在预览中选择并裁剪图像的特定区域。
2.缩放和旋转: 支持用户对裁剪区域进行缩放和旋转操作,以便更精确地选择所需部分。
3.上传和导出: 提供了上传和导出裁剪后的图像功能,通常可以导出为Base64格式的图像数据或者Blob对象,以便于上传或保存到服务器。
4.交互式预览: 用户可以在裁剪过程中实时预览裁剪后的效果,可以调整裁剪框的大小和位置。
5.自定义选项: 支持各种自定义选项和配置,例如裁剪框的比例、裁剪框的最小和最大尺寸等,以满足不同场景的需求。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>图片裁剪</title>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css"
    />
    <style>
      #image {
        max-width: 100%;
      }
    </style>
  </head>

  <body>
    <h1>图片裁剪</h1>
    <input type="file" id="fileInput" accept="image/*" />
    <div>
      <img id="image" src="" alt="选择图片" />
    </div>
    <button id="cropButton" style="display: none">裁剪图片</button>
    <div>
      <img id="croppedImage" src="" alt="裁剪后的图片" />
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
    <script>
      document
        .getElementById("fileInput")
        .addEventListener("change", function (event) {
          const file = event.target.files[0];
          if (file) {
            const reader = new FileReader();
            reader.onload = function (e) {
              const img = document.getElementById("image");
              img.src = e.target.result;
              img.onload = function () {
                const cropper = new Cropper(img, {
                  aspectRatio: 1 / 1, // 裁剪框的宽高比
                  viewMode: 1,
                  dragMode: "move",
                  autoCropArea: 0.8,
                  cropBoxMovable: true,
                  cropBoxResizable: true,
                  background: true,
                });

                document.getElementById("cropButton").style.display = "block";
                document.getElementById("cropButton").onclick = function () {
                  const canvas = cropper.getCroppedCanvas();
                  const base64Image = canvas.toDataURL("image/png");
                  // 处理裁剪后的图片,例如显示或上传
                  document.getElementById("croppedImage").src = base64Image;
                  console.log(base64Image);//输出裁剪后的图片base64编码
                };
              };
            };
            reader.readAsDataURL(file);
          }
        });
    </script>
  </body>
</html>

JS原生版

原生版的就比较复杂一点,主要是用到了canvas和鼠标的一些事件

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片裁剪</title>
    <style>
        #canvas {
            border: 1px solid black;
            /* background-color: black; */
        }

        #croppedImage {
            display: none;
        }
    </style>
</head>

<body>
    <input type="file" id="fileInput" accept="image/*">
    <canvas id="canvas" width="500" height="500"></canvas>
    <button id="cropButton">裁剪</button>
    <img id="croppedImage" alt="裁剪后的图片">

    <script>
        const fileInput = document.getElementById('fileInput');
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        const cropButton = document.getElementById('cropButton');
        const croppedImage = document.getElementById('croppedImage');

        let image = new Image();
        let cropStartX = 0;
        let cropStartY = 0;
        let cropEndX = 0;
        let cropEndY = 0;
        let isDrawing = false;

        // 点击上传图片的时候
        fileInput.addEventListener('change', function (event) {
            const file = event.target.files[0];
            const reader = new FileReader();
            const maxWidth = 800; // 设置最大宽度
            const maxHeight = 600; // 设置最大高度
            // 文件读取完成后
            reader.onload = function (e) {
                const img = new Image();
                img.src = e.target.result;

                img.onload = function () {
                    let width = img.width;
                    let height = img.height;

                    // 优化:如果图片尺寸超过最大值,进行缩放(防止图片过大溢出屏幕)
                    if (width > maxWidth || height > maxHeight) {
                        const ratio = Math.min(maxWidth / width, maxHeight / height);
                        width *= ratio;
                        height *= ratio;
                    }

                    canvas.width = width;
                    canvas.height = height;
                    ctx.drawImage(img, 0, 0, width, height);
                };
            };

            reader.readAsDataURL(file);
        });

        // 在图像上鼠标按下的时候
        canvas.addEventListener('mousedown', function (event) {
            cropStartX = event.offsetX;
            cropStartY = event.offsetY;
            isDrawing = true;
        });

        // 在图像上鼠标移动的时候
        canvas.addEventListener('mousemove', function (event) {
            if (isDrawing) {
                console.log('在图像上的时候');
                cropEndX = event.offsetX;
                cropEndY = event.offsetY;
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(image, 0, 0);
                ctx.strokeStyle = 'red';
                ctx.strokeRect(cropStartX, cropStartY, cropEndX - cropStartX, cropEndY - cropStartY);
            }
        });

        // 在图像上松开鼠标的时候
        canvas.addEventListener('mouseup', function (event) {
            isDrawing = false;
        });

        // 点击裁剪的时候
        cropButton.addEventListener('click', function () {
            // 计算裁剪区域的宽度和高度
            const cropWidth = Math.abs(cropEndX - cropStartX);
            const cropHeight = Math.abs(cropEndY - cropStartY);
            // 计算裁剪区域的左上角坐标
            const cropX = Math.min(cropStartX, cropEndX);
            const cropY = Math.min(cropStartY, cropEndY);
            // 创建canvas 元素,并存放裁剪后的图像
            const croppedCanvas = document.createElement('canvas');
            croppedCanvas.width = cropWidth;
            croppedCanvas.height = cropHeight;
            const croppedCtx = croppedCanvas.getContext('2d');
            croppedCtx.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);

            console.log(croppedCanvas.toDataURL());
            croppedImage.src = croppedCanvas.toDataURL();
            croppedImage.style.display = 'block';
        });
    </script>
</body>

</html>

小结

工作好累,想摸鱼。

标签:原生,function,插件,const,裁剪,canvas,width,event
From: https://blog.csdn.net/qq_53080558/article/details/140440211

相关文章

  • 细粒度掌控:精通Gradle中Java插件的配置艺术
    细粒度掌控:精通Gradle中Java插件的配置艺术引言Gradle是一个灵活且功能丰富的构建工具,它通过插件扩展其功能。Java插件是Gradle中最常用的插件之一,为Java项目提供了丰富的构建生命周期任务和约定。合理配置Java插件,可以极大提升Java项目的构建效率和质量。Java插件简介G......
  • 插件魔法:深度解析Gradle插件系统的运作机制
    插件魔法:深度解析Gradle插件系统的运作机制在自动化构建的奇幻世界中,Gradle以其插件系统的强大灵活性和扩展性而著称。插件是Gradle自动化构建的基石,它们为构建过程提供了额外的能力,使得构建脚本更加简洁、功能更加丰富。本文将深入探讨Gradle插件系统的工作原理,揭示其背后......
  • 掌握构建魔法:Gradle中Groovy插件的配置秘籍
    掌握构建魔法:Gradle中Groovy插件的配置秘籍引言Gradle是一个灵活且功能强大的构建工具,它使用Groovy和Kotlin作为其构建脚本的编写语言。Groovy插件为Gradle带来了额外的便利性,使得构建脚本更加简洁和富有表现力。本文将详细介绍如何在Gradle中配置Groovy插件,并提供实际的......
  • Smart-doc:零注解侵入的API接口文档生成插件
    零注解侵入的API接口文档生成插件——Smart-docsmart-doc是一款同时支持JAVARESTAPI和ApacheDubboRPC接口文档生成的工具,在业内率先提出基于JAVA泛型定义推导的理念,完全基于接口源码来分析生成接口文档,不采用任何注解侵入到业务代码中。你只需要按照java-doc标准编写......
  • SQLAlchemy 执行原生 SQL 语句
    在使用SQLAlchemy进行数据库操作时,虽然ORM提供了强大的模型映射功能,但有时候直接使用原生SQL语句可能更加简单直率,甚至性能更优。下面我们来看一下如何在SQLAlchemy中执行原生的SQL语句。执行原生SQL语句的步骤构造SQL语句调用session中的execute方法执行,得......
  • ​Chrome 插件: GoFullPage 一键搞定全网页截图
    在互联网时代,网页截图已成为我们日常工作和生活中不可或缺的部分。无论是保存重要信息、制作教程,还是分享有趣的内容,截图功能都显得尤为重要。然而,常规的截图工具往往只能截取当前屏幕的内容,对于长网页则显得力不从心。你是否也曾为此苦恼过? 如果你曾经尝试过用浏览器自......
  • ​Chrome 插件: GoFullPage 一键搞定全网页截图
      在互联网时代,网页截图已成为我们日常工作和生活中不可或缺的部分。无论是保存重要信息、制作教程,还是分享有趣的内容,截图功能都显得尤为重要。然而,常规的截图工具往往只能截取当前屏幕的内容,对于长网页则显得力不从心。你是否也曾为此苦恼过? 如果你曾经尝试过用浏览器......
  • Js 前置,后置补零的原生方法与补字符串 padStart及padEnd
    在工作中,遇到了需要将不满八位的一个字符串进行后补0的操作,所以就在网上学习了关于js原生补充字符串的方法,然后用这篇博客记录下来。目录前置补充字符串 String.prototype.padStart()后置补充字符串String.prototype.padEnd()前置补充字符串 String.prototype.padStart......
  • 【云原生技术】Serverless简介
    Serverless简介Serverless的定义Serverless的工作原理应用举例1.Web应用后端服务2.数据处理和分析3.IoT应用总结Serverless是一种云计算服务模型,它使开发者能够编写和部署功能单元(Functions)而无需管理底层的服务器资源。下面详细介绍Serverless的定义、工作原理......
  • 记一次原生AB分区OTA升级实现
    记一次原生AB分区OTA升级实现系统需要实现软件ota功能具体代码实现UpdateEnginemUpdateEngine=newUpdateEngine();UpdateParser.ParsedUpdatemParsedUpdate;try{mParsedUpdate=UpdateParser.parse(newFile(Environment.getDataDirectory(),"ota_package/upd......