Vue实现简单基础的图片裁剪功能

一、准备工作

本文中我所使用的环境为vue2 。现在可以在随便一个vue项目中新建一个vue文件开始了。

二、基本结构

在本文中会使用到两个canvas,一个用来绘制我们要加载的图片,一个用来绘制矩形框选区域,就像下面这样,并且在两个canvas身上分别加上ref属性。

html

<template>
  <div>
    <div class=\"wrap\">
      <canvas id=\"canvas\" ref=\"imgCanvas\"></canvas>
      <canvas
        id=\"drawCanvas\"
        ref=\"drawCanvas\"
      ></canvas>
    </div>
  </div>
</template>

下方样式设置两个canvas重叠

<style>
#drawCanvas {
  position: absolute;
  top: 0;
  left: 0;
}
.wrap {
  position: relative;
}
</style>

三、添加功能

首先我们需要将两个canvas的宽高都设置为相同的,由于上面没有设置canvas的宽高,因此我们在data选项中添加好需要的宽高数据 width: 500,height: 300,稍后将它设置为canvas的大小,请记住,不要用css设置canvas的大小,这其实是将canvas拉伸了。然后在data中添加 ctx 和 imgCtx两个属性用于保存上下文。 接着在mounted生命周期中对canvas进行操作,并且获取到要加载的图片

    let imgCanvas = this.$refs.imgCanvas;//绘制图片的canvas
    let drawCanvas = this.$refs.drawCanvas;//绘制框选款的canvas
    //设置两个canvas的宽高
    imgCanvas.width = this.width;
    imgCanvas.height = this.height;
    drawCanvas.width = this.width;
    drawCanvas.height = this.height;
    //获取两个canvas的上下文并且保存在data中
    this.ctx = drawCanvas.getContext(\"2d\");
    this.imgCtx = imgCanvas.getContext(\"2d\");
    //加载图片
    let img = new Image();
    img.src = \"https://www.auok.ltd/background.jpg\";
    img.crossOrigin = \"anonymous\";
    img.onload = () => {
      console.log(\"加载完成\", img);
      //图片加载完成后开始绘制图片
      this.imgCtx.drawImage(img, 0, 0, this.width, this.height);
    };

以上步骤搞定后现在的页面中应该如下面一样了

11718852d84006e45ce05d9b18f2305a71b608ee

接下来让我们给drawCanvas添加事件监听。需要监听的事件有以下几个

  • 鼠标按下
  • 鼠标抬起
  • 鼠标移动
  • 鼠标移出

我们来改写一下模板结构,像下面这样

<template>
  <div>
    <div class=\"wrap\">
      <canvas id=\"canvas\" ref=\"imgCanvas\"></canvas>
      <canvas
        id=\"drawCanvas\"
        ref=\"drawCanvas\"
        @mousedown=\"onMouseDown\"
        @mousemove=\"onMouseMove\"
        @mouseup=\"onMouseUp\"
        @mouseleave=\"onMouseLeave\"
      ></canvas>
    </div>
    <img :src=\"curSrc\" alt=\"\" style=\"margin: 10px 10px 0 0\" />
    <canvas id=\"outCanvas\"></canvas>
  </div>
</template>

然后在methods中添加对应的onMouseDown、onMouseUp、onMouseMove、onMouseLeave四个方法。然后我们来编写这四个方法就好

onMouseDown

这个方法是鼠标按下事件的监听处理函数。主要负责以下几点

  • 清除drawCanvas
  • 获取鼠标按下时的位置
  • 设置一下绘制线条的样式

代码如下: 编写这个方法前我们要现在data中增加ddownPoint和down两个属性用来存储点的位置标识鼠标是否按下

 onMouseDown(e) {
      console.log(\"鼠标按下\", e.offsetX, e.offsetY);
      this.downPoint = [e.offsetX, e.offsetY];
      this.down = true;
      this.ctx.strokeStyle = \"#fff\";
      this.ctx.lineWidth = 2;
    }

onMouseMove

鼠标按下了,下面就要移动了。此方法是鼠标移动的监听处理函数。负责以下几点

  • 获取鼠标移动的位置
  • 绘制矩形选框
  • 绘制遮罩层
   onMouseMove(e) {
   //鼠标未按下不执行操作
      if (!this.down) {
        return;
      }
    console.log(\"鼠标移动\", e.offsetX, e.offsetY);
    //当前鼠标移动的位置
    let movePoint = [e.offsetX, e.offsetY];
      this.ctx.fillStyle = \"rgba(0,0,0,.5)\";//设置遮罩层填充颜色
      //清空drawCanvas
      this.ctx.clearRect(0, 0, this.width, this.height);
      //使用设置的填充颜色来设置drawCanvas的颜色
      this.ctx.fillRect(0, 0, this.width, this.height);
      //清除指定区域的颜色,因为需要绘制的选框中间是没有颜色的,不然的话选框区域都是遮罩层的颜色。如下图
      this.ctx.clearRect(
        downPoint[0],
        downPoint[1],
        movePoint[0] - this.downPoint[0],
        movePoint[1] - this.downPoint[1]
      );
      //绘制描边矩形 四个参数是x坐标 , y坐标 , 矩形的长,矩形的宽
      this.ctx.strokeRect(
        downPoint[0],
        downPoint[1],
        movePoint[0] - this.downPoint[0],
        movePoint[1] - this.downPoint[1]
      );
    },

9a626950f6c514e4ced125e88d8b18e69301c10b

onMouseUp

这个方法是鼠标松开按键的事件处理函数,主要负责

  • 获取鼠标松开的坐标
  • 获取框选部分的图片 上面的步骤中截图区域已经选择完成。接下来就是要获取截图部分的图片了。

代码如下

    onMouseUp(e) {
        console.log(\"鼠标抬起\", e.offsetX, e.offsetY);
        //获取坐标
        let upPoint = [e.offsetX, e.offsetY];
        //重置鼠标按下状态
        this.down = false;
        //获取指定区域的图片数据
        let cutImgData = this.imgCtx.getImageData(
          this.downPoint[0],
          this.downPoint[1],
          upPoint[0] - this.downPoint[0],
          upPoint[1] - this.downPoint[1]
        );
        //获取返回的图片数据中的宽高
        let { width, height } = cutImgData;
        console.log(cutImgData);
        //创建一个用于放置图片的canvas用来输出图片
        let outCanvas = document.createElement(\"canvas\");
        let outCtx = outCanvas.getContext(\"2d\");
        outCanvas.height = height;
        outCanvas.width = width;
        //将图片放置到canvas上
        outCtx.putImageData(cutImgData, 0, 0);
        //以blob的形式输出图片
        outCanvas.toBlob((blob) => {
          this.curSrc = URL.createObjectURL(blob);
    }

通过调用getImageData获取了图片指定区域的数据,然后将获取到的图片数据使用putImageData放到创建好的canvas中,再通过canvas的toBlob或者toDataURL方法就可以输入图片的二进制数据或者base64字符串了,这里我用的是blob,再通过URL.createObjectURL获取到图片的本地地址,这种形式:blob:http://localhost:8080/e835d581-cdfe-48ff-b562-743bfcd4970d,可以用来显示或者上传。 在模板中添加一个img标签,并且在data中添加cruSrc属性,最后就如下图

<img :src=\”curSrc\” alt=\”\” style=\”margin: 10px 10px 0 0\” />

da55966f4808e5d806a852bc9c1bb0b6c4e24ae7

onMouseLeave

这个方法是在鼠标移出canvas区域后重置canvas的状态的。将鼠标状态down重置为false,然后再清除canvas。

四、总结

如果要实际的实现一个和vue-cropper功能差不多的是比较复杂,要考虑很多东西,比如图像的缩放比例、选框的移动及大小调整之类的。这些部分还没有写。

以上就是Vue实现简单基础的图片裁剪功能的详细内容,更多关于Vue图片裁剪的资料请关注OX520其它相关文章!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容