写在前面

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. 【Python3之基本数据类型,基本运算】

    一.基本数据类型 1.字符串 类:str 方法:选中str,按住command(ctrl)+左键跳转至对应的方法 创建 a = "hexin" a = str('hexin') 转 ...

  2. java排序算法之冒泡排序

    冒泡排序的基本思想即将一串数字进行由小到大进行排序 例如1,9,7,2,4,3,6,10,20,5 实现思路: 第一个数分别与接下来的数字做对比 第一次  1<9不变,再1<7不变,1&l ...

  3. ecshop调用指定分类和个数的文章列表

    举例如首页调用方法: 1.先打开index.php文件找到以下代码: $smarty->assign('new_articles', index_get_new_articles()); // ...

  4. Silverlight将Excel导入到SQLserver数据库

    最近纠结于读取Excel模板数据,将数据导入SQLServer的Silverlight实现,本文将实现代码贴出,作为一个简单的例子,方便各位: 1.先设计前台界面新建Silverlight5.0应用程 ...

  5. javascript四舍五入tofixed

    //toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. $("#renjunlirun").val(zongLiRun.toFixed(2));//金额

  6. 国内APM企业的现状

    19世纪美国西部掘金热大起,大家听闻有人挖到了金子一夜暴富,于是蜂拥而上,但是很多人失望而归,最后居然是卖铲子的人赚到了钱. APM在互联网+时代表示应用性能管理,就是掘金万亿互联网市场的“铲子”,主 ...

  7. iOS基于AVPlayer的视频播放

    基于 AVPlayer 自定义播放器http://www.cocoachina.com/ios/20160921/17609.html,http://www.2cto.com/kf/201608/53 ...

  8. (cljs/run-at (JSVM. :browser) "命名空间就这么简单")

    前言  一个cljs文件定义一个命名空间,通过命名空间可以有效组织代码,这是构建大型系统必备的基础设施.本篇我们就深入理解cljs中的命名空间吧! 好习惯从"头"开始 每个cljs ...

  9. [leetcode-507-Perfect Number]

    We define the Perfect Number is a positive integer that is equal to the sum of all its positive divi ...

  10. 【LeetCode】187. Repeated DNA Sequences

    题目: All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: " ...