Giter VIP home page Giter VIP logo

photoclip.js's Introduction

PhotoClip.js v3 npm version

一款手势驱动的裁图插件,移动端照片裁剪的简洁化解决方案!

  • 在移动设备上双指捏合为缩放,双指转动为旋转
  • 在PC设备上鼠标滚轮为缩放,每次双击则顺时针旋转90度

Demo(如果无法打开,请翻墙,或者自行下载体验)

兼容

IE10及以上版本,Chrome、Firefox、Safari、Android、微信等主流先进浏览器

依赖插件

iscroll-zoom.js
hammer.js
lrz.all.bundle.js

由于 iscroll 原插件的 zoom 扩展存在几处 bug,所以建议使用 demo 中提供的 iscroll-zoom.js 文件,本人已经将这些 bug 修复,并针对本插件做了优化。

使用方法

一般引入

<div id="clipArea"></div>
<input type="file" id="file" />
...
<script src="js/iscroll-zoom.js"></script>
<script src="js/hammer.min.js"></script>
<script src="js/lrz.all.bundle.js"></script>
<script src="js/PhotoClip.js"></script>
<script>
var pc = new PhotoClip('#clipArea');
file.addEventListener('change', function() {
    pc.load(this.files[0]);
});
</script>

AMD模块化引入

require.config({
    paths: {
        'iscroll': 'js/iscroll-zoom-min',
        'hammer': 'js/hammer.min',
        'lrz': 'js/lrz.all.bundle',
        'PhotoClip': 'js/PhotoClip'
    },
    shim: {
        'iscroll': {
            exports: 'IScroll'
        }
    }
});

require(['PhotoClip'], function(PhotoClip) {
    var pc = new PhotoClip('#clipArea');
});

通过npm引入

安装

$ npm install photoclip

引入

// ES6
import PhotoClip from 'photoclip'
// CommonJS
var PhotoClip = require('photoclip')

PhotoClip 构造函数

new PhotoClip( container [, options] )

构造函数有两个主要参数:

container

表示图片裁剪容器的选择器或者DOM对象。

options

