Javascript 如何在HTML5画布中存储缩放图像

Javascript 如何在HTML5画布中存储缩放图像,javascript,html,cordova,canvas,Javascript,Html,Cordova,Canvas,我正在创建一个绘图应用程序,在那里我可以选择放大/缩小使用drawImage()方法绘制的画布图像,在缩放图像后,我尝试使用toDataUrl()方法保存图像,但在将缩放图像的宽度和高度指定给画布后,它将显示空白页。 下面的代码是保存放大后的图像 destinationCanvas.width = 500; // actual size given with integer values destinationCanvas.height = 500; destinat

我正在创建一个绘图应用程序,在那里我可以选择放大/缩小使用drawImage()方法绘制的画布图像,在缩放图像后,我尝试使用toDataUrl()方法保存图像,但在将缩放图像的宽度和高度指定给画布后,它将显示空白页。 下面的代码是保存放大后的图像

destinationCanvas.width = 500;              // actual size given with integer values
destinationCanvas.height = 500;
 destinationCanvas.style.width = '500px';     // show at 50% on screen
destinationCanvas.style.height = '500px';

 var destinationCanvasURL = destinationCanvas.toDataURL();  
 console.log("markerNormalStyleChange() destinationCanvasURL - "+destinationCanvasURL);

function drawImage(_onScreenMarkingImagePath) {
 var canvas = document.getElementById('drawOnScreen');
 var ctx = canvas.getContext("2d");
 var imageObject = new Image();
 var div = $('#drawOnScreenContext'),
 w = $(window).width() - 1,
 h = $(window).height() - 150;

 canvas.width = w;  
 canvas.height = h ;  

$(imageObject).load(function () {
    ctx.drawImage(imageObject, 0, 0, w,h);

});

}
下面的代码用于绘制和缩放图像,在画布上绘制后,如果我尝试缩放,则绘制的内容将被删除,因为它仅用于绘制图像,因此对于缩放,我还希望缩放绘制的内容

