使用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代码)
Oct 29 Javascript
Jquery 滑入滑出效果实现代码
Mar 27 Javascript
JavaScript实现控制打开文件另存为对话框的方法
Apr 17 Javascript
JavaScript中数据结构与算法(一):栈
Jun 19 Javascript
js实现简单秒表走动的时钟特效
Mar 25 Javascript
jquery siblings获取同辈元素用法实例分析
Jul 25 Javascript
AngularJS教程之简单应用程序示例
Aug 16 Javascript
将JSON字符串转换成Map对象的方法
Nov 30 Javascript
js数字舍入误差以及解决方法(必看篇)
Feb 28 Javascript
Angular2 之 路由与导航详细介绍
May 26 Javascript
Vue条件循环判断+计算属性+绑定样式v-bind的实例
Sep 18 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
Apr 26 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 magic_quotes_gpc的一点认识与分析
2008/08/18 PHP
谈谈php对接芝麻信用踩的坑
2016/12/01 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
jquery中对表单的基本操作代码
2010/07/29 Javascript
jquery中ajax使用error调试错误的方法
2015/02/08 Javascript
JS实现在页面随时自定义背景颜色的方法
2015/02/27 Javascript
jQuery实现html表格动态添加新行的方法
2015/05/28 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖动基本操作
2015/11/30 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
vue axios整合使用全攻略
2018/05/24 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
Fetch超时设置与终止请求详解
2019/05/18 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
2020/06/29 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
2020/05/10 Javascript
[01:09:20]NB vs NAVI Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
[03:55]TI9战队采访——TNC Predator
2019/08/22 DOTA
简单总结Python中序列与字典的相同和不同之处
2016/01/19 Python
Python 文件操作的详解及实例
2017/09/18 Python
python+mongodb数据抓取详细介绍
2017/10/25 Python
python和mysql交互操作实例详解【基于pymysql库】
2019/06/04 Python
Python CVXOPT模块安装及使用解析
2019/08/01 Python
python常用排序算法的实现代码
2019/11/08 Python
Python sep参数使用方法详解
2020/02/12 Python
解决Pycharm 中遇到Unresolved reference 'sklearn'的问题
2020/07/13 Python
CSS3 渐变(Gradients)之CSS3 线性渐变
2016/07/08 HTML / CSS
翻新二手苹果产品的网络领导者:Mac of all Trades
2017/12/19 全球购物
创业计划书模版
2014/02/05 职场文书
幼儿园小班评语
2014/04/18 职场文书
厨师个人自我鉴定范文
2014/04/19 职场文书
社区平安建设汇报材料
2014/08/14 职场文书
我的中国梦演讲稿高中篇
2014/08/19 职场文书
小学教师个人工作总结2015
2015/04/20 职场文书
springboot集成redis存对象乱码的问题及解决
2022/06/16 Java/Android
CSS子盒子水平和垂直居中的五种方法
2022/07/23 HTML / CSS