配置选项,详细配置如下:

  • options.size

    type: Number|Array

    截取框大小。
    当值为数字时,表示截取框为宽高都等于该值的正方形。
    当值为数组时,数组中索引[0][1]所对应的值分别表示宽和高。
    默认值为 [100,100]

  • options.adaptive

    type: String|Array

    截取框自适应。设置该选项后,size 选项将会失效,此时 size 进用于计算截取框的宽高比例。
    当值为一个百分数字符串时,表示截取框的宽度百分比。
    当值为数组时,数组中索引 [0][1] 所对应的值分别表示宽和高的百分比。
    当宽或高有一项值未设置或值无效时,则该项会根据 size 选项中定义的宽高比例自适应。
    默认为 ''

  • options.outputSize

    type: Number|Array

    输出图像大小。
    当值为数字时,表示输出宽度,此时高度根据截取框比例自适应。
    当值为数组时,数组中索引 [0][1] 所对应的值分别表示宽和高,若宽或高有一项值无效,则会根据另一项等比自适应。
    默认值为[0,0],表示输出图像原始大小。

  • options.outputType

    type: String

    指定输出图片的类型,可选 'jpg' 和 'png' 两种种类型,默认为 'jpg'。

  • options.outputQuality

    type: Number

    图片输出质量,仅对 jpeg 格式的图片有效,取值 0 - 1,默认为0.8。(这个质量并不是图片的最终质量,而是在经过 lrz 插件压缩后的基础上输出的质量。相当于 outputQuality * lrzOption.quality

  • options.maxZoom

    type: Number

    图片的最大缩放比,默认为 1。

  • options.rotateFree

    type: Boolean

    是否启用图片自由旋转。由于安卓浏览器上存在性能问题,因此在安卓设备上默认关闭。

  • options.view

    type: String|HTMLElement

    显示截取后图像的容器的选择器或者DOM对象。如果有多个,可使用英文逗号隔开的选择器字符串,或者DOM对象数组。

  • options.file

    type: String|HTMLElement

    上传图片的 <input type="file"> 控件的选择器或者DOM对象。如果有多个,可使用英文逗号隔开的选择器字符串,或者DOM对象数组。

  • options.ok

    type: String|HTMLElement

    确认截图按钮的选择器或者DOM对象。如果有多个,可使用英文逗号隔开的选择器字符串,或者DOM对象数组。

  • options.img

    type: String

    需要裁剪图片的url地址。该参数表示当前立即开始读取图片,不需要使用 file 控件获取。注意,加载的图片必须要与本程序同源,如果图片跨域,则无法截图。

  • options.loadStart

    type: Function

    图片开始加载的回调函数。this 指向当前 PhotoClip 的实例对象,并将正在加载的 file 对象作为参数传入。(如果是使用非 file 的方式加载图片,则该参数为图片的 url)

  • options.loadComplete

    type: Function

    图片加载完成的回调函数。this 指向当前 PhotoClip 的实例对象,并将图片的 <img> 对象作为参数传入。

  • options.loadError

    type: Function

    图片加载失败的回调函数。this 指向当前 PhotoClip 的实例对象,并将错误信息作为第一个参数传入,如果还有其它错误对象或者信息会作为第二个参数传入。

  • options.done

    type: Function

    裁剪完成的回调函数。this 指向当前 PhotoClip 的实例对象,会将裁剪出的图像数据DataURL作为参数传入。

  • options.fail

    type: Function

    裁剪失败的回调函数。this 指向当前 PhotoClip 的实例对象,会将失败信息作为参数传入。

  • options.lrzOption

    type: Object

    lrz 压缩插件的配置参数。该压缩插件作用于图片从相册输出到移动设备浏览器过程中的压缩,配置的高低将直接关系到图片在移动设备上操作的流畅度。以下为子属性:

    • options.lrzOption.width

      type: Number

      图片最大不超过的宽度,默认为原图宽度,高度不设时会适应宽度。(由于安卓浏览器存在性能问题,所以默认值为 1000)

    • options.lrzOption.height

      type: Number

      图片最大不超过的高度,默认为原图高度,宽度不设时会适应高度。(由于安卓浏览器存在性能问题,所以默认值为 1000)

    • options.lrzOption.quality

      type: Number

      图片压缩质量,仅对 jpeg 格式的图片有效,取值 0 - 1,默认为0.7。(这个质量不是最终输出的质量,与 options.outputQuality 是相乘关系)

  • options.style

    type: Object

    样式配置。以下为子属性:

    • options.style.maskColor

      type: String

      遮罩层的颜色。默认为 'rgba(0,0,0,.5)'

    • options.style.maskBorder

      type: String

      遮罩层的 border 样式。默认为 '2px dashed #ddd'

    • options.style.jpgFillColor

      type: String

      当输出 jpg 格式时透明区域的填充色。默认为 '#fff'

  • options.errorMsg

    type: Object

    错误信息对象,包含各个阶段出错时的文字说明。以下为子属性:

    • options.errorMsg.noSupport

      type: String

      浏览器无法支持本插件。将会使用 alert 弹出该信息,若不希望弹出,可将该值置空。

    • options.errorMsg.imgError

      type: String

      使用 file 控件读取图片格式错误时的错误信息。将会在 loadError 回调的错误信息中输出。

    • options.errorMsg.imgHandleError

      type: String

      lrz 压缩插件处理图片失败时的错误信息。将会在 loadError 回调的错误信息中输出。

    • options.errorMsg.imgLoadError

      type: String

      图片加载出错时的错误信息。将会在 loadError 回调的错误信息中输出。

    • options.errorMsg.noImg

      type: String

      没有加载完成的图片时,执行截图操作时的错误信息。将会在 fail 回调的失败信息中输出。

    • options.errorMsg.clipError

      type: String

      截图出错时的错误信息。将会在 fail 回调的失败信息中输出。

PhotoClip 对象实例方法

/**
 * 设置截取框的宽高
 * 如果设置了 adaptive 选项,则该方法仅用于修改截取框的宽高比例
 * @param  {Number} width  截取框的宽度
 * @param  {Number} height 截取框的高度
 * @return {PhotoClip}     返回 PhotoClip 的实例对象
 */
pc.size(width, height);

/**
 * 加载一张图片
 * @param  {String|Object} src 图片的 url,或者图片的 file 文件对象
 * @return {PhotoClip}         返回 PhotoClip 的实例对象
 */
pc.load(src);

/**
 * 清除当前图片
 * @return {PhotoClip}  返回 PhotoClip 的实例对象
 */
pc.clear();

/**
 * 图片旋转到指定角度
 * @param  {Number} angle      可选。旋转的角度
 * @param  {Number} duration   可选。旋转动画的时长,如果为 0 或 false,则表示没有过渡动画
 * @return {PhotoClip|Number}  返回 PhotoClip 的实例对象。如果参数为空,则返回当前的旋转角度
 */
pc.rotate(angle, duration);

/**
 * 图片缩放到指定比例,如果超出缩放范围,则会被缩放到可缩放极限
 * @param  {Number} zoom       可选。缩放比例,取值在 0 - 1 之间
 * @param  {Number} duration   可选。缩放动画的时长,如果为 0 或 false,则表示没有过渡动画
 * @return {PhotoClip|Number}  返回 PhotoClip 的实例对象。如果参数为空,则返回当前的缩放比例
 */
pc.scale(zoom, duration);

/**
 * 截图
 * @return {String}  返回截取后图片的 Base64 字符串
 */
pc.clip();

/**
 * 销毁
 * @return {Undefined}  无返回值
 */
pc.destroy();

FAQ

Q: 为什么使用插件裁剪出来的图片比原始图还大?

A:

PhotoClip.js 仅仅是一个前端裁图插件,其中用到的压缩是为了防止手机中过大的照片(约2MB)载入到某些手机浏览器中导致崩溃的问题,原理上是用canvas来实现的。

因此对于一些过小的图片(几十KB),有时裁剪出的图片反而会变大(几百KB),这种现象是正常现象。如果对于图片压缩效果不满意,建议将图片传到后端,由后端图形引擎进行真正的压缩处理。

Q: 为什么在旋转图片操作时卡顿严重,甚至图片时有时无,更严重的导致浏览器崩溃?

A:

由于照片自身尺寸很大,配置越高的手机往往一张照片的尺寸会达到几千的像素宽高,这种图片加载进浏览器后,会占用大量的内存。如果对图片进行移动、缩放、旋转等操作时,浏览器就需要对图片进行重绘,此时就会消耗设备性能。尤其是图片进行旋转操作时,对设备的性能消耗巨大。这一点在安卓设备上尤为突出。

因此,如果出现上述问题,请使用 options.lrzOption 选项,限制图片的最大宽高,可以有效的降低浏览器的压力,但副作用是会大大的降低图片的质量。

您的捐助是我最大的动力

image

photoclip.js's People

Contributors

baijunjie avatar

Stargazers

starm avatar Adam Lu avatar  avatar Microtobe avatar aLi avatar Leo avatar Yiding Jin avatar  avatar viivaev avatar hot-coffee avatar  avatar Mark avatar Junjun avatar o2y avatar  avatar Lyter avatar  avatar Royce Zhang avatar  avatar  avatar  avatar Web Front end avatar  avatar tang avatar Yao Shiquan avatar  avatar  avatar Font End React Coder In ChengDu avatar swagger avatar Yu avatar  avatar  avatar xiaosi avatar MeePwn avatar Arjun avatar 似若秋叶 avatar 余明智 avatar  avatar ShaoHua avatar 牧风 avatar John Titor avatar Adger avatar LinJieLinLin avatar  avatar LEI avatar  avatar  avatar  avatar indiboy avatar  avatar Yuchang Zhou avatar  avatar  avatar  avatar Liu Jinghua avatar  avatar  avatar  avatar  avatar Tao avatar  avatar  avatar  avatar RadEon9550_CN avatar Daniel avatar baobeisuper avatar  avatar struggle_ale avatar sali avatar mm avatar  avatar  avatar beifeng avatar  avatar Full stack grave avatar  avatar  avatar JetChou avatar  avatar Lynn avatar  avatar infinityboy avatar  avatar NEOSOUL avatar  avatar  avatar  avatar  avatar  avatar zss avatar 花花 avatar  avatar xuhaibing avatar  avatar guopeng avatar Shuokang Jin avatar  avatar 5% avatar 偶是小菜鸟 avatar dc avatar

Watchers

James Cloos avatar  avatar xiaolin avatar  avatar 孙万鑫 avatar  avatar RongJie avatar MichaelSun avatar  avatar ofix avatar chenxingbin avatar ciyafo avatar kado avatar  avatar  avatar BUG avatar Troy Cui avatar  avatar  avatar 严浩韦 avatar  avatar  avatar  avatar 鸥鹭忘机 avatar  avatar Jason Li avatar Wang Zheng avatar cw avatar  avatar  avatar  avatar  avatar 小仙女 avatar HUGY1 avatar laughing avatar

photoclip.js's Issues

安卓下闪动

安卓下闪动,在浏览器微信未出现 webview 中放大缩小摇晃的很厉害

iphone

苹果手机上裁剪之后会失败,这个怎么解决

flip option

Hi, I love your library, seems to be the best there is.
I would like to add a flip vertical / horizontal options to it.

How would you recommend doing it?

问题

手机上有些图片不能上传

图片存在跨域问题

var pc = new PhotoClip('#clipArea',{ size: [230,310], outputSize: 375, lrzOption:{quality:0.9}, file: '#picture', ok: '#clipBtn', loadStart: function() { console.log('开始读取照片'); }, loadComplete: function() { console.log('照片读取完成'); },done: function(dataURL) { var url=“xxxxx.xxxxx.xxx” $.ajax({ url: url, type: 'post', data: {base64_string: dataURL}, dataType: 'json', timeout: 200000, success: function (response) { $.hideIndicator(); console.log(response) if (response.code ===0) { $("#input_picture_url").val(response.data.url) $("#Myimg").attr("src",response.data.url); $.toast("图片上传成功"); $("#pop_photoclip").hide(); return true; } else { $("#pop_photoclip").hide(); return alert(response.reason); } }, error: function (jqXHR, textStatus, errorThrown) { if (textStatus == 'timeout') { $.toast("请求超时"); return false; } $.toast(jqXHR.responseText); alert(jqXHR.responseText); $("#pop_photoclip").hide(); } }); }, fail: function(msg) { console.log("122") alert(msg); } 直接跳过了done直接在fail这报图片文件存在跨域问题,请问这是什么问题?

clipArea.destroy()使用后不能重新创建对象

我使用的场景是这样得:
打开一个弹出层,然后在这个层内创建插件对象。
当直接创建对象:

new PhotoClip("#clipArea",{
                size: [260, 350], // 截取框的宽和高组成的数组。默认值为[260,260]
                outputSize: [0, 0], // 输出图像的宽和高组成的数组。默认值为[0,0],表示输出图像原始大小
                //outputType: "jpg",    // 指定输出图片的类型,可选 "jpg" 和 "png" 两种种类型,默认为 "jpg"
                file: "#selectPhoto", // 上传图片的<input type="file">控件的选择器或者DOM对象
                //view: "#view",        // 显示截取后图像的容器的选择器或者DOM对象
                ok: "#clipSave", // 确认截图按钮的选择器或者DOM对象

这里不写完,因为有点长。第一次点击上传图片没有问题。上传了一张。然后再次点击选择图片,相应的图片上传就成了两张。然后再次点击选择图片上传,就成了四张。通过

 loadStart: function(file) {
                    console.info("start load");
                }

输出值发现,第二次选择上传的时候这个被执行了两次,第三次就执行了4次。我想着或许用你的插件提供的clipArea.destroy()等到上传成功后,销毁创建的对象。然后再次打开弹出层,重新创建这个插件对象能解决此问题。我是这样用的:

$("#popPhoto").popup();
            console.info("pop1");
            var clipArea=new PhotoClip("#clipArea",{
                size: [260, 350], // 截取框的宽和高组成的数组。默认值为[260,260]
                outputSize: [0, 0], // 输出图像的宽和高组成的数组。默认值为[0,0],表示输出图像原始大小
                //outputType: "jpg",    // 指定输出图片的类型,可选 "jpg" 和 "png" 两种种类型,默认为 "jpg"
                file: "#selectPhoto", // 上传图片的<input type="file">控件的选择器或者DOM对象
                //view: "#view",        // 显示截取后图像的容器的选择器或者DOM对象
                ok: "#clipSave", // 确认截图按钮的选择器或者DOM对象
                // 开始加载的回调函数。this指向 fileReader 对象,并将正在加载的 file 对象作为参数传入
                loadStart: function(file) {
                    console.info("start load");
                },
                // 加载完成的回调函数。this指向图片对象,并将图片地址作为参数传入
                loadComplete: function(dataURL) {
                    console.info("start complete");
                },
                // 加载失败的回调函数。this指向 fileReader 对象,并将错误事件的 event 对象作为参数传入
                loadError: function(event) {
                    console.info("load error");
                },
                // 裁剪完成的回调函数。this指向图片对象,会将裁剪出的图像数据DataURL作为参数传入
                clipFinish: function (dataURL, a, b) {
                    console.info("clipFinish");
                    $.post("/wx/WxService/Upload64", { fileName: "", fileCategory: "/images/Activity", imageBuffer: dataURL }, function(data) {
                        page.VM.Photo(data.Content);
                        $("#Photo").val(data.Content);
                        if (data.Code != 0) {
                            //console.info("alert");
                            $.alert(data.Content);
                            return;
                        }
                        //console.info($("#Photo").val());
                        clipArea.destroy();
                        //clipArea = null;
                        $.closePopup();
                        
                    });
                }
            });

第一次打开弹出层,然后选中图片保存,保存完后自动关闭弹出层。然后第二次打开弹出层,选择图片,再次保存图片的时候出现了这个js提示:
jquery.photoClip.js:515 Uncaught TypeError: Cannot read property 'offset' of null
这我猜测是因为你的destroy方法销毁了太多东西,导致再次创建的对象有缺失造成。另外我不能确定,你这个多次选择图片,保存的图片成倍增加是不是因为你这个插件的问题。期待你的解决

谷歌浏览器53版本,一些小问题

用谷歌浏览器53版本,此插件在调出file控件的文件选取器时会非常慢,大概需要3-4秒左右。(其他浏览器并无此问题,谷歌其他版本没测,但也应该没有这个问题)

一些bug

插件很好用,使用过程中发现一些问题,IOS手机端刚加载图片后没有剪裁的那个虚线框(安卓端没测),手势不太好用,每次缩放都会旋转,希望能够改进,或有参数可以选择是否使用旋转功能

有计划不依赖jquery吗

作者做的插件非常好,经常在项目中使用,非常感谢。
不过最近开始使用vue后不再引入jquery了,也不想再专门为了一个插件专门引入jquery。
不知道作者有没有计划去掉jquery的依赖?

希望添加下载图片功能

目前我知道保存图片的方式有一下几种:
1.将canvas转base64放入img标签里,长按保存图片,但是有些浏览器兼容性不是很好。
2.js创建a标签,将href替换为base64数据,并添加download属性,兼容性也不是很好,电脑上可以下载,手机上有些浏览器没反应,有些是跳转页面展示图片。

找来找去找不到很好的解决办法,所以希望大神能出个方案,适应不同设备、不同浏览器的图片下载方案!

怎么在vue-cli项目中使用啊?

import IScroll from '../assets/js/iscroll-zoom'
import Hammer from '../assets/js/hammer.min'
import lrz from '../assets/js/lrz.all.bundle'
import PhotoClip from '../assets/js/PhotoClip'

这样直接import 会报错。。。
ERROR in ./src/assets/js/PhotoClip.js
Module not found: Error: Cannot resolve module 'iscroll-zoom' in /home/zz/Desktop/vue-wechat/src/assets/js
@ ./src/assets/js/PhotoClip.js 13:2-52

ERROR in ./src/assets/js/PhotoClip.js
Module not found: Error: Cannot resolve module 'hammer' in /home/zz/Desktop/vue-wechat/src/assets/js
@ ./src/assets/js/PhotoClip.js 13:2-52

ERROR in ./src/assets/js/PhotoClip.js
Module not found: Error: Cannot resolve module 'lrz' in /home/zz/Desktop/vue-wechat/src/assets/js
@ ./src/assets/js/PhotoClip.js 13:2-52

将截取之后的dataURL赋值给一个IMG,然后用drawImage画到画布上,此时从 img1.onload开始在部分苹果机器上不执行,包括6s/IOS11.0, 5s IOS9.3

将截取之后的dataURL赋值给一个IMG,然后用drawImage画到画布上,此时从 img1.onload开始在部分苹果机器上不执行,包括6s/IOS11.0, 5s IOS9.3

done: function(dataURL) {
			//pc.rotate(90, 4);
			//console.log(dataURL);
			var img1=new Image;
			img1.setAttribute('crossOrigin', 'anonymous');
			img1.src=dataURL;
			alert(img1.src);
			$('#clipArea').hide();
			$('.light1').attr('src',dataURL);
			alert("good1");
			img1.onload=function(){
				alert('开始画');
				ctx.drawImage(img1,455,512,208,255);

				uploadfileid='1';
				
				alert("good122");
			}
			
		},

一点小建议。

近来因为弄个微信页面需要用到上传头像的功能,无意中发现了这个小插件,用起来感觉挺好的。但有个小问题,我看了下注释,相信作者也发现了,就是ios照片的方向问题。其实这个问题可以通过Exif.js来解决,具体见 http://code.ciaoca.com/javascript/exif-js/ ,可以在图片转base64编码后,检测Orientation值来判断图片方向,在初始化时把图片旋转到正确的方向。希望这点建议对插件的改进会有帮助。

图片截取后有很多小白点

图片压缩失真太严重了,导致图片有很多白点,请问有什么解决方法吗?
outputQuality: 1, lrzOption: { quality: 1 },这里我改到最高了

安卓设备上options.img属性设置的问题

在安卓设备上使用此插件,options.img属性设置为file:///data/data/com.abc.cheng/cache/tmp_ImageSelector_20161121_121131-751232154.JPEG,无法正常运行,这个问题怎么解决?

希望有销毁函数

原因是这样的,当开发 Web APP 时,看似不同的页面确实在一个 html 里,有不同尺寸的图片需要上传时,我们向复用一个页面时变得困难。

希望添加一个这样的函数。^_^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.