var requestID;
(function() {
var root = this; //global object

var ImgTouchCanvas = function(options) {
    if( !options || !options.canvas || !options.path) {
        throw 'ImgZoom constructor: missing arguments canvas or path';
    }

    this.canvas         = options.canvas;
    this.canvas.width   = this.canvas.clientWidth;
    this.canvas.height  = this.canvas.clientHeight;
    this.context        = this.canvas.getContext('2d');

    console.log("ImgTouchCanvas() initiated this.canvas.width - "+this.canvas.width);
    console.log("ImgTouchCanvas() initiated this.canvas.height - "+this.canvas.height);

    this.desktop = options.desktop || false; //non touch events

    this.position = {
        x: 0,
        y: 0
    };
    this.scale = {
        x: 0.5,
        y: 0.5
    };
    this.imgTexture = new Image();
    this.imgTexture.src = options.path;

    this.lastZoomScale = null;
    this.lastX = null;
    this.lastY = null;

    this.init = false;
    this.checkRequestAnimationFrame();
    requestID = requestAnimationFrame(this.animate.bind(this));

    this.setEventListeners();
};


ImgTouchCanvas.prototype = {
    animate: function() {
        console.log("ImgTouchCanvas requestAnimationFrame()");
        //set scale such as image cover all the canvas
        if(!this.init) {
            if(this.imgTexture.width) {
                var scaleRatio = null;
                if(this.canvas.clientWidth > this.canvas.clientHeight) {
                    scaleRatio = this.canvas.clientWidth / this.imgTexture.width;
                }
                else {
                    scaleRatio = this.canvas.clientHeight / this.imgTexture.height;
                }

                this.scale.x = scaleRatio;  
                this.scale.y = scaleRatio;
                this.init = true;
            }
        }

        //this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);

        //canvas.width = w;    
        //canvas.height = h ;  
        /*this.canvas.width   = zoomWidth;
        this.canvas.height  = zoomHeight;*/

        this.context.drawImage(
            this.imgTexture, 
            this.position.x, this.position.y, 
            this.scale.x * this.imgTexture.width, 
            this.scale.y * this.imgTexture.height);



        console.log("this.scale.x * this.imgTexture.width -- "+this.scale.x * this.imgTexture.width);
        console.log("this.scale.y * this.imgTexture.height -- "+this.scale.y * this.imgTexture.height);

        mWidth = this.scale.x * this.imgTexture.width;
        mHeight = this.scale.y * this.imgTexture.height;

        console.log("mWidth  -- "+mWidth);
        console.log("mHeight  -- "+mHeight);

        //if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
            //requestAnimationFrame(this.animate.bind(this));
        //}else{
            //cancelAnimationFrame(this.animate.bind(this));
        //}  

    },


    gesturePinchZoom: function(event) {
        var zoom = false;

        if( event.targetTouches.length >= 2 ) {
            var p1 = event.targetTouches[0];
            var p2 = event.targetTouches[1];
            var zoomScale = Math.sqrt(Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)); //euclidian distance

            if( this.lastZoomScale ) {
                zoom = zoomScale - this.lastZoomScale;
            }

            this.lastZoomScale = zoomScale;
        }    

        return zoom;
    },

    doZoom: function(zoom) {
        if(!zoom) return;

        //new scale
        var currentScale = this.scale.x;
        var newScale = this.scale.x + zoom/100;


        //some helpers
        var deltaScale = newScale - currentScale;
        var currentWidth    = (this.imgTexture.width * this.scale.x);
        var currentHeight   = (this.imgTexture.height * this.scale.y);
        var deltaWidth  = this.imgTexture.width*deltaScale;
        var deltaHeight = this.imgTexture.height*deltaScale;


        //by default scale doesnt change position and only add/remove pixel to right and bottom
        //so we must move the image to the left to keep the image centered
        //ex: coefX and coefY = 0.5 when image is centered <=> move image to the left 0.5x pixels added to the right
        var canvasmiddleX = this.canvas.clientWidth / 2;
        var canvasmiddleY = this.canvas.clientHeight / 2;
        var xonmap = (-this.position.x) + canvasmiddleX;
        var yonmap = (-this.position.y) + canvasmiddleY;
        var coefX = -xonmap / (currentWidth);
        var coefY = -yonmap / (currentHeight);
        var newPosX = this.position.x + deltaWidth*coefX;
        var newPosY = this.position.y + deltaHeight*coefY;

        //edges cases
        var newWidth = currentWidth + deltaWidth;
        var newHeight = currentHeight + deltaHeight;
        zoomWidth = newWidth;
        zoomHeight = newHeight;
        //console.log("doZoom() newWidth -- "+newWidth);
        //console.log("doZoom() newHeight -- "+newHeight);


        if( newWidth < this.canvas.clientWidth ) return;
        if( newPosX > 0 ) { newPosX = 0; }
        if( newPosX + newWidth < this.canvas.clientWidth ) { newPosX = this.canvas.clientWidth - newWidth;}

        if( newHeight < this.canvas.clientHeight ) return;
        if( newPosY > 0 ) { newPosY = 0; }
        if( newPosY + newHeight < this.canvas.clientHeight ) { newPosY = this.canvas.clientHeight - newHeight; }


        //finally affectations
        this.scale.x    = newScale;
        this.scale.y    = newScale;
        this.position.x = newPosX;
        this.position.y = newPosY;
    },  

    doMove: function(relativeX, relativeY) {
        if(this.lastX && this.lastY) {
          var deltaX = relativeX - this.lastX;
          var deltaY = relativeY - this.lastY;
          var currentWidth = (this.imgTexture.width * this.scale.x);
          var currentHeight = (this.imgTexture.height * this.scale.y);

          //console.log("doZoom() currentWidth -- "+currentWidth);
          //console.log("doZoom() currentHeight -- "+currentHeight);

          this.position.x += deltaX;
          this.position.y += deltaY;


          //edge cases
          if( this.position.x > 0 ) {
            this.position.x = 0;
          }
          else if( this.position.x + currentWidth < this.canvas.clientWidth ) {
            this.position.x = this.canvas.clientWidth - currentWidth;
          }
          if( this.position.y > 0 ) {
            this.position.y = 0;
          }
          else if( this.position.y + currentHeight < this.canvas.clientHeight ) {
            this.position.y = this.canvas.clientHeight - currentHeight;
          }
        }

        this.lastX = relativeX;
        this.lastY = relativeY;
    },

    Draw222: function(x, y, isDown) {
        //console.log("Draw222() -- "+isDown);
         if (isDown) {  
             this.context.beginPath();
             this.context.strokeStyle="#FF0000";
             this.context.lineWidth = 5;
             this.context.lineJoin = "round";
             this.context.moveTo(lx, ly);
             this.context.lineTo(x, y);
             this.context.closePath();
             this.context.stroke();
            }
            lx = x; ly = y;
    },

    setEventListeners: function() {
        // touch
        this.canvas.addEventListener('touchstart', function(e) {
            this.lastX          = null;
            this.lastY          = null;
            this.lastZoomScale  = null;
            //newCtx = this.canvas.getContext("2d");
            var relativeX = e.targetTouches[0].pageX - this.canvas.getBoundingClientRect().left;
            var relativeY = e.targetTouches[0].pageY - this.canvas.getBoundingClientRect().top;    

            if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
                //requestAnimationFrame(this.animate.bind(this));
            }else{
                $( '#undoIcon' ).css({
                    opacity: 1,
                    pointerEvents: 'auto'
                });

                cancelAnimationFrame(this.animate.bind(this));
                canvasPressed = true;
                this.Draw222(parseInt(relativeX), parseInt(relativeY), false);
            } 

        }.bind(this));

        this.canvas.addEventListener('touchmove', function(e) {
            e.preventDefault();

            if(e.targetTouches.length == 2 && $('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) { //pinch
                console.log("pinch zoom")  
                requestID = requestAnimationFrame(this.animate.bind(this));
                this.doZoom(this.gesturePinchZoom(e));
            }
            else {
                //console.log("touchmove  --- 1")
                var relativeX = e.targetTouches[0].pageX - this.canvas.getBoundingClientRect().left;
                var relativeY = e.targetTouches[0].pageY - this.canvas.getBoundingClientRect().top;                

                if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
                    //console.log("hasClass  btnIconHighLight --- ");

                    requestID = requestAnimationFrame(this.animate.bind(this));
                    this.doMove(relativeX, relativeY);
                }else{
                    //console.log("touchmove  --- canvasPressed -- "+canvasPressed)
                    if (canvasPressed) {
                        cancelAnimationFrame(this.animate.bind(this));
                        this.Draw222(parseInt(relativeX), parseInt(relativeY), true);
                    }
                } 
            }
        }.bind(this));

        this.canvas.addEventListener('touchend', function(e) {
            e.preventDefault();
            //cPush();
            canvasPressed = false;

            /*var base64String = null;

            var canvas = document.getElementById('drawOnScreen');
            var context = canvas.getContext('2d');
            // save canvas image as data url (png format by default)
            var dataURL = canvas.toDataURL();
            console.log("dataURL - "+dataURL);*/
            //base64ByteString = dataURL;
            //dataURL = dataURL.substr(dataURL.lastIndexOf(',') + 1);

        }.bind(this));
    },

    checkRequestAnimationFrame: function() {
        var lastTime = 0;
        var vendors = ['ms', 'moz', 'webkit', 'o'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame = 
              window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
        }

        if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
                  timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };
        }

        if (!window.cancelAnimationFrame) {
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
        }
    }
};

