使用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 判断判断某个对象是Object还是一个Array
Jan 28 Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
Sep 27 Javascript
JSON无限折叠菜单编写实例
Dec 16 Javascript
javascript计算当月剩余天数(天数计算器)示例代码
Jan 09 Javascript
一个不错的字符串转码解码函数(自写)
Jul 31 Javascript
js闭包的用途详解
Nov 09 Javascript
JavaScript中的Math.LN2属性用法详解
Jun 12 Javascript
JS实现title标题栏文字不间断滚动显示效果
Sep 07 Javascript
easyui messager alert 三秒后自动关闭提示的实例
Nov 07 Javascript
Vue 中 template 有且只能一个 root的原因解析(源码分析)
Apr 11 Javascript
vue实现前端列表多条件筛选
Oct 26 Javascript
浅谈vue.watch的触发条件是什么
Nov 07 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 中文字符串首字母的获取函数分享
2013/11/04 PHP
CI框架给视图添加动态数据
2014/12/01 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
PHP会话操作之cookie用法分析
2016/09/28 PHP
PHP与服务器文件系统的简单交互
2016/10/21 PHP
PHP使用PDO访问oracle数据库的步骤详解
2017/09/29 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
Javascript 刷新全集常用代码
2009/11/22 Javascript
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
JavaScript中使用sencha gridpanel 编辑单元格、改变单元格颜色
2015/11/26 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
jQuery实现切换隐藏与显示同时切换图标功能
2017/10/29 jQuery
vue自定义指令directive实例详解
2018/01/17 Javascript
vue-自定义组件传值的实例讲解
2018/09/18 Javascript
vue axios 简单封装以及思考
2018/10/09 Javascript
vue2.0实现的tab标签切换效果(内容可自定义)示例
2019/02/11 Javascript
微信小程序之几种常见的弹框提示信息实现详解
2019/07/11 Javascript
微信小程序官方动态自定义底部tabBar的例子
2019/09/04 Javascript
Python实现的下载8000首儿歌的代码分享
2014/11/21 Python
Python socket编程实例详解
2015/05/27 Python
在pytorch中查看可训练参数的例子
2019/08/18 Python
用Python将Excel数据导入到SQL Server的例子
2019/08/24 Python
Python lambda表达式filter、map、reduce函数用法解析
2019/09/11 Python
基于python读取.mat文件并取出信息
2019/12/16 Python
20行代码教你用python给证件照换底色的方法示例
2021/02/05 Python
农田水利实习自我鉴定
2013/09/19 职场文书
大学生求职自我评价
2014/01/16 职场文书
酒店总经理助理职责
2014/02/12 职场文书
2014年入党积极分子党校培训心得体会
2014/07/08 职场文书
餐厅周年庆活动方案
2014/08/25 职场文书
先进个人材料怎么写
2014/12/30 职场文书
委托书格式范文
2015/01/28 职场文书
2015年勤工助学工作总结
2015/04/29 职场文书
2019各种承诺书范文
2019/06/24 职场文书