前端开发那些事儿

一次移动端图片裁剪-JavaScript

2020-07-18  本文已影响0人  D_R_M

由于业务需要用户上传图片并且需要用户自行对上传的图片做尺寸裁剪,本次目的是让用户操作方便、简单,起初翻阅了几个类似功能的库后准备使用 腾讯前端团队的AlloyCrop.js ,在移动端体验很差似乎仓库也没有在维护了,找到了另外俩个库:

这俩款库都支持移动端和pc端,API文档也都写得清晰明了,这里就用Croppie。

安装

NPM:

  npm install croppie

Bower:

  bower install croppie

或者直接引入

  <link rel="stylesheet" href="croppie.css" />
  <script src="croppie.js"></script>

使用

<div class="demo"></div>
<script>
$('.demo').croppie({
    url: 'demo/demo-1.jpg',
});
</script>
<!--更简单用法 -->
<img class="my-image" src="demo/demo-1.jpg" />
<script>
$('.my-image').croppie();
</script>

初始化对象

<div id="demo"></div>
//参数1:页面上的容器Node
//参数2:插件配置项
var c = new Croppie(document.getElementById('demo'), opts);
// 调用方法
//参数:方法接收的参数
c.method(args);
//参数:插件配置项
$('#demo').croppie(opts);
// 调用方法
//参数1:方法名
//参数2:方法接收的参数
$('#demo').croppie(method, args);

配置项:

方法

功能实现

首先在页面插入一些节点作为剪切图片的操作面板。并简单设置一下样式,以及rem单位划分

<style>
        *{padding: 0; margin: 0;}
        html,body{ width: 100%; height: 100%; }
        body{background: #fff;position: relative;}
        .croppie-box{ height: 100%; width: 100%; position: absolute; left: 0; top: 0; z-index: 9999; display: none;}
        .croppie-box .button{ position: absolute; right: 3rem; bottom: 2rem; width: 8rem; height: 2.5rem; z-index: 99; border-radius: 2px; text-align: center; line-height: 2.5rem; font-size: 1rem; }
        .croppie-box .button.ok{ color:#002531; background: rgb(43, 202, 253);}
        .croppie-box .button.cancel{ background-color: #ccc; color:#444; left: 3rem;}
</style>
<script>
        var htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
        var htmlHeight = document.documentElement.clientHeight || document.body.clientHeight;
        var htmlDom = document.documentElement;
        var WIDTH = htmlWidth;
        if(htmlWidth>htmlHeight){
            WIDTH = 750;
            htmlDom.style.cssText = 'width:750px;margin:0 auto;background:#000;'
        }
        htmlDom.style.fontSize= WIDTH/25 + 'px';
</script>
<div class="croppie-box">
  <div class="croppie"></div>
  <div class="button ok">确定</div>
  <div class="button cancel">取消</div>
</div>
<input type="file" name=""  class="upload">
<img class="img" style="width: 100%;height: auto;padding: 2rem;box-sizing: border-box;display: block;" src="" alt="">

将需要用到的节点全部存起来

var croppie = undefined,
  fileInput = document.querySelector('.upload'),
  okBtn = document.querySelector('.button.ok'),
  cancelBtn = document.querySelector('.button.cancel'),
  croppieBox = document.querySelector('.croppie-box'),
  resultImg = document.querySelector('.img');
  scale  = (WIDTH-50) / 5;//计算一个倍数简单适配一下不同手机屏幕

定义俩个待会儿需要用到的方法

croppieBox.show = function(){
  this.style.cssText = 'display:block;'
}
 croppieBox.hide = function(){
  this.style.cssText = 'display:none;'
}

业务要求用户需要裁剪一个5:4比例的图片。
创建Croppie实例,并且不需要底部滑块所以隐藏掉

croppie = new Croppie(croppieBox.querySelector('.croppie'),{
  showZoomer:false,//隐藏滑块
  viewport: {
      width: 5*scale,//乘上倍数 保证裁剪框大小是5:4
      height: 4*scale
  },
  enableExif: true//纠正旋转角度
})

给file绑定一个事件然后把file选择的图片读取到croppie容器里面进行裁剪,zoom设置为0.00001是为了让图片载入的时候能够把一个边完全贴合容器。

fileInput.addEventListener('change', function (e) {
  croppieBox.show();
  croppie.bind({
    url: window.URL.createObjectURL(e.target.files[0]),
    zoom:0.00001,
  })
});

接下来给俩个按钮绑定事件,result方法的size属性需要注意如果选择'viewport'得到的图片会比较模糊因为宽高是根据裁剪视口大小来的(即图像宽通常 < window.innerWidth)。当然可以自行设定{widnth,height}拿固定值(需要注意裁剪的比例如果指定的大小和裁剪比例不一致会导致图片拉伸),在这里的业务场景比较适合用原始图像的宽高所以选择了'original',点击确定调用result方法生成一个blob对象,接下来拿到blob之后就可以自己随意操作了

okBtn.addEventListener('click', function (ev) {
    croppie.result({
      type: 'blob',
      size: 'original',
    }).then(function (resp) {
      resultImg.setAttribute('src',window.URL.createObjectURL(resp))
      fileInput.value='';
      croppieBox.hide();
    });
});

cancelBtn.addEventListener('click', function (ev) {
  croppieBox.hide();
  fileInput.value='';
});

点击预览

仓库地址

上一篇 下一篇

猜你喜欢

热点阅读