1. dn_canvas_drawimage.js文件

/**
 *  直角三角形 正弦 sin = (对边/斜边);余弦 cos = (邻边/斜边);余切 tan = (对边/邻边)。
 *  互余是指相加等于90°的两角,互补是指两个角的和为180°
 *
 *  canvas 画布(ctx = Canvas.getContext("2d"))
 *  1.原点:Canvas的左上角(0, 0);x轴正方向向右;y轴的正方向向下。
 *  2.旋转正方向:向右旋转(顺时针旋转);
 *    默认旋转中心:Canvas原点(0, 0)。
 *      Canvas画布坐标系旋转的角度,单位是弧度。此旋转和CSS3的旋转变换不一样,旋转的是坐标系,而非元素。
 *      ctx.translate(x,y)指将畫布原點(或圖像的左上角)移到点(x,y)後,再對對象進行(旋轉等)操作;
 *      坐标系还原到初始原点: ctx.setTransform(1, 0, 0, 1, 0, 0);
 *  3. ctx.drawImage()
 *      ① 在画布上定位图像:ctx.drawImage(img,x,y)
 *      ② 在画布上定位图像,并规定图像的宽度和高度:ctx.drawImage(img,x,y,width,height)
 *      ③ 剪切图像,并在画布上定位被剪切的部分:ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
 *          重点:sx,sy是相对于图片的坐标,即图片左上角为sx,sy的坐标系,而不是画布左上角(0,0)为坐标系
 *      参数            描述
 *      img            规定要使用的图像、画布或视频。
 *      sx            可选。开始剪切的 x 坐标位置。
 *      sy            可选。开始剪切的 y 坐标位置。
 *      swidth        可选。被剪切图像的宽度。
 *      sheight        可选。被剪切图像的高度。
 *      x            在画布上放置图像的 x 坐标位置。
 *      y            在画布上放置图像的 y 坐标位置。
 *      width        可选。要使用的图像的宽度。(伸展或缩小图像)
 *      height        可选。要使用的图像的高度。(伸展或缩小图像)
 *
 *  注意,canvas繪製圖像url時:
 *      1.先以url圖像的原始寬高(圖像真實的寬高, 設置畫布的繪製寬高(canvas->width、height)畫布真實的大小)繪畫在畫布上;
 *            再按照樣式style指定的寬高在頁面(瀏覽器)上顯示(canvas.style --> width、height 画布最终显示的大小)。
 *      2.呈现图像:先在画布上定位图像,再以指定的绘画原點来呈现图像。
 *      3.图像旋转:先在画布上定位图像,然后以指定平移的旋转中心(畫布原點)旋转图像,再将旋转后的图像绘画在指定大小的画布上(画布大小:图像旋转后的新的圖像寬高)。
 *      4.图像剪切:先在画布上定位图像,然后以图像的原始大小,根据传入的x,y,w,h的值来剪切图像,再绘画剪切后的图像。
 *      5.图像旋转剪切:先在画布上定位图像,然后以图像的原始大小,根据传入的x,y,w,h的值来剪切图像,接着旋转图像,再绘画先剪切后旋转过的图像。
 *      6.Url圖像呈現顺序:定位 -> 剪切 -> 再旋轉 -> 最后绘制图像。[ctx.translate(x,y);ctx.rotate(radian);ctx.drawImage(img,sx,sy,sw,sh,x,y,w,h);]
 *      7.若要实现:定位 -> 再旋轉 -> 剪切 -> 最后绘制图像。
 *          需要使用 img.setAttribute("crossOrigin", 'Anonymous');  var imgData = ctx.getImageData(cx, cy, cw, ch); ctx.putImageData(imgData, x, y);
 *          或使用HTML的crossOrigin属性; canvas.toDataURL("image/png");再重新呈现图像。
 *
 *  4. ctx.scale() 图片镜像
 *      scale(1, 1):   默认
 *      scale(-1,1):    水平翻转
 *      scale(1,-1):    垂直翻转
 *      scale(-1,-1):   水平垂直翻转
 *
 *  img HTML标签
 *  1.原点:左上角;x轴正方向向右;y轴的正方向向下,(人的面对屏幕时,以人的方向为基准)。
 *  2.旋转正方向:向右旋转(顺时针旋转)。
 *    默认旋转中心: img圖像的中心。
 *  3.元素控件的Style宽高:需要通过图像最终显示的宽高来推算出,控件的style宽高。
 *  4.元素控件最终显示的宽高与Style的宽高值不同。
 *
 * (HTML 标签 img旋轉:將图像放进控件中,再以旋转中心进行旋转)
**/
function CanvasDrawImage() {
    function el(id) { return document.getElementById(id); };

    var d = this;

    //保留n为小数(四舍五入)
    d.round = function (num, n) { return Number(num.toFixed(n)); };

    //處理角度, 防止輸入大於360或負數的度數
    d.getRotate = function (rotate) {
        rotate = rotate % 360;
        if (rotate < 0)
            rotate = 360 + rotate;

        return rotate;
    };

    //解析最大宽度或高度约束
    d.parseSizeMax = function (w, h, max) {
        var scale = zoom = 1;
        var rw = w, rh = h;

        if (max > 0 && w > 0 && h > 0) {
            //横向及方形
            if (w >= h) {
                if (w > max) {
                    scale = max / w;
                    zoom = w / max;

                    rw = max;
                    rh = d.round((h * scale), 2);

                }
            } else {
                //纵向
                if (h > max) {
                    scale = max / h;
                    zoom = h / max;

                    rw = d.round((w * scale), 2);
                    rh = max;
                }
            }
        }

        return { width: rw, height: rh, scale: scale, zoom: zoom };
    };

    //角度转弧度计算(公式:radian = degree * Math.PI / 180)
    d.calculateRadian = function (rotate) {
        return (rotate * Math.PI / 180);
    };

    //計算旋轉指定角度後,新的圖像寬高及旋轉中心(Cancas畫布)
    d.calculatePointCoordinates = function (rotate, w, h) {
        rotate = d.getRotate(rotate);
        //角度转弧度
        var rotateRadian = d.calculateRadian(rotate);

        var o = {
            DrawX: 0, //(cancas畫布)起始繪畫坐標x
            DrawY: 0, //(cancas畫布)起始繪畫坐標y
            DrawWidth: w, //圖像繪畫寬
            DrawHeight: h, //圖像繪畫高
            Rotate: rotate, //旋轉角度
            Radian: rotateRadian, //旋轉弧度
            RotateWidth: w,   //旋轉後的寬
            RotateHeight: h,  //旋轉後的高
            TransformOrigin: { X: 0, Y: 0 },  //(cancas畫布)旋轉中心平移坐標
            Left: 0,    //(img元素標籤)旋轉後的圖像需左移的距離
            Top: 0,     //(img元素標籤)旋轉後的圖像需下移的距離
            OriginalWidth: w, //原始寬
            OriginalHeight: h //原始高
        };

        if (rotate != 0) {
            //坐標計算參考系:原點(0,0):圖像左上角,x軸正方向:向右,y軸的正方向:向上,旋轉中心:原點
            //圖像沒有作任何旋轉時,圖像四個角的坐標值(左上、右上、右下、左下)
            var ix1 = 0, iy1 = 0;
            var ix2 = w, iy2 = 0;
            var ix3 = w, iy3 = -h;
            var ix4 = 0, iy4 = -h;

            //圖像旋轉一定弧度後,四個角的坐標值(左上、右上、右下、左下)
            var rx1 = d.round((Math.cos(rotateRadian) * ix1 + Math.sin(rotateRadian) * iy1), 2);
            var ry1 = d.round((-Math.sin(rotateRadian) * ix1 + Math.cos(rotateRadian) * iy1), 2);
            var rx2 = d.round((Math.cos(rotateRadian) * ix2 + Math.sin(rotateRadian) * iy2), 2);
            var ry2 = d.round((-Math.sin(rotateRadian) * ix2 + Math.cos(rotateRadian) * iy2), 2);
            var rx3 = d.round((Math.cos(rotateRadian) * ix3 + Math.sin(rotateRadian) * iy3), 2);
            var ry3 = d.round((-Math.sin(rotateRadian) * ix3 + Math.cos(rotateRadian) * iy3), 2);
            var rx4 = d.round((Math.cos(rotateRadian) * ix4 + Math.sin(rotateRadian) * iy4), 2);
            var ry4 = d.round((-Math.sin(rotateRadian) * ix4 + Math.cos(rotateRadian) * iy4), 2);

            //旋轉後的寬、高(用對角坐標求得)
            o.RotateWidth = Math.max(Math.abs(rx1 - rx3), Math.abs(rx2 - rx4));
            o.RotateHeight = Math.max(Math.abs(ry1 - ry3), Math.abs(ry2 - ry4));

            //(cancas畫布)圖像旋轉前,旋轉中心需要平移坐標點
            o.TransformOrigin.X = Math.abs(Math.min(rx1, rx2, rx3, rx4));
            o.TransformOrigin.Y = Math.abs(Math.max(ry1, ry2, ry3, ry4));

            //(img元素標籤)旋轉後的圖像需左移或下移的距離
            o.Left = (o.RotateWidth - o.DrawWidth) / 2;
            o.Top = (o.RotateHeight - o.DrawHeight) / 2;
        }

        return o;
    };

    //从canvas提取图片image(返回的是一串Base64编码的URL,默認格式PNG)
    d.getCanvasToImageUrl = function (objCanvas, exp) {
        if (exp)
            return objCanvas.toDataURL("image/" + exp);
        else
            return objCanvas.toDataURL("image/png");
    };

    /* 以下為呈現圖像處理 */

    d.MaxWH = 650;

    //取圖像對象
    d.getImage = function (imgSrc) {
        var objImg = new Image();
        objImg.src = imgSrc;
        //解决canvas图片getImageData cross-origin跨域问题, Anonymous元素的跨域资源请求不需要凭证标志设置。
        objImg.setAttribute("crossOrigin", 'Anonymous');

        return objImg;
    };

    //設置畫布的寬高
    d.setCanvasSize = function (objCanvas, width, height, styleWidth, styleHeight) {
        //畫布的真實大小,不可見
        objCanvas.width = width;
        objCanvas.height = height;

        //畫布最終顯示的大小;若畫布顯示大小沒有設置,則默認取畫布的真實大小作顯示大小
        if (styleWidth > 0 && styleHeight > 0) {
            objCanvas.style.width = styleWidth + "px";
            objCanvas.style.height = styleHeight + "px";
        }
    };

    //檢驗值是否為“Y”(Yes)
    d.checkValueIsYes = function (val) {
        return val == "Y";
    };

    //取畫布呈現圖像位置信息(計算圖像旋轉後的尺寸位置,並處理剪切图像數據)
    d.getCropPosition = function (oCropInfo) {
        var o = new Object();

        //按比例換算圖像寬高
        //按圖片縮放比例、屏幕縮放比例換算縮略圖原圖大小
        o.Width = Math.ceil(oCropInfo.Width * oCropInfo.Zoom / oCropInfo.Scale);
        o.Height = Math.ceil(oCropInfo.Height * oCropInfo.Zoom / oCropInfo.Scale);

        //按屏幕縮放比例換算PT圖位置及大小
        o.CropX = Math.floor(oCropInfo.X / oCropInfo.Scale);
        o.CropY = Math.floor(oCropInfo.Y / oCropInfo.Scale);
        o.CropWidth = Math.ceil(oCropInfo.CropWidth / oCropInfo.Scale);
        o.CropHeight = Math.ceil(oCropInfo.CropHeight / oCropInfo.Scale);

        return o;
    };

    //清空畫布
    d.clearCanvas = function (objCanvas) {
        if (objCanvas != null) {
            //取畫布的上下文
            var context = objCanvas.getContext("2d");

            if (context != null)
                context.clearRect(0, 0, objCanvas.width, objCanvas.height);
        }
    };

    //canvas繪圖(在画布顯示按指定位置大小顯示圖像,不作旋轉處理)
    d.drawImage = function (objCanvas, imgSrc, showWidth, showHeight, drawX, drawY) {
        if (objCanvas != null) {
            //取畫布的上下文
            var context = objCanvas.getContext("2d");

            if (context != null) {
                //清除上下文
                context.clearRect(0, 0, objCanvas.width, objCanvas.height);
                context.save();

                //取圖像
                var objImg = d.getImage(imgSrc);

                //圖像加載
                objImg.onload = function () {
                    //設置畫布的寬高
                    d.setCanvasSize(objCanvas, objImg.width, objImg.height, showWidth, showHeight);
                    //剪切图像,并在画布上定位被剪切的部分
                    context.drawImage(objImg, drawX, drawY, objCanvas.width, objCanvas.height);
                    context.restore();
                };
            }
        }
    };

    //canvas繪圖(使用过渡画布,旋转 -> 镜像 -> 剪切)
    d.drawImageTransitionCrop = function (objTargetCanvas, imgSrc, cropInfo, oPosition) {
        if (objTargetCanvas != null && cropInfo != null) {
            var objTransCanvas = document.createElement("canvas");
            objTransCanvas.style.display = "none";

            //取畫布的上下文
            var context = objTransCanvas.getContext("2d");

            if (context != null) {
                //取圖像
                var objImg = d.getImage(imgSrc);

                //清除上下文
                context.clearRect(0, 0, objTransCanvas.width, objTransCanvas.height);
                //保存当前的绘图状态
                context.save();

                //圖像加載(先旋转图像再剪切指定位置大小的图像)
                objImg.onload = function () {
                    var drawSize = d.calculatePointCoordinates(cropInfo.ActualRotate, objImg.width, objImg.height);

                    //==========*==========*旋转*==========*==========
                    //設置畫布的寬高
                    d.setCanvasSize(objTransCanvas, drawSize.RotateWidth, drawSize.RotateHeight);
                    //平移畫布原點
                    context.translate(drawSize.TransformOrigin.X, drawSize.TransformOrigin.Y);
                    //旋轉弧度
                    context.rotate(drawSize.Radian);
                    //画图
                    context.drawImage(objImg, drawSize.DrawX, drawSize.DrawY, drawSize.DrawWidth, drawSize.DrawHeight);
                    //坐标系还原到初始比例及原点
                    context.setTransform(1, 0, 0, 1, 0, 0);
                    //保存状态
                    context.save();
                                        
                    //==========*==========*镜像*==========*==========
                    d.drawImageAfterMirror(objTargetCanvas, objTransCanvas, context, cropInfo, oPosition);
                };
            }
        }
    };

    //canvas繪圖(旋转剪切图像后,再水平镜像或垂直镜像)
    d.drawImageAfterMirror = function (objTargetCanvas, objTransCanvas, cxt, cropInfo, oPosition) {
        var w = objTransCanvas.width, h = objTransCanvas.height;

        //在展示的画布上画图
        var drawTargetCanvas = function () {
            var rate, cx, cy, cw, ch;
            //按指定的位置大小截取旋转后的图像的图像数据
            var imgData;

            //==========*==========*剪切經過旋转、鏡像等處理後的畫布图像*==========*==========
            if (oPosition != null && oPosition.Width > 0) {
                rate = oPosition.Width / w;
                cx = Math.floor(oPosition.CropX / rate);
                cy = Math.floor(oPosition.CropY / rate);
                cw = (oPosition.CropWidth / rate);
                ch = (oPosition.CropHeight / rate);
            }
            else {
                rate = 1;
                cx = 0;
                cy = 0;
                cw = w;
                ch = h;
            }

            //按指定的位置大小截取旋转后的图像的图像数据
            imgData = cxt.getImageData(cx, cy, cw, ch);
            //存儲圖像縮放比例
            //objTargetCanvas.setAttribute("zoom", rate);

            //==========*==========*展示 經過旋转、鏡像、剪切的图像*==========*==========
            //展示画布的上下文
            var context = objTargetCanvas.getContext("2d");
            if (context != null) {
                context.clearRect(0, 0, objTargetCanvas.width, objTargetCanvas.height);
                context.save();

                //設置畫布的寬高
                d.setCanvasSize(objTargetCanvas, cw, ch);
                //呈现截取后的图像数据
                //context.putImageData(imgData, 0, 0, 0, 0, cw, ch);
                context.putImageData(imgData, 0, 0);
                //保存绘图状态
                context.save();
            }
        };

        var bFlipH = d.checkValueIsYes(cropInfo.FlipHorizontal);
        var bFlipV = d.checkValueIsYes(cropInfo.FlipVertical);

        if (bFlipH || bFlipV) {
            //从canvas提取图片image
            var canvasImg = d.getCanvasToImageUrl(objTransCanvas);
            //取圖像
            var objImg = d.getImage(canvasImg);

            objImg.onload = function () {
                //清除画布
                cxt.clearRect(0, 0, w, h);

                if (bFlipH && bFlipV) {
                    //平移畫布原點
                    cxt.translate(w, h);
                    //水平垂直翻转
                    cxt.scale(-1, -1);
                }
                else if (bFlipH) {
                    cxt.translate(w, 0);
                    //水平翻转
                    cxt.scale(-1, 1);
                }
                else if (bFlipV) {
                    cxt.translate(0, h);
                    //垂直翻转
                    cxt.scale(1, -1);
                }

                //画图
                cxt.drawImage(objImg, 0, 0, w, h);
                //坐标系还原到初始比例及原点
                cxt.setTransform(1, 0, 0, 1, 0, 0);
                cxt.restore();

                drawTargetCanvas();
            };
        }
        else {
            drawTargetCanvas();
        }
    };

    //canvas繪圖(使用剪切图像數據,旋转、剪切、镜像图像)
    d.drawImageByCropPosition = function (objCanvas, imgSrc, cropInfo) {
        if (objCanvas != null && cropInfo != null) {
            //圖像位置信息
            var oPosition = d.getCropPosition(cropInfo);
            //圖像處理:旋转 -> 镜像 -> 剪切
            d.drawImageTransitionCrop(objCanvas, imgSrc, cropInfo, oPosition);
        }
    };
};

