写在前面

AlloyCrop 这个项目是8个月前发布的,作为AlloyFinger 的典型案例,发布之后被BAT等其他公司广泛使用。但是发布之后,有两个问题一直没有抽出时间去解决:

  • 裁剪图像的分辨率太小,是否可配?
  • pinch双指放大的时候,放大的中心不是双指中心,是否可以优化?

现在很高兴地告诉大家,AlloyCrop 已经完全搞定了上面两个问题,本文将解释新版本的变化和AlloyCrop背后的原理。当然AlloyFinger的原理这里就不再阐述,以前有分享过 超小Web手势库AlloyFinger原理

先看全新的API变化。

API

new AlloyCrop({
image_src: "img src",
circle: true, // optional parameters , the default value is false
width: 200, // crop width
height: 100, // crop height
output: 2, // output resolution --> 400*200
ok: function (base64, canvas) { },
cancel: function () { },
ok_text: "yes", // optional parameters , the default value is ok
cancel_text: "no" // optional parameters , the default value is cancel
});
参数 是否必填 意义
image_src 必须 需要裁剪图片的src地址
circle 不必须,默认是false 代表选取的是否是圆形还是矩形,默认是矩形,注意:圆形选取裁剪出来的也是正方形图片
width 必须 选区的宽
height 必须 选区的高
output 必须 输出的倍率。比如如果output为2,选区的宽300,选区的高100,输出的图像的分辨率为 (2×300,2×100)
ok 必须 点击ok按钮的回调
cancel 必须 点击cancel按钮的回调
ok_text 不必须,默认是ok ok按钮的文本
cancel_text 不必须,默认是cancel cancel按钮的文本

与之前版本最主要的变化就是新增了 output 支持自定义倍率分辨率的图像输出。

output原理

crop: function () {
this.calculateRect();
this.ctx.drawImage(this.img, this.crop_rect[0], this.crop_rect[1], this.crop_rect[2], this.crop_rect[3], 0, 0, this.canvas.width, this.canvas.height); },

其中 this.calculateRect() 是计算选取和图片重叠在一起的矩形区域,drawImage 是把裁剪的区域绘制到 canvas 上。注意 canvas 的宽高是多少?且看:

this.canvas.width = option.width * this.output;
this.canvas.height = option.height * this.output;

所以就达到了自定义倍率分辨率的目的。当然这里图片的失真又或者超分辨,都取决于 drawImage 插值过程。关于插值,以前特意对比过,使用三次卷积插值完爆了其他几个,但是三次卷积插值速度也是最慢,所以浏览器内核要权衡效率和插值结果去实现 drawImage。

calculateRect计算裁剪区域

因为我们需要把图片的某个区域绘制到整个canvas上。所以drawImage的后四个参数为(0, 0, this.canvas.width, this.canvas.height),然后我们需要去计算图片裁剪的区域。

大概就分上面两种情况,一种是完全包含,一种部分相交。

因为图片会被放大或者缩小(scale),所以情况会变得稍微复杂一点点。求出相交的矩形区域后,要对图片scale进行校正,校正回到1的比例,才能用于drawImage。具体代码参见 https://github.com/AlloyTeam/AlloyCrop/blob/master/alloy-crop.js#L227-L255

pinch 缩放优化

使用AlloyCrop是可以放大或者缩小再进行裁剪,怎么基于 pinch 的两个手指的中间进行放大呢?所以的秘密都在这个multipointStart里。

  • multipointStart是AlloyFinger抛出的多手指开始碰到屏幕的回调函数,通过evt.touches拿到前两个手指的坐标去计算中心坐标
  • 重置 originX 和 originY 到两手指的中心
  • 再重置 translateX 和 translateY 去抹平 originX和originY变更带来的位移
 new AlloyFinger(this.croppingBox, {
multipointStart: function (evt) {
//reset origin x and y
var centerX = (evt.touches[0].pageX + evt.touches[1].pageX) / 2;
var centerY = (evt.touches[0].pageY + evt.touches[1].pageY) / 2;
var cr = self.img.getBoundingClientRect();
var img_centerX = cr.left + cr.width / 2;
var img_centerY = cr.top + cr.height / 2;
var offX = centerX - img_centerX;
var offY = centerY - img_centerY;
var preOriginX = self.img.originX
var preOriginY = self.img.originY
self.img.originX = offX / self.img.scaleX;
self.img.originY = offY / self.img.scaleY;
//reset translateX and translateY
self.img.translateX += offX - preOriginX * self.img.scaleX;
self.img.translateY += offY - preOriginY * self.img.scaleX;
self.initScale = self.img.scaleX;
},
pinch: function (evt) {
self.img.scaleX = self.img.scaleY = self.initScale * evt.zoom;
},
pressMove: function (evt) {
self.img.translateX += evt.deltaX;
self.img.translateY += evt.deltaY;
evt.preventDefault();
}
});
  • 注意,translateX, translateY, translateZ, scaleX, scaleY, scaleZ, rotateX, rotateY, rotateZ, skewX, skewY, originX, originY, originZ 都是 css3transform 类库 注入到DOM元素上的属性。

