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

时间:2017-01-09 12:59:00

标签: javascript html5 cordova canvas

我正在创建一个绘图应用程序,我可以选择放大/缩小我使用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);

对于捏合放大/缩小图像,我正在使用此https://github.com/rombdn/img-touch-canvas

0 个答案:

没有答案