var canDrawImg = new CanvasDrawImage();
 

1. 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <style>
        body {
            background-color: #cfcfcf;
        }
    </style>
    <script type="text/javascript">
        function el(id) { return document.getElementById(id); };

        /**
         *  直角三角形 正弦 sin = (对边/斜边);余弦 cos = (邻边/斜边);余切 tan = (对边/邻边)。
         *
         *  canvas 画布(ctx = Canvas.getContext("2d"))
         *  1.原点:Canvas的左上角(0, 0);x轴正方向向右;y轴的正方向向下。
         *  2.旋转正方向:向右旋转(顺时针旋转); 
         *    默认旋转中心:Canvas原点(0, 0)。
         *      Canvas画布坐标系旋转的角度,单位是弧度。和CSS3的旋转变换不一样,旋转的是坐标系,而非元素。
         *      ctx.translate(x,y)指将畫布原點移到点(x,y)後,再對图像進行操作(如:旋轉);
         *      坐标系还原到初始原点: ctx.setTransform(1, 0, 0, 1, 0, 0);
         *  3.画布大小:最终显示的宽高(可以是图像旋转后的宽高)
         *  5. ctx.drawImage()
         *      ① 在画布上定位图像:ctx.drawImage(img,x,y)
         *      ② 在画布上定位图像,并规定图像的宽度和高度:ctx.drawImage(img,x,y,width,height)
         *      ③ 剪切图像,并在画布上定位被剪切的部分:ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
         *   参数          描述
         *   img          规定要使用的图像、画布或视频。
         *   sx            可选。开始剪切的 x 坐标位置。
         *   sy            可选。开始剪切的 y 坐标位置。
         *   swidth        可选。被剪切图像的宽度。
         *   sheight      可选。被剪切图像的高度。
         *   x             在画布上放置图像的 x 坐标位置。
         *   y             在画布上放置图像的 y 坐标位置。
         *   width         可选。要使用的图像的宽度。(伸展或缩小图像)
         *   height        可选。要使用的图像的高度。(伸展或缩小图像)
         *
         *  HTML 标签 img旋轉:將图像放进控件中,再以旋转中心进行旋转
         *  1.旋转正方向:向右旋转(顺时针旋转)。
         *    默认旋转中心: img圖像的中心。transform-origin:center;transform:rotate(45deg);
         *  2.元素控件最终显示的宽高与设置的img style的宽高可能不同;img.style的宽高是图片的原始宽高。
         *
        **/
        function RotatePhoto() {
            function el(id) { return document.getElementById(id); };
            //保留n位小数(四舍五入)
            function round(num, n) { return Number(num.toFixed(n)); };

            var r = this;

            //處理角度, 防止輸入大於360或負數的度數
            r.getRotate = function (rotate) {
                rotate = rotate % 360;
                if (rotate < 0)
                    rotate = 360 + rotate;

                return rotate;
            };

            //解析最大宽度或高度约束
            r.parseSizeMax = function (w, h, max) {
                var scale = 1;
                var rw = w, rh = h;

                //横向及方形
                if (w >= h) {
                    if (w > max) {
                        scale = w / max;

                        rw = max;
                        rh = (h * scale).toFixed(2);

                    }
                } else {
                    //纵向
                    if (h > max) {
                        scale = h / max;

                        rw = (w * scale).toFixed(2);
                        rh = max;
                    }
                }

                return { width: rw, height: rh, scale: scale };
            };

            //角度转弧度计算(公式:radian = degree * Math.PI / 180)
            r.calculateRotateRadian = function (rotate) {
                return (rotate * Math.PI / 180);
            };

            //計算旋轉指定角度後,新的圖像寬高及旋轉中心(Cancas畫布)
            r.calculatePointCoordinates = function (rotate, w, h) {
                rotate = r.getRotate(rotate);
                //角度转弧度
                var rotateRadian = r.calculateRotateRadian(rotate);

                var o = {
                    DrawX: 0, //(cancas畫布)起始坐標x
                    DrawY: 0, //(cancas畫布)起始坐標y
                    SourceWidth: w, //原始寬
                    SourceHeight: h, //原始高
                    Rotate: rotate, //旋轉角度
                    Radian: rotateRadian, //旋轉弧度
                    Width: w,   //旋轉後的寬
                    Height: h,  //旋轉後的高
                    TransformOrigin: { X: 0, Y: 0 },  //(cancas畫布)旋轉中心平移坐標
                    Left: 0,    //(img元素標籤)旋轉後的圖像需左移的距離
                    Top: 0      //(img元素標籤)旋轉後的圖像需下移的距離
                };

                if (rotate != 0) {
                    //坐標計算參考系:原點(0,0):圖像左上角,x軸正方向:向右,y軸的正方向:向上,旋轉中心:原點
                    //圖像沒有作任何旋轉時,圖像四個角的坐標值(左上、右上、右下、左下)
                    var ix1 = 0, iy1 = 0;
                    var ix2 = w, iy2 = 0;
                    var ix3 = w, iy3 = -h;
                    var ix4 = 0, iy4 = -h;

                    //圖像旋轉一定弧度後,四個角的坐標值(左上、右上、右下、左下)
                    var rx1 = round((Math.cos(rotateRadian) * ix1 + Math.sin(rotateRadian) * iy1), 2);
                    var ry1 = round((-Math.sin(rotateRadian) * ix1 + Math.cos(rotateRadian) * iy1), 2);
                    var rx2 = round((Math.cos(rotateRadian) * ix2 + Math.sin(rotateRadian) * iy2), 2);
                    var ry2 = round((-Math.sin(rotateRadian) * ix2 + Math.cos(rotateRadian) * iy2), 2);
                    var rx3 = round((Math.cos(rotateRadian) * ix3 + Math.sin(rotateRadian) * iy3), 2);
                    var ry3 = round((-Math.sin(rotateRadian) * ix3 + Math.cos(rotateRadian) * iy3), 2);
                    var rx4 = round((Math.cos(rotateRadian) * ix4 + Math.sin(rotateRadian) * iy4), 2);
                    var ry4 = round((-Math.sin(rotateRadian) * ix4 + Math.cos(rotateRadian) * iy4), 2);

                    //旋轉後的寬、高(用對角坐標求得)
                    o.Width = Math.max(Math.abs(rx1 - rx3), Math.abs(rx2 - rx4));
                    o.Height = Math.max(Math.abs(ry1 - ry3), Math.abs(ry2 - ry4));

                    //(cancas畫布)圖像旋轉前,旋轉中心需要平移坐標點
                    o.TransformOrigin.X = Math.abs(Math.min(rx1, rx2, rx3, rx4));
                    o.TransformOrigin.Y = Math.abs(Math.max(ry1, ry2, ry3, ry4));

                    //(img元素標籤)旋轉後的圖像需左移或下移的距離
                    o.Left = (o.Width - o.SourceWidth) / 2;
                    o.Top = (o.Height - o.SourceHeight) / 2;
                }

                return o;
            };

            //HTML 标签 canvas
            r.parseCanvaseRotateSize = function (rotate, w, h, x, y) {
                var o = r.calculatePointCoordinates(rotate, w, h);

                return o;
            };

            //(作參考用) 解析圖片旋轉後的寬高(0,90,180,270)(HTML 标签 img)
            r.parseImgRotateSize = function (rotate, w, h, x, y) {
                rotate = r.parseRotate(rotate);

                var size = new Object();
                /*
                    obj.style.cssText = string.format("width:{0}px;height:{1}px;left:{2}px;top:{3}px;transformOrigin:center;transform:rotate({4}deg);",
                            size.width,size.height,size.x,size.y,size.rotate)
                */

                if (rotate % 180 != 0 && rotate % 90 == 0) {
                    var rx = Math.floor((w - h) / 2);
                    var ry = Math.floor((h - w) / 2);

                    size.width = h;
                    size.height = w;
                    size.x = -(x - rx);
                    size.y = -(y - ry);
                }
                else {
                    size.width = w;
                    size.height = h;
                    size.x = -x;
                    size.y = -y;
                }

                size.rotate = rotate;

                return size;
            };

            //(作參考用) 计算旋转中心 (HTML 标签 canvas)
            r.calculateTransformOrigin = function (rotate, w, h) {
                rotate = r.parseRotate(rotate);
                var ar = rotate % 90;
                var arAngle = (ar * Math.PI / 180);
                var x = y = 0;

                switch (rotate) {
                    case 0: x = y = 0; break;
                    case 90: x = h; y = 0; break;
                    case 180: x = w; y = h; break;
                    case 270: x = 0; y = w; break;
                    default:
                        if (rotate > 0 && rotate < 90) {
                            x = Math.abs(Math.sin(arAngle) * h);
                            y = 0;
                        }
                        else if (rotate > 90 && rotate < 180) {
                            x = Math.abs(Math.cos(arAngle) * h) + Math.abs(Math.sin(arAngle) * w);
                            y = Math.abs(Math.sin(arAngle) * h) || Math.abs(Math.cos(arAngle) * w);
                        }
                        else if (rotate > 180 && rotate < 270) {
                            x = Math.abs(Math.cos(arAngle) * w);
                            y = Math.abs(Math.cos(arAngle) * h + Math.abs(Math.sin(arAngle) * w));
                        }
                        else if (rotate > 270 && rotate < 360) {
                            x = 0;
                            y = Math.abs(Math.cos(arAngle) * w);
                        }
                        break;
                }

                return { x: x, y: y };
            };
        };

        var rPhoto = new RotatePhoto();

        function renderCanvas(rotate) {
            var objCanvas = el("canvasContainer");
            //取畫布的上下文
            var context = objCanvas.getContext("2d");
            if (context != null) {
                var objImg = new Image();
                objImg.src = "../img/5x4.png";

                var imgSourceWidth = 500;
                var imgSourceHeight = 400;
                var size = rPhoto.parseCanvaseRotateSize(rotate, imgSourceWidth, imgSourceHeight);

                objImg.onload = function () {
                    //清除上下文
                    context.clearRect(0, 0, objCanvas.width, objCanvas.height);

                    objCanvas.width = size.Width;
                    objCanvas.height = size.Height;

                    context.translate(size.TransformOrigin.X, size.TransformOrigin.Y);
                    context.rotate(size.Radian);
                    //context.drawImage(objImg, size.DrawX, size.DrawY, size.SourceWidth, size.SourceHeight);
                    var sx = 50
                    var sy = 25
                    var swidth = 450
                    var sheight = 375
                    
                    context.drawImage(objImg, sx, sy, swidth, sheight, size.DrawX, size.DrawY, size.SourceWidth, size.SourceHeight);

                    //坐标系还原到初始原点
                    context.setTransform(1, 0, 0, 1, 0, 0);
                };

                var oImg = el("imgFirst");

                oImg.style.cssText = ""
                                + "margin-left:" + size.Left + "px;"
                                + "margin-top:" + size.Top + "px;"
                                + "transform-origin:center;"
                                + "transform:rotate(" + size.Rotate + "deg);"
            }
        };
    </script>