Preview

Demo

Dependencies

License

This content is released under the MIT License.

腾讯 AlloyCrop 1.0 发布的更多相关文章

  1. 腾讯 Omi 5.0 发布 - Web 前端 MVVM 王者归来,mappingjs 强力加持

    写在前面 腾讯 Omi 框架正式发布 5.0,依然专注于 View,但是对 MVVM 架构更加友好的集成,彻底分离视图与业务逻辑的架构. 你可以通过 omi-cli 快速体验 MVVM: $ npm ...

  2. Surging1.0发布在即,.NET开发者们,你们还在等什么?

    Surging1.0发布在即,.NET开发者们,你们还在等什么? 开源,是近三十年来互联网经久不衰的话题.它不仅仅是一种技术分享的形态,更是一种开放,包容,互利共赢的互联网精神. 不到30年前,大神林 ...

  3. 腾讯 angel 3.0:高效处理模型

    腾讯 angel 3.0:高效处理模型 紧跟华为宣布新的 AI 框架开源的消息,腾讯又带来了全新的全栈机器学习平台 angel3.0.新版本功能特性覆盖了机器学习的各个阶段,包括:特征工程.模型训练. ...

  4. Visual Studio Code 1.0发布,支持中文在内9种语言

    Visual Studio Code 1.0发布,支持中文在内的9种语言:Simplified Chinese, Traditional Chinese, French, German, Italia ...

  5. Apache Flume 1.7.0 发布,日志服务器

    Apache Flume 1.7.0 发布了,Flume 是一个分布式.可靠和高可用的服务,用于收集.聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型.这是一个可靠.容错的服务. 本次更 ...

  6. Percona Server 5.6.33-79.0 发布

    Percona Server 5.6.33-79.0 发布了,该版本基于 MySQL 5.6.33,包含了所有的 bug 修复,是Percona Server 5.6 系列中的正式版本.该版本主要是修 ...

  7. Rubinius 2.0 发布,Ruby 虚拟机

    Rubinius 2.0 发布了,官方发行说明请看这里. Rubinius是一个运行Ruby程序的虚拟机,其带有Ruby的核心库. Rubinius的设计决定了其调试功能的强大,使得在运行时常规的Ru ...

  8. Restful.Data v2.0发布,谢谢你们的支持和鼓励

    v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...

  9. 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!

    网页动物园2.0发布,经过几个月的努力,采用JAVA编写! 网页动物园2.0 正式发布!游戏发布 游戏名称: 网页动物园插件 游戏来源: 原创插件 适用版本: Discuz! X1.5 - X3.5 ...

随机推荐

  1. 使用hashCode()和equals()方法 - Java

    在这篇文章中,我将指出我对hashCode()和equals()方法的理解.我将讨论它们的默认实现以及如何正确地覆盖它们.我还将使用Apache Commons包中的实用工具类来实现这些方法. has ...

  2. js前端实现多图图片上传预览

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  3. AngularJS高级程序设计读书笔记 -- 大纲篇

    零. 初衷 现在 AngularJS 4 已经发布了, 楼主还停留在 1.x 的阶段, 深感自卑. 学习 AngularJS 的初衷是因为, 去年楼主开始尝试使用 Flask 开发自动化程序, 需要用 ...

  4. Qt中的View Model模型

    原始日期: 2016-08-17 21:19 Qt中的View主要有三种QListView,QTreeView, QTabelView 而对应的Model是:QStringListModel, QAb ...

  5. PHP中递归最详解释.

    说到递归函数想必会有很多同学感到晕晕的,很难绕,容易绕错,那下面就让我来为大家详解一下. 首先,什么是递归函数呢? 1.所谓递归:指的是在函数内部,调用函数自身的操作.2.递归分两布:递(从最外层函数 ...

  6. 多个form表单的提交

    if(zhengchang_stop&&no_zhengchang_wancheng&&respon_info_lists){ $('form[name="f ...

  7. iOS10 相关的隐私设置,

    最近下载了几个demo,总是一运行就崩,看了下崩溃日志,有几个是因为没在plist里设置因此权限,而现在iOS 10 开始对隐私权限更加严格, 如需使用隐私权限需要在工程的info.plist文件中声 ...

  8. 浅谈angular中的promise

    promise目的就是为了跳出回调地狱.老掉牙的东西,大神轻拍. 举个最简单的例子:请求数据(getData),解析数据(executeData),显示数据(showData). //获取数据 fun ...

  9. Spring 加载静态资源

    <mvc:default-servlet-handler/> JSP 中通过标签加载js文件或者link标签加载css文件等静态资源时要在springmvc的xml文件中配置以上设置请求就 ...

  10. 基于GTID的Mysql-Mha高可用方案探索

    声明: 本篇文章内容整理来源于互联网以及本人自己的梳理总结,目的是从零到一的搭建起来mysql mha高可用架构. 一.软件概述 MHA(Master High Availability)目前在MyS ...