使用JavaScript+canvas实现图片裁剪


Posted in Javascript onJanuary 30, 2015

canvas是一个可以让我们使用脚本绘图的标签,它提供了一系列完整的属性和方法。我们可以借此来实现图形绘制,图像处理甚至实现简单的动画和游戏制作。

canvas标签只有两个属性:width和height,用来设定画布的宽和高,如果没有通过标签属性或者脚本来设置,默认为300*150;

好了,canvas的介绍就先到这里,下面我们来看看javascript结合canvas实现图片的裁剪代码:

var selectObj = null;

function ImageCrop(canvasId, imageSource, x, y, width, height) {

    var canvas = $("#" + canvasId);

    if (canvas.length == 0 && imageSource) {

        return;

    }

    function canvasMouseDown(e) {

        StopSelect(e);

        canvas.css("cursor", "default");

    }

    function canvasMouseMove(e) {

        var canvasOffset = canvas.offset();

        var pageX = e.pageX || event.targetTouches[0].pageX;

        var pageY = e.pageY || event.targetTouches[0].pageY;

        iMouseX = Math.floor(pageX - canvasOffset.left);

        iMouseY = Math.floor(pageY - canvasOffset.top);

        canvas.css("cursor", "default");

        if (selectObj.bDragAll) {

            canvas.css("cursor", "move");

            canvas.data("drag", true);

            var cx = iMouseX - selectObj.px;

            cx = cx < 0 ? 0 : cx;

            mx = ctx.canvas.width - selectObj.w;

            cx = cx > mx ? mx : cx;

            selectObj.x = cx;

            var cy = iMouseY - selectObj.py;

            cy = cy < 0 ? 0 : cy;

            my = ctx.canvas.height - selectObj.h;

            cy = cy > my ? my : cy;

            selectObj.y = cy;

        }

        for (var i = 0; i < 4; i++) {

            selectObj.bHow[i] = false;

            selectObj.iCSize[i] = selectObj.csize;

        }

        // hovering over resize cubes

        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&

            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {

            canvas.css("cursor", "pointer");

            selectObj.bHow[0] = true;

            selectObj.iCSize[0] = selectObj.csizeh;

        }

        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&

            iMouseY > selectObj.y - selectObj.csizeh && iMouseY < selectObj.y + selectObj.csizeh) {

            canvas.css("cursor", "pointer");

            selectObj.bHow[1] = true;

            selectObj.iCSize[1] = selectObj.csizeh;

        }

        if (iMouseX > selectObj.x + selectObj.w - selectObj.csizeh && iMouseX < selectObj.x + selectObj.w + selectObj.csizeh &&

            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {

            canvas.css("cursor", "pointer");

            selectObj.bHow[2] = true;

            selectObj.iCSize[2] = selectObj.csizeh;

        }

        if (iMouseX > selectObj.x - selectObj.csizeh && iMouseX < selectObj.x + selectObj.csizeh &&

            iMouseY > selectObj.y + selectObj.h - selectObj.csizeh && iMouseY < selectObj.y + selectObj.h + selectObj.csizeh) {

            canvas.css("cursor", "pointer");

            selectObj.bHow[3] = true;

            selectObj.iCSize[3] = selectObj.csizeh;

        }

        if (iMouseX > selectObj.x && iMouseX < selectObj.x + selectObj.w && iMouseY > selectObj.y && iMouseY < selectObj.y + selectObj.h) {

            canvas.css("cursor", "move");

        }

        // in case of dragging of resize cubes

        var iFW, iFH, iFX, iFY, mx, my;

        if (selectObj.bDrag[0]) {

            iFX = iMouseX - selectObj.px;

            iFY = iMouseY - selectObj.py;

            iFW = selectObj.w + selectObj.x - iFX;

            iFH = selectObj.h + selectObj.y - iFY;

            canvas.data("drag", true);

        }

        if (selectObj.bDrag[1]) {

            iFX = selectObj.x;

            iFY = iMouseY - selectObj.py;

            iFW = iMouseX - selectObj.px - iFX;

            iFH = selectObj.h + selectObj.y - iFY;

            canvas.data("drag", true);

        }

        if (selectObj.bDrag[2]) {

            iFX = selectObj.x;

            iFY = selectObj.y;

            iFW = iMouseX - selectObj.px - iFX;

            iFH = iMouseY - selectObj.py - iFY;

            canvas.data("drag", true);

        }

        if (selectObj.bDrag[3]) {

            iFX = iMouseX - selectObj.px;

            iFY = selectObj.y;

            iFW = selectObj.w + selectObj.x - iFX;

            iFH = iMouseY - selectObj.py - iFY;

            canvas.data("drag", true);

        }

        if (iFW > selectObj.csizeh * 2 && iFH > selectObj.csizeh * 2) {

            selectObj.w = iFW;

            selectObj.h = iFH;

            selectObj.x = iFX;

            selectObj.y = iFY;

        }

        drawScene();

    }

    function canvasMouseOut() {

        $(canvas).trigger("mouseup");

    }

    function canvasMouseUp() {

        selectObj.bDragAll = false;

        for (var i = 0; i < 4; i++) {

            selectObj.bDrag[i] = false;

        }

        canvas.css("cursor", "default");

        canvas.data("select", {

            x: selectObj.x,

            y: selectObj.y,

            w: selectObj.w,

            h: selectObj.h

        });

        selectObj.px = 0;

        selectObj.py = 0;

    }

    function Selection(x, y, w, h) {

        this.x = x; // initial positions

        this.y = y;

        this.w = w; // and size

        this.h = h;

        this.px = x; // extra variables to dragging calculations

        this.py = y;

        this.csize = 4; // resize cubes size

        this.csizeh = 6; // resize cubes size (on hover)

        this.bHow = [false, false, false, false]; // hover statuses

        this.iCSize = [this.csize, this.csize, this.csize, this.csize]; // resize cubes sizes

        this.bDrag = [false, false, false, false]; // drag statuses

        this.bDragAll = false; // drag whole selection

    }

    Selection.prototype.draw = function () {

        ctx.strokeStyle = '#666';

        ctx.lineWidth = 2;

        ctx.strokeRect(this.x, this.y, this.w, this.h);

        // draw part of original image

        if (this.w > 0 && this.h > 0) {

            ctx.drawImage(image, this.x, this.y, this.w, this.h, this.x, this.y, this.w, this.h);

        }

        // draw resize cubes

        ctx.fillStyle = '#999';

        ctx.fillRect(this.x - this.iCSize[0], this.y - this.iCSize[0], this.iCSize[0] * 2, this.iCSize[0] * 2);

        ctx.fillRect(this.x + this.w - this.iCSize[1], this.y - this.iCSize[1], this.iCSize[1] * 2, this.iCSize[1] * 2);

        ctx.fillRect(this.x + this.w - this.iCSize[2], this.y + this.h - this.iCSize[2], this.iCSize[2] * 2, this.iCSize[2] * 2);

        ctx.fillRect(this.x - this.iCSize[3], this.y + this.h - this.iCSize[3], this.iCSize[3] * 2, this.iCSize[3] * 2);

    };

    var drawScene = function () {

        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear canvas

        // draw source image

        ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);

        // and make it darker

        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

        ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

        // draw selection

        selectObj.draw();

        canvas.mousedown(canvasMouseDown);

        canvas.on("touchstart", canvasMouseDown);

    };

    var createSelection = function (x, y, width, height) {

        var content = $("#imagePreview");

        x = x || Math.ceil((content.width() - width) / 2);

        y = y || Math.ceil((content.height() - height) / 2);

        return new Selection(x, y, width, height);

    };

    var ctx = canvas[0].getContext("2d");

    var iMouseX = 1;

    var iMouseY = 1;

    var image = new Image();

    image.onload = function () {

        selectObj = createSelection(x, y, width, height);

        canvas.data("select", {

            x: selectObj.x,

            y: selectObj.y,

            w: selectObj.w,

            h: selectObj.h

        });

        drawScene();

    };

    image.src = imageSource;

    canvas.mousemove(canvasMouseMove);

    canvas.on("touchmove", canvasMouseMove);

    var StopSelect = function (e) {

        var canvasOffset = $(canvas).offset();

        var pageX = e.pageX || event.targetTouches[0].pageX;

        var pageY = e.pageY || event.targetTouches[0].pageY;

        iMouseX = Math.floor(pageX - canvasOffset.left);

        iMouseY = Math.floor(pageY - canvasOffset.top);

        selectObj.px = iMouseX - selectObj.x;

        selectObj.py = iMouseY - selectObj.y;

        if (selectObj.bHow[0]) {

            selectObj.px = iMouseX - selectObj.x;

            selectObj.py = iMouseY - selectObj.y;

        }

        if (selectObj.bHow[1]) {

            selectObj.px = iMouseX - selectObj.x - selectObj.w;

            selectObj.py = iMouseY - selectObj.y;

        }

        if (selectObj.bHow[2]) {

            selectObj.px = iMouseX - selectObj.x - selectObj.w;

            selectObj.py = iMouseY - selectObj.y - selectObj.h;

        }

        if (selectObj.bHow[3]) {

            selectObj.px = iMouseX - selectObj.x;

            selectObj.py = iMouseY - selectObj.y - selectObj.h;

        }

        if (iMouseX > selectObj.x + selectObj.csizeh &&

            iMouseX < selectObj.x + selectObj.w - selectObj.csizeh &&

            iMouseY > selectObj.y + selectObj.csizeh &&

            iMouseY < selectObj.y + selectObj.h - selectObj.csizeh) {

            selectObj.bDragAll = true;

        }

        for (var i = 0; i < 4; i++) {

            if (selectObj.bHow[i]) {

                selectObj.bDrag[i] = true;

            }

        }

    };

    canvas.mouseout(canvasMouseOut);

    canvas.mouseup(canvasMouseUp);

    canvas.on("touchend", canvasMouseUp);

    this.getImageData = function (previewID) {

        var tmpCanvas = $("<canvas></canvas>")[0];

        var tmpCtx = tmpCanvas.getContext("2d");

        if (tmpCanvas && selectObj) {

            tmpCanvas.width = selectObj.w;

            tmpCanvas.height = selectObj.h;

            tmpCtx.drawImage(image, selectObj.x, selectObj.y, selectObj.w, selectObj.h, 0, 0, selectObj.w, selectObj.h);

            if (document.getElementById(previewID)) {

                document.getElementById(previewID).src = tmpCanvas.toDataURL();

                document.getElementById(previewID).style.border = "1px solid #ccc";

            }

            return tmpCanvas.toDataURL();

        }

    };

}

function autoResizeImage(maxWidth, maxHeight, objImg) {

    var img = new Image();

    img.src = objImg.src;

    var hRatio;

    var wRatio;

    var ratio = 1;

    var w = objImg.width;

    var h = objImg.height;

    wRatio = maxWidth / w;

    hRatio = maxHeight / h;

    if (w < maxWidth && h < maxHeight) {

        return;

    }

    if (maxWidth == 0 && maxHeight == 0) {

        ratio = 1;

    } else if (maxWidth == 0) {

        if (hRatio < 1) {

            ratio = hRatio;

        }

    } else if (maxHeight == 0) {

        if (wRatio < 1) {

            ratio = wRatio;

        }

    } else if (wRatio < 1 || hRatio < 1) {

        ratio = (wRatio <= hRatio ? wRatio : hRatio);

    } else {

        ratio = (wRatio <= hRatio ? wRatio : hRatio) - Math.floor(wRatio <= hRatio ? wRatio : hRatio);

    }

    if (ratio < 1) {

        if (ratio < 0.5 && w < maxWidth && h < maxHeight) {

            ratio = 1 - ratio;

        }

        w = w * ratio;

        h = h * ratio;

    }

    objImg.height = h;

    objImg.width = w;

}

小伙伴们拿去试试吧,希望大家能够喜欢,有疑问就给我留言吧。

Javascript 相关文章推荐
javascript解析json数据的3种方式
May 08 Javascript
js用typeof方法判断undefined类型
Jul 15 Javascript
Javascript 绘制 sin 曲线过程附图
Aug 21 Javascript
利用jQuery实现漂亮的圆形进度条倒计时插件
Sep 30 Javascript
浅谈jQuery效果函数
Sep 16 Javascript
利用jquery禁止外层滚动条的滚动
Jan 05 Javascript
switchery按钮的使用方法
Dec 18 Javascript
JavaScript实现身份证验证代码实例
Aug 26 Javascript
微信小程序 scroll-view的使用案例代码详解
Jun 11 Javascript
如何使用JavaScript实现无缝滚动自动播放轮播图效果
Aug 20 Javascript
基于openlayers实现角度测量功能
Sep 28 Javascript
JavaScript Html实现移动端红包雨功能页面
Jan 10 Javascript
js判断手机和pc端选择不同执行事件的方法
Jan 30 #Javascript
项目中常用的JS方法整理
Jan 30 #Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 #Javascript
jquery实现拖拽调整Div大小
Jan 30 #Javascript
jQuery中$.click()无效问题分析
Jan 29 #Javascript
Eclipse配置Javascript开发环境图文教程
Jan 29 #Javascript
js操作滚动条事件实例
Jan 29 #Javascript
You might like
FCKeditor添加自定义按钮
2008/03/27 PHP
php单件模式结合命令链模式使用说明
2008/09/07 PHP
用php实现的下载css文件中的图片的代码
2010/02/08 PHP
PHP连接SQLServer2005 的问题解决方法
2010/07/19 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
js 跨域和ajax 跨域问题小结
2009/07/01 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
使用VS开发 Node.js指南
2015/01/06 Javascript
js简单实现点击左右运动的方法
2015/04/10 Javascript
js实现无缝滚动图(可控制当前滚动的方向)
2017/02/22 Javascript
d3.js实现立体柱图的方法详解
2017/04/28 Javascript
JavaScript实现QQ聊天消息展示和评论提交功能
2017/05/22 Javascript
angularJS模态框$modal实例代码
2017/05/27 Javascript
解决ztree搜索中多级菜单展示不全问题
2017/07/05 Javascript
原生js封装添加class,删除class的实例
2017/11/06 Javascript
TypeScript中的方法重载详解
2019/04/12 Javascript
JS document内容及样式操作完整示例
2020/01/14 Javascript
vue 全局封装loading加载教程(全局监听)
2020/11/05 Javascript
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
python 根据pid杀死相应进程的方法
2017/01/16 Python
Python使用pyh生成HTML文档的方法示例
2018/03/10 Python
Python 3.6 -win64环境安装PIL模块的教程
2019/06/20 Python
django实现类似触发器的功能
2019/11/15 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
HTML5 中新的全局属性(整理)
2013/07/31 HTML / CSS
NBA德国官方网上商店:NBA Store德国
2018/04/13 全球购物
TripAdvisor日本:全球领先的旅游网站
2019/02/14 全球购物
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
幼儿园课题方案
2014/06/09 职场文书
2015年禁毒工作总结
2015/04/30 职场文书
家长会后的感想
2015/08/11 职场文书
2016优秀毕业生个人事迹材料
2016/02/29 职场文书
Nginx开启Brotli压缩算法实现过程详解
2021/03/31 Servers
Python还能这么玩之用Python做个小游戏的外挂
2021/06/04 Python
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python
实现AJAX异步调用和局部刷新的基本步骤
2022/03/17 Javascript