root.ImgTouchCanvas = ImgTouchCanvas;
}).call(this);
var请求id;
(功能(){
var root=this;//全局对象
var ImgTouchCanvas=函数(选项){
如果(!options | | |!options.canvas | |!options.path){
抛出“ImgZoom构造函数:缺少参数画布或路径”;
}
this.canvas=options.canvas;
this.canvas.width=this.canvas.clientWidth;
this.canvas.height=this.canvas.clientHeight;
this.context=this.canvas.getContext('2d');
log(“ImgTouchCanvas()启动this.canvas.width-”+this.canvas.width);
log(“ImgTouchCanvas()启动this.canvas.height-”+this.canvas.height);
this.desktop=options.desktop | | false;//非触摸事件
此位置={
x:0,,
y:0
};
这个比例={
x:0.5,
y:0.5
};
this.imgTexture=新图像();
this.imgTexture.src=options.path;
this.lastZoomScale=null;
this.lastX=null;
this.lastY=null;
this.init=false;
这个.checkRequestAnimationFrame();
requestID=requestAnimationFrame(this.animate.bind(this));
this.setEventListeners();
};
ImgTouchCanvas.prototype={
设置动画:函数(){
log(“ImgTouchCanvas requestAnimationFrame()”;
//设置比例,如图像覆盖整个画布
if(!this.init){
if(this.imgTexture.width){
var scaleRatio=null;
if(this.canvas.clientWidth>this.canvas.clientHeight){
scaleRatio=this.canvas.clientWidth/this.imgTexture.width;
}
否则{
scaleRatio=this.canvas.clientHeight/this.imgTexture.height;
}
这个.scale.x=scaleRatio;
这个.scale.y=scaleRatio;
this.init=true;
}
}
//this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
//画布宽度=w;
//canvas.height=h;
/*this.canvas.width=zoomWidth;
this.canvas.height=缩放高度*/
this.context.drawImage(
这个.imgTexture,
这个位置x,这个位置y,
this.scale.x*this.imgTexture.width,
这个.scale.y*这个.imgTexture.height);
log(“this.scale.x*this.imgTexture.width--”+this.scale.x*this.imgTexture.width);
log(“this.scale.y*this.imgTexture.height--”+this.scale.y*this.imgTexture.height);
mWidth=this.scale.x*this.imgTexture.width;
mHeight=this.scale.y*this.imgTexture.height;
log(“mWidth--”+mWidth);
log(“mHeight--”+mHeight);
//if($('pinchZoomInZoomOut').find('pinchZoomInZoomOutBg').hasClass('btnIconHighLight')){
//requestAnimationFrame(this.animate.bind(this));
//}否则{
//cancelAnimationFrame(this.animate.bind(this));
//}  
},
gesturePinchZoom:功能(事件){
var zoom=false;
如果(event.targetTouches.length>=2){
var p1=事件.targetTouches[0];
var p2=event.targetTouches[1];
var zoomScale=Math.sqrt(Math.pow(p2.pageX-p1.pageX,2)+Math.pow(p2.pageY-p1.pageY,2));//欧几里德距离
如果(this.lastZoomScale){
zoom=zoomScale-this.lastZoomScale;
}
this.lastZoomScale=zoomScale;
}    
返回缩放;
},
doZoom:功能(缩放){
如果(!缩放)返回;
//新尺度
var currentScale=此.scale.x;
var newScale=this.scale.x+zoom/100;
//一些助手
var deltaScale=新尺度-当前尺度;
var currentWidth=(this.imgTexture.width*this.scale.x);
var currentHeight=(this.imgTexture.height*this.scale.y);
var deltaWidth=this.imgTexture.width*deltaScale;
var deltahheight=this.imgTexture.height*deltaScale;
//默认情况下,缩放不改变位置,只在右侧和底部添加/删除像素
//因此,我们必须将图像向左移动,以保持图像居中
//例如:coefX和coefY=0.5当图像居中时,将图像向左移动0.5x像素并添加到右侧
var canvasmidlex=this.canvas.clientWidth/2;
var canvasmiddleY=this.canvas.clientHeight/2;
var xonmap=(-this.position.x)+canvasmidlex;
var yonmap=(-this.position.y)+canvasmidley;
var coefX=-xonmap/(当前宽度);
var coefY=-yonmap/(当前高度);
var newPosX=this.position.x+deltaWidth*coefX;
var newPosY=this.position.y+deltaHeight*coefY;
//边缘案例
var newWidth=currentWidth+deltaWidth;
var newHeight=当前高度+增量高度;
zoomWidth=新宽度;
ZoomHight=新高度;
//log(“doZoom()newWidth--”+newWidth);
//log(“doZoom()newHeight--”+newHeight);
if(newWidth0){newPosX=0;}
如果(newPosX+newWidth0){newPosY=0;}
如果(newPosY+newHeight