资讯专栏INFORMATION COLUMN

zepto.cutphoto 头像裁剪小工具

chunquedong / 717人阅读

摘要:首先它是基于的同样能用。其次它其实就是借助的一些属性做了一些小改动。第一个版本粗糙了些,借助他人代码和思路多了一些,后续马上会优化起来可以访问网址,在这里也可以直接下载代码使用起来也很简单如果对代码感兴趣,图片裁剪

这几天在做移动端的事情,其中有一个涉及到上传头像,这个功能模型简直不要太常见了,几乎所有的网站都到有这个功能,所以避免重复造轮子,直接参考大家的方案,封装了这个小东西,还有很多待遇完善的地方,后期也肯定会继续优化,现在就先这样子吧。

首先它是基于 zepto 的(jquery 同样能用)。

其次它其实就是借助 canvas 的一些属性做了一些小改动。

压缩过后 8kb 大小。

第一个版本粗糙了些,借助他人代码和思路多了一些,后续马上会优化起来&&&&&

可以访问网址,在这里---> Zepto cutphoto;
也可以直接下载代码---> Zepto cutphoto for github

使用起来也很简单:

$.cutPhoto(
    {
        container         : "container_node",
        browse_button     : "browseFile",
        save_button       : "saveimg",
        filters_background: "<%= locals.userInfo.photo_url %>"
    },
    function (cutPhotoCacheData, initStatus) {
        var imgData   = cutPhotoCacheData();
        //todo
    }
);

如果对代码感兴趣,↓↓↓↓

+function ($) {
    "use strict";
    var cutPhoto         = function (data, callback) {

        var options = cutPhoto_options.defaults;

        $("#" + data.browse_button).bind("change", function (event) {
            var reader = new FileReader();
            $(imgCutPreview).css({"width": "", "height": ""});

            reader.onload      = function (evt) {
                document.getElementById(imgCutPreview.attr("id")).src = evt.target.result;
                $.hidePreloader();
            };
            options.cutImgData = reader.readAsDataURL(this.files[0]);
        });
        var containerNode         = $("#" + data.container),
            wrapper               = $("
", { id : "wrapper", css: { padding: ".5rem" } }), componentNode = $("
", { id : "component_node", css: { position : "relative", margin : "0 auto", border : "1px green solid", width : "302px", height : "302px", background: "#eee", overflow : "hidden" } }), cutWrapperNode = $("
", { id : "cut_wrapper_node", css: { overflow : "hidden", display : "none", position : "absolute", top : "0", left : "0", "z-index": "15" } }), imgCutPreview = $("", { id : "img_cut_preview", css: { border: "0" } }).on("load", function () { options.cutImgWidth = document.getElementById(imgCutPreview.attr("id")).width; options.cutImgHeight = document.getElementById(imgCutPreview.attr("id")).height; imgCutPreviewWidthAndHeightInit(); imgCutPreviewWidthAndHeight(); mainCutterWidthAndHeight(); cutBoxWidthAndHeightInit(); cutBoxWidthAndHeight(); options.initStatus = true; options.processInitStatus = true; options.processPercent = 100; options.processPointX = options.processBarWidth; processPoint.css("left", options.processPointX + "px"); }), cutBox = $("
", { id : "cut_box", css: { position : "absolute", width : "200px", height : "200px", opacity : ".5", background: "gray" } }).bind("touchstart", function (event) { event.preventDefault() && event.stopPropagation(); options.moveBeginX1 = event.changedTouches[0].pageX; options.moveBeginY1 = event.changedTouches[0].pageY; }).bind("touchmove", function (event) { event.preventDefault() && event.stopPropagation(); options.moveEndX1 = event.changedTouches[0].pageX; options.moveEndY1 = event.changedTouches[0].pageY; options.cutLeft += (options.moveEndX1 - options.moveBeginX1); options.cutTop += (options.moveEndY1 - options.moveBeginY1); if (options.cutLeft < options.cutBoxLimitX1) { options.cutLeft = options.cutBoxLimitX1; } else if (options.cutLeft > options.cutBoxLimitX2) { options.cutLeft = options.cutBoxLimitX2; } if ((options.cutLeft + options.cutViewWidth) > options.cutBoxLimitX2) { options.cutLeft = options.cutBoxLimitX2 - options.cutViewWidth; } if (options.cutTop < options.cutBoxLimitY1) { options.cutTop = options.cutBoxLimitY1; } else if (options.cutTop > options.cutBoxLimitY2) { options.cutTop = options.cutBoxLimitY2; } if ((options.cutTop + options.cutViewHeight) > options.cutBoxLimitY2) { options.cutTop = options.cutBoxLimitY2 - options.cutViewHeight; } cutBoxWidthAndHeight(true); options.moveBeginX1 = options.moveEndX1; options.moveBeginY1 = options.moveEndY1; }).bind("touchend", function (event) { event.preventDefault() && event.stopPropagation(); return false; }), imgBackground = $("
", { id : "img_background", css: { position : "relative", width : "100%", height : "100%", "background" : "url("" + data.filters_background + "")", "background-size": "100%", "z-index" : "10", opacity : ".1" } }), cropper = $("", { id : "cropper", css: { display: "none", border : "1px solid red", width : "300px", height : "300px" } }), wrapperFooter = $("
", { id : "wrapper_footer", css: { "margin-left": "0", "overflow" : "hidden" } }), spanTitleNode = $("", { text: "图片裁剪", css : { "font-size" : "12px", "height" : "20px", "line-height": "20px", "text-align" : "center", "background" : "#F88103", "color" : "#fff", "width" : "20%", "margin" : "0", "box-sizing" : "border-box", "float" : "left" } }), wrapperFooterRightBox = $("
", { css: { "background": "#F88103", "width" : "80%", "margin" : "0", "box-sizing": "border-box", "float" : "left" } }), processBar = $("
", { id : "process_bar", css: { "margin" : "0 auto", "position" : "relative", "width" : "220px", "height" : "20px", "background" : "#e7e7e7", "border-radius" : "3px", "border" : "1px solid #f60", "-moz-box-shadow" : "1px 1px 1px rgba(153,153,153,.15) inset", "-webkit-box-shadow": "1px 1px 1px rgba(153,153,153,.15) inset", "box-shadow" : "1px 1px 1px rgba(153,153,153,.15) inset" } }).bind("touchstart", function (event) { event.preventDefault() && event.stopPropagation(); if (!options.processInitStatus) { return false; } options.processBeginX = event.changedTouches[0].pageX; options.processBeginY = event.changedTouches[0].pageY; }).bind("touchmove", function (event) { event.preventDefault() && event.stopPropagation(); if (!options.processInitStatus) { return; } options.processEndX = event.changedTouches[0].pageX; options.processEndY = event.changedTouches[0].pageY; options.processPercent += parseInt((options.processEndX - options.processBeginX) * 100 / options.processBarWidth); if (options.processPercent < 0) { options.processPercent = 0; } else if (options.processPercent > 100) { options.processPercent = 100; } options.processPointX = parseInt(options.processBarWidth * (options.processPercent / 100)); processPoint.css("left", options.processPointX + "px"); var _new_cut_width = parseInt(options.cutMaxWidth * (options.processPercent / 100)), _new_cut_height = parseInt(options.cutMaxHeight * (options.processPercent / 100)); if (_new_cut_width > options.cutViewWidth) { options.cutLeft = options.cutLeft - parseInt((_new_cut_width - options.cutViewWidth) / 2); options.cutTop = options.cutTop - parseInt((_new_cut_height - options.cutViewHeight) / 2); options.cutViewWidth = _new_cut_width; options.cutViewHeight = _new_cut_height; cutBoxWidthAndHeight(true); } else if (_new_cut_width < options.cutViewWidth) { options.cutLeft = options.cutLeft + parseInt((options.cutViewWidth - _new_cut_width) / 2); options.cutTop = options.cutTop + parseInt((options.cutViewHeight - _new_cut_height) / 2); options.cutViewWidth = _new_cut_width; options.cutViewHeight = _new_cut_height; cutBoxWidthAndHeight(true); } options.processBeginX = options.processEndX; options.processBeginY = options.processEndY; }).bind("touchend", function (event) { event.preventDefault() && event.stopPropagation(); if (!options.processInitStatus) { return false; } }), processPoint = $("
", { id : "process_point", css: { "background" : "#F88103", "width" : "18px", "height" : "18px", "position" : "absolute", "border-radius": "50%", "left" : "0", "top" : "0" } }); function imgCutPreviewWidthAndHeightInit() { var scale = Math.max(options.cutImgWidth / options.width, options.cutImgHeight / options.height); if (scale > 1) { options.cropViewInitWidth = options.cropViewWidth = parseInt(Math.floor(options.cutImgWidth / scale)); options.cropViewInitHeight = options.cropViewHeight = parseInt(Math.floor(options.cutImgHeight / scale)); } else { options.cropViewInitWidth = options.cropViewWidth = options.cutImgWidth; options.cropViewInitHeight = options.cropViewHeight = options.cutImgHeight; } options.cropLeft = parseInt((options.width - options.cropViewWidth) / 2); options.cropTop = parseInt((options.height - options.cropViewHeight) / 2); } function imgCutPreviewWidthAndHeight() { if (options.cropViewHeight > options.cropViewWidth) { options.cropViewWidth = parseInt(Math.floor(options.width * (options.cropViewInitWidth / options.height))); options.cropViewHeight = options.height; } else if (options.cropViewHeight < options.cropViewWidth) { options.cropViewHeight = parseInt(Math.floor(options.height * (options.cropViewInitHeight / options.width))); options.cropViewWidth = options.width; } else { options.cropViewWidth = options.cropViewHeight = options.height; } imgCutPreview.css({ "width" : options.cropViewWidth + "px", "height": options.cropViewHeight + "px" }); } function mainCutterWidthAndHeight() { if (options.cropViewHeight > options.cropViewWidth) { options.cropTop = 0; options.cropLeft = parseInt(Math.floor((options.width - options.cropViewWidth) / 2)); } else if (options.cropViewHeight < options.cropViewWidth) { options.cropLeft = 0; options.cropTop = parseInt(Math.floor((options.height - options.cropViewHeight) / 2)); } else { options.cropLeft = options.cropTop = 0; } cutWrapperNode.css({ "display": "block", "width" : options.cropViewWidth + "px", "height" : options.cropViewHeight + "px", "left" : options.cropLeft + "px", "top" : options.cropTop + "px" }); } function cutBoxWidthAndHeightInit() { var scale = Math.max(options.cutWidth / options.cropViewWidth, options.cutHeight / options.cropViewHeight); if (scale > 1) { options.cutViewWidth = parseInt(Math.floor(options.cutWidth / scale)); options.cutViewHeight = parseInt(Math.floor(options.cutHeight / scale)); } else { options.cutViewHeight = options.cutHeight; options.cutViewWidth = options.cutWidth; } options.cutMaxWidth = options.cutViewWidth; options.cutMaxHeight = options.cutViewHeight; options.cutLeft = parseInt(Math.floor((options.cropViewWidth - options.cutViewWidth)) / 2); options.cutTop = parseInt(Math.floor((options.cropViewHeight - options.cutViewHeight)) / 2); options.cutBoxLimitX1 = 0; options.cutBoxLimitX2 = options.cropViewWidth; options.cutBoxLimitY1 = 0; options.cutBoxLimitY2 = options.cropViewHeight; } function cutBoxWidthAndHeight(move) { if (!move) { if (options.cropViewHeight > options.cropViewWidth) { options.cutLeft = 0; options.cutViewHeight = options.cutViewWidth = options.cropViewWidth; } else if (options.cropViewHeight < options.cropViewWidth) { options.cutTop = 0; options.cutViewWidth = options.cutViewHeight = options.cropViewHeight; } else { options.cutLeft = options.cutTop = 0; options.cutViewWidth = options.cutViewHeight = options.cropViewHeight; } } cutBox.css({ "display": "block", "width" : options.cutViewWidth + "px", "height" : options.cutViewHeight + "px", "left" : options.cutLeft + "px", "top" : options.cutTop + "px" }); } cutWrapperNode.append(imgCutPreview, cutBox); componentNode.append(cutWrapperNode, imgBackground); wrapper.append(componentNode, cropper); processBar.append(processPoint); wrapperFooterRightBox.append(processBar); wrapperFooter.append(spanTitleNode, wrapperFooterRightBox); containerNode.append(wrapper, wrapperFooter); callback(function () { var output = document.createElement("canvas"), scale_x = options.cutImgWidth / options.cropViewWidth, scale_y = options.cutImgHeight / options.cropViewHeight, _o_x = parseInt((scale_x) * options.cutLeft), _o_y = parseInt((scale_y) * options.cutTop), _o_width = parseInt(scale_x * options.cutViewWidth), _o_height = parseInt(scale_y * options.cutViewHeight); output.width = options.cutWidth; output.height = options.cutHeight; output.getContext("2d").drawImage(document.getElementById(imgCutPreview.attr("id")), _o_x, _o_y, _o_width, _o_height, 0, 0, output.width, output.height); return output.toDataURL("image/jpeg"); }, true) }; var cutPhoto_options = { defaults: { width : 300, height : 300, cutWidth : 300, cutHeight : 300, cutMinSize : 50, cropViewWidth : 0, cropViewHeight : 0, cropViewInitWidth : 0, cropViewInitHeight: 0, cropLeft : 0, cropTop : 0, cutViewWidth : 0, cutViewHeight : 0, cutMaxWidth : 0, cutMaxHeight : 0, cutBoxLimitX1 : 0, cutBoxLimitX2 : 0, cutBoxLimitY1 : 0, cutBoxLimitY2 : 0, cutLeft : 0, cutTop : 0, initStatus : false, cutImgWidth : 0, cutImgHeight : 0, cutImgData : "", processBeginX : 0, processBeginY : 0, processEndX : 0, processEndY : 0, processBarWidth : 200, processPointX : 0, processPointY : 0, processPercent : 0, processInitStatus : false } }; $.cutPhoto = cutPhoto; /*$.cutPhoto = function (params) { $.extend(params, $.cutPhoto.prototype.defaults); return new PhotoBrowser(params); }; $.cutPhoto.prototype = { defaults: {} };*/ }(Zepto);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79624.html

相关文章

  • 记录微信程序的坑

    摘要:除官方外的参考文章微信小程序实例创建下发模板消息实例手把手教你开发微信小程序之模版消息开发教你突破小程序模板消息的推送限制获取用户信息接口的废弃问题接口是获取用户信息昵称,头像等的接口,在官方文档上写是即将废弃。 ----------------更新-------------- 2018年10月10日官网3个接口废弃的通知: 1、分享监听接口分享消息给好友时,开发者将无法从callba...

    EastWoodYang 评论0 收藏0
  • 腾讯 AlloyTeam 移动 Web 裁剪组件 AlloyCrop 正式开源

    摘要:兼容性如何支持以及的设备的浏览器便可运行不一一列举一共不到行为什么体积这么小腾讯手内大量的都会去不断地从各个维度进行性能优化。腾讯内部有哪些项目在用目前主要是兴趣部落群等业务在用,刚刚开源出来,只要有裁剪图片的地方都会用到。 传送门 Github地址:https://github.com/AlloyTeam/AlloyFinger/tree/master/alloy_crop 在线De...

    yexiaobai 评论0 收藏0
  • js头像裁剪实现——canvas+Jcrop+jQuery

    摘要:表示的不一定是原生格式的数据。接口基于,继承了的功能并将其扩展使其支持用户系统上的文件。要从其他非对象和数据构造一个,请使用构造函数。要创建包含另一个数据的子集,请使用方法。要获取用户文件系统上的文件对应的对象,请参阅文档。 封好的插件不用写html啦,直接new一个就好了 var test = document.getElementById(test); var clipBox ...

    verano 评论0 收藏0
  • 编写一个头像裁剪组件(一)

    摘要:需求是编写一个头像剪裁工具再封装成为一个组件,然后根据功能开始逐步编写代码先是上传图片预览图片编辑图片。 需求是编写一个头像剪裁工具再封装成为一个组件,然后根据功能开始逐步编写代码:先是上传图片 => 预览图片 => 编辑图片。 刚开始没有去考虑兼容性的问题,直接编写upload部分的代码,参考了很多代码还有HTML5 FILE API之后,发现很少有React编写的这样的代码,因为想...

    whatsns 评论0 收藏0
  • 编写一个头像裁剪组件(一)

    摘要:需求是编写一个头像剪裁工具再封装成为一个组件,然后根据功能开始逐步编写代码先是上传图片预览图片编辑图片。 需求是编写一个头像剪裁工具再封装成为一个组件,然后根据功能开始逐步编写代码:先是上传图片 => 预览图片 => 编辑图片。 刚开始没有去考虑兼容性的问题,直接编写upload部分的代码,参考了很多代码还有HTML5 FILE API之后,发现很少有React编写的这样的代码,因为想...

    haobowd 评论0 收藏0

发表评论

0条评论

chunquedong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<