简体   繁体   中英

CamanJS revert and rotate fix

If you use the rotation plugin in CamanJS there is an issue when you are trying to revert changes. Caman is only implemented in a way that is working good when you crop or resize your image, but not when you rotate it. When you revert and the image is rotated the image reloads distorted, because it doesn't take under consideration that the canvas has rotated and changed size. Also the imageData.data of the canvas are different now. So I think i fixxed it by looking how he implemented the resize. Basicaly what I did (and he does too) is:

  1. Create a canvas in the initial state
  2. Update his pixelData from the initialState
  3. create a new canvas
  4. Rotate him with the initial image
  5. get the ImageData and rerender them

So what I added. I needed to know how many angles was the image rotated so I can get the correct imageData when rotate the new canvas (step 4).

this.angle=0; //added it in the constructor

I also added a new boolean in the constructor to tell me if canvas was rotated

this.rotated = false;

In the rotated plugin:

Caman.Plugin.register("rotate", function(degrees) {
    //....
    //....
    //....
    this.angle += degrees;
    this.rotated = true;
    return this.replaceCanvas(canvas);
}

and on the originalVisiblePixels prototype:

else if (this.rotated){
    canvas = document.createElement('canvas');//Canvas for initial state
    canvas.width = this.originalWidth; //give it the original width
    canvas.height = this.originalHeight; //and original height
    ctx = canvas.getContext('2d');
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    pixelData = imageData.data;//get the pixelData (length equal to those of initial canvas      
    _ref = this.originalPixelData; //use it as a reference array
    for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        pixel = _ref[i];
        pixelData[i] = pixel; //give pixelData the initial pixels
    }
    ctx.putImageData(imageData, 0, 0); //put it back on our canvas
    rotatedCanvas = document.createElement('canvas'); //canvas to rotate from initial
    rotatedCtx = rotatedCanvas.getContext('2d');
    rotatedCanvas.width = this.canvas.width;//Our canvas was already rotated so it has been replaced. Caman's canvas attribute is allready rotated, So use that width
    rotatedCanvas.height = this.canvas.height; //the same
    x = rotatedCanvas.width / 2; //for translating
    y = rotatedCanvas.width / 2; //same
    rotatedCtx.save();
    rotatedCtx.translate(x, y);
    rotatedCtx.rotate(this.angle * Math.PI / 180); //rotation based on the total angle
    rotatedCtx.drawImage(canvas, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height); //put the image back on canvas
    rotatedCtx.restore(); //restore it
    pixelData = rotatedCtx.getImageData(0, 0, rotatedCanvas.width, rotatedCanvas.height).data; //get the pixelData back       
    width = rotatedCanvas.width; //used for returning the pixels in revert function               
}

You also need to add some resets in the reset prototype function. Basicaly reset angle and rotated

Caman.prototype.reset = function() {
    //....
    //....
    this.angle = 0;
    this.rotated = false;
}

and that's it.

I used it and works so far. What do you think?Hope it helps

Thanks for this, it worked after one slight change.

in the else if statement inside the originalVisiblePixels prototype I changed:

x = rotatedCanvas.width / 2; //for translating
y = rotatedCanvas.width / 2; //same

to:

x = rotatedCanvas.width / 2; //for translating
y = rotatedCanvas.height/ 2; //same

before this change my images where being cut.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM