使用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 相关文章推荐
jquery的ajax请求全面了解
Mar 20 Javascript
浅析Cookie中的Path与domain
Dec 18 Javascript
jquery attr方法获取input的checked属性问题
May 26 Javascript
JavaScript中setter和getter方法介绍
Jul 11 Javascript
微信小程序 简单DEMO布局,逻辑,样式的练习
Nov 30 Javascript
JS实现的随机排序功能算法示例
Jun 09 Javascript
详解基于vue-router的动态权限控制实现方案
Sep 28 Javascript
js保留两位小数方法总结
Jan 31 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
Layui表格监听行单双击事件讲解
Nov 14 Javascript
JavaScript array常用方法代码实例详解
Sep 02 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
Sep 11 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
PHP 中的批处理的实现
2007/06/14 PHP
php以post形式发送xml的方法
2014/11/04 PHP
php通过strpos查找字符串出现位置的方法
2015/03/17 PHP
几行代码轻松实现PHP文件打包下载zip
2017/03/01 PHP
PHP面向对象五大原则之接口隔离原则(ISP)详解
2018/04/04 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
JavaScript 字符串与数组转换函数[不用split与join]
2009/12/13 Javascript
javascript倒计时功能实现代码
2012/06/07 Javascript
纯js简单日历实现代码
2013/10/05 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
js实现简单的可切换选项卡效果
2015/04/10 Javascript
jQuery实现仿Google首页拖动效果的方法
2015/05/04 Javascript
javascript html5摇一摇功能的实现
2016/04/19 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
Angularjs 双向绑定时字符串的转换成数字类型的问题
2017/06/12 Javascript
angularjs2 ng2 密码隐藏显示的实例代码
2017/08/01 Javascript
node.js文件上传重命名以及移动位置的示例代码
2018/01/19 Javascript
微信小程序可滑动周日历组件使用详解
2019/10/21 Javascript
Python多线程编程(三):threading.Thread类的重要函数和方法
2015/04/05 Python
Django返回json数据用法示例
2016/09/18 Python
python导入时小括号大作用
2017/01/10 Python
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
Python+OpenCV实现车牌字符分割和识别
2018/03/31 Python
Pytorch 实现冻结指定卷积层的参数
2020/01/06 Python
TensorFlow:将ckpt文件固化成pb文件教程
2020/02/11 Python
Python如何脚本过滤文件中的注释
2020/05/27 Python
python 多线程中join()的作用
2020/10/29 Python
Python经纬度坐标转换为距离及角度的实现
2020/11/01 Python
鱼油专家:Omegavia
2016/10/10 全球购物
程序员机试试题汇总
2012/03/07 面试题
机械绘图员岗位职责
2013/11/19 职场文书
商场父亲节活动方案
2014/08/27 职场文书
入股合作协议书
2014/10/12 职场文书
忠犬八公的故事观后感
2015/06/05 职场文书
导游词之西安骊山
2019/12/03 职场文书
angular4实现带搜索的下拉框
2022/03/25 Javascript