</head>
<body>
    <div style="float:left; padding: 0 30px;border:0px solid #ff006e;">
        <img id="imgFirst" src="../img/5x4.png" />
    </div>
    <div id="divLayoutBox" style="float:left">
        <canvas id="canvasContainer" width="500" height="500" style="border:1px solid #ff006e;"></canvas>
    </div>
</body>
</html>
View Code

 2. 樣例

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <style>
        body {
            background-color: #cfcfcf;
        }
    </style>
    <script src="dn_canvas_drawimage.js"></script>
    <style>
        body {
            background: #3e3e3e;
        }
        .box {
            position: relative;
            width: auto;
        }
        .source-image {
            display: block;
            margin: auto;
        }
        .crop-box {
            display: none;
            position: absolute;
            top: 0;
            left: 366px;
            height: 293px;
            width: 500px;
            border: 1px solid red;
        }
        canvas{
            background-color: #fff;
        }
    </style>
    <script>
       
        function el(id) { return document.getElementById(id); };

        window.onload = function () {
            var objCanvas = el("canvasImg");
            
            var imageSrc = "./6C5EF58D49C23E4AD4FFAA319629E12A0118C7B9_ed.jpg";
            
            var oCropInfo_1 = { "ID": "1", "Exp": "jpg", "X": 834, "Y": 0, "Width": 1137, "Height": 735, "CropX": 0, "CropY": 0, "CropWidth": 1137, "CropHeight": 666, "CropRotate": 0, "Rotate": 0, "Zoom": 2, "Scale": 2.276, "FlipHorizontal": "N", "FlipVertical": "N", "Sharpen": "N", "Filter": "", "Brightness": 0, "ThumbnailScale": 2.7889, "AllowEdit": "Y", "AllowMove": "Y", "Alpha": 1, "Resolution": 150, "Index": 0, "Quality": "Y", "AutoDirection": "N", "ApplyMask": "N", "IsEmpty": false, "IsUsePhotoEd": true, "ActualRotate": 0, "IsUseImageEd": true };
            var oCropInfo_2 = { "ID": "2", "Exp": "jpg", "X": 799, "Y": 780, "Width": 1137, "Height": 886, "CropX": 0, "CropY": 0, "CropWidth": 1137, "CropHeight": 666, "CropRotate": 0, "Rotate": 15, "Zoom": 2, "Scale": 2.276, "FlipHorizontal": "N", "FlipVertical": "N", "Sharpen": "N", "Filter": "", "Brightness": 0, "ThumbnailScale": 3.1592, "AllowEdit": "Y", "AllowMove": "Y", "Alpha": 1, "Resolution": 150, "Index": 0, "Quality": "Y", "AutoDirection": "N", "ApplyMask": "N", "IsEmpty": false, "IsUsePhotoEd": true, "ActualRotate": 15 };
            var oCropInfo_3 = { "ID": "3", "Exp": "jpg", "X": 0, "Y": 85, "Width": 1137, "Height": 836, "CropX": 0, "CropY": 0, "CropWidth": 1137, "CropHeight": 666, "CropRotate": 0, "Rotate": 0, "Zoom": 1, "Scale": 2.276, "FlipHorizontal": "Y", "FlipVertical": "N", "Sharpen": "N", "Filter": "", "Brightness": 0, "ThumbnailScale": 1.0003, "AllowEdit": "Y", "AllowMove": "Y", "Alpha": 1, "Resolution": 150, "Index": 0, "Quality": "N", "AutoDirection": "N", "ApplyMask": "N", "IsEmpty": false, "IsUsePhotoEd": false, "ActualRotate": 0 };
            var oCropInfo_4 = { "ID": "4", "Exp": "jpg", "X": 117, "Y": 218, "Width": 1137, "Height": 954, "CropX": 0, "CropY": 0, "CropWidth": 1137, "CropHeight": 666, "CropRotate": 0, "Rotate": 15, "Zoom": 1.1557, "Scale": 2.276, "FlipHorizontal": "Y", "FlipVertical": "Y", "Sharpen": "N", "Filter": "#000000", "Brightness": 0, "ThumbnailScale": 1.1557, "AllowEdit": "Y", "AllowMove": "Y", "Alpha": 1, "Resolution": 150, "Index": 0, "Quality": "N", "AutoDirection": "N", "ApplyMask": "N", "IsEmpty": false, "IsUsePhotoEd": false, "ActualRotate": 15 };

            canDrawImg.drawImageByCropPosition(el("canvasImg"), imageSrc, oCropInfo_1);
            canDrawImg.drawImageByCropPosition(el("canvasImg2"), imageSrc, oCropInfo_2);
            canDrawImg.drawImageByCropPosition(el("canvasImg3"), imageSrc, oCropInfo_3);
            canDrawImg.drawImageByCropPosition(el("canvasImg4"), imageSrc, oCropInfo_4);
        };
    </script>
</head>
<body>
    <div class="box">
        <img id="sourceImg" class="source-image" src="./6C5EF58D49C23E4AD4FFAA319629E12A0118C7B9_ed.jpg">
    </div>
    <canvas id="canvasImg"></canvas>
    <canvas id="canvasImg2"></canvas>
    <canvas id="canvasImg3"></canvas>
    <canvas id="canvasImg4"></canvas>
</body>
</html>
View Code

3. 樣例效果

 

posted on 2022-07-11 13:47  欲穷  阅读(419)  评论(0编辑  收藏  举报