简体   繁体   中英

How do I rotate the entire canvas and an image drawn into the canvas at the same time?

First, upload a tiny image that is wider than it is tall using the following code.

 //<![CDATA[ /* js/external.js */ var doc, M, I; addEventListener('load', function(){ doc = document; M = function(tag){ return doc.createElement(tag); } I = function(id){ return doc.getElementById(id); } var canvas = I('canvas'), ctx; I('upload').onchange = function(){ var files = this.files, file, fr, img; if(files.length){ file = files[0]; fr = new FileReader; img = M('img'); fr.onload = function(){ img.onload = function(){ canvas.width = this.width; canvas.height = this.height; ctx = canvas.getContext('2d'); ctx.drawImage(this, 0, 0, canvas.width, canvas.height); } img.src = this.result; } fr.readAsDataURL(file); } } }); //]]> 
 /* css/external.css */ *{ float:left; clear:left; } #canvas{ margin-top:10px; } 
 <!DOCTYPE html> <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> <head> <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' /> <title>canvas rotate</title> <link type='text/css' rel='stylesheet' href='css/external.css' /> <script type='text/javascript' src='js/external.js'></script> </head> <body> <input id='upload' type='file' accept='image/*' /> <canvas id='canvas' width='0' height='0'></canvas> </body> </html> 

You can see that the image displays in the canvas correctly. That is not my problem, though. I'm really trying to rotate the entire canvas dimensions along with the canvas contents at the same time. If it was a square it would be no problem because I could take half of the height and the width like: ctx.save(); cxt.translate(halfImageWidth, halfImageHeight); ctx.rotate(Math.PI*90/180); ctx.translate(-halfImageWidth, -halfImageHeight); ctx.drawImage(imageContext, 0, 0, imageWidth, imageHeight); ctx.save(); cxt.translate(halfImageWidth, halfImageHeight); ctx.rotate(Math.PI*90/180); ctx.translate(-halfImageWidth, -halfImageHeight); ctx.drawImage(imageContext, 0, 0, imageWidth, imageHeight); .

Here is what I thought would work, but does not:

 //<![CDATA[ /* js/external.js */ var doc, M, I; addEventListener('load', function(){ doc = document; M = function(tag){ return doc.createElement(tag); } I = function(id){ return doc.getElementById(id); } var canvas = I('canvas'), ctx; I('upload').onchange = function(){ var files = this.files, file, fr, img; if(files.length){ file = files[0]; fr = new FileReader; img = M('img'); fr.onload = function(){ img.onload = function(){ canvas.width = this.height; canvas.height = this.width; ctx = canvas.getContext('2d'); ctx.save(); ctx.rotate(Math.PI*90/180); ctx.translate(-canvas.width, 0); ctx.drawImage(this, 0, 0, canvas.width, canvas.height); ctx.restore(); } img.src = this.result; } fr.readAsDataURL(file); } } }); //]]> 
 /* css/external.css */ *{ float:left; clear:left; } #canvas{ margin-top:10px; } 
 <!DOCTYPE html> <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> <head> <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' /> <title>canvas rotate</title> <link type='text/css' rel='stylesheet' href='css/external.css' /> <script type='text/javascript' src='js/external.js'></script> </head> <body> <input id='upload' type='file' accept='image/*' /> <canvas id='canvas' width='0' height='0'></canvas> </body> </html> 

I figured that by not translating before rotation, my origin is top left corner, so I should just be able to set negative origin after rotation, but that doesn't work. If someone could show and explain how to do this correctly I would be most appreciated.

PS

I already thought about a CSS rotation, but since I'm really using the data this won't be a solution for me.

If as you stated, you only need to rotate by 90deg, then it's quite simple.

Your image's width will become your canvas' height, and its height will become the canvas' width.

From there you just have to apply the usual

translate(target-center-x, target-center-y)
rotate(angle)
drawImage(img, -transform-origin, -transform-origin)

 fileinput.onchange = e => { const img = new Image(); img.onload = e => draw(img); img.src = URL.createObjectURL(fileinput.files[0]); }; function draw(img) { const ctx = canvas.getContext('2d'); canvas.width = img.height; canvas.height = img.width; // move to center of the canvas ctx.translate(canvas.width / 2, canvas.height / 2); ctx.rotate(Math.PI / 2); // set the transform origin at center of the image ctx.drawImage(img, -img.width / 2, -img.height / 2); } 
 <input type="file" id="fileinput"> <canvas id="canvas"></canvas> 

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