效果图
在我的上一篇文章已经介绍过如何实现图片压缩,本篇文章主要讲解在此基础上单独实现的图片裁剪功能.
点击选择文件上传一张图片,点击裁切时会出现裁剪框,移动或拉伸裁剪框会在下方生成裁剪后的图片.点击下拉框选择裁剪图的压缩比例.最终点击生成就可以将裁剪压缩后的图片下载到本地.
HTML结构
对应页面图
裁剪功能
思路分析
用户点击选择文件后将图片转换成base64编码在页面上预览,裁剪功能的核心就是实现中间那块虚线的裁剪框.
- 裁剪框的第一个基本功能是当用户鼠标在框上按下后可以拖动框,按键松起后就不能再拖动
- 裁剪框的右下角的黄色小方块单击后拖动可以等比例拉伸改变框的大小
以上两个功能是实现裁剪的重点,最终的目的是通过裁剪获取比例数据就算完成任务,即裁剪框距离左边界的left,距离上边界的top,还有裁剪框自身的width和height.裁剪的使命就是为了获取left,top,width和height这四条数据,随后我们再通过其他的手段通过这四条数据生成裁剪后的图片.
移动裁剪框
先来实现裁剪框的第一个核心功能,鼠标在框上按下后可以拖动框,按键松起后就不能再拖动.
首先定义一个构造函数cropImg,用它生成的对象实现裁剪.目前只需要关注构造函数里的this.target,它是一个div元素,和图片一样大小,图片以背景图的形式完全充满了该div,正是上图中图片外延的虚线框.this.target相当于原始图片.为了便于叙述,我们就将this.target称为图片框.
function cropImg(options) {
this.target = document.getElementById(options.target) || document;
this.width = 0;
this.height = 0;
this.container_width = 0;
this.container_height = 0;
this.mouse_index = 0;
this.callback = options.callback || function () {};
this.fun_list = []; //所有绑定的事件存储起来,插件销毁时解绑
this.init();
}
在this.init()函数里会执行下面渲染裁剪框的逻辑.
在做移动功能之前需要先把裁剪框在页面上渲染出来,否则框都没有就谈不上如何移动.裁剪框也是一个div,将它渲染到图片框的内部.
- 事先设定裁剪框的宽高比和图片框的宽高比保持一致,裁剪框相对于图片框做绝对定位
- 初始渲染裁剪框的宽和高设置为图片框的1/3(比例数据可以自由设定)
- 初始渲染裁剪框的位置处于图片框的正中央
下面的代码就是为了做上面三件事情,创建一个div元素container作为裁剪框对象,通过算出图片框的宽高从而得到裁剪框的宽高,并设置好它的left和top让它处于图片框的正中央位置.
cropImg.prototype.renderBox = function () {
const width = (this.container_width = parseInt( //算出图片框的宽
getComputedStyle(this.target).width
));
const height = (this.container_height = parseInt( //算出图片框的高
getComputedStyle(this.target).height
));
this.radio = width / height; //算出宽高比例
this.width = parseInt(width / 3); //得到裁剪框的宽
this.height = parseInt(height