Как вращать весь холст и изображение, нарисованное на холсте одновременно? - PullRequest
0 голосов
/ 10 апреля 2019

Сначала загрузите крошечное изображение, которое шире его высоты, используя следующий код.

//<![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>

Вы видите, что изображение отображается на холсте правильно. Это не моя проблема, хотя. Я действительно пытаюсь вращать все размеры холста вместе с содержимым холста одновременно. Если бы это был квадрат, это не было бы проблемой, потому что я мог бы взять половину высоты и ширины, как: ctx.save(); cxt.translate(halfImageWidth, halfImageHeight); ctx.rotate(Math.PI*90/180); ctx.translate(-halfImageWidth, -halfImageHeight); ctx.drawImage(imageContext, 0, 0, imageWidth, imageHeight);.

Вот то, что я думал, будет работать, но не работает:

//<![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>

Я подумал, что, не переводя до поворота, мой источник находится в верхнем левом углу, поэтому я должен просто установить отрицательный источник после поворота, но это не сработает. Если бы кто-то мог показать и объяснить, как это сделать правильно, я был бы очень признателен.

PS

Я уже думал о ротации CSS, но поскольку я действительно использую данные, это не будет для меня решением.

1 Ответ

2 голосов
/ 10 апреля 2019

Если, как вы сказали, вам нужно повернуть только на 90 градусов, то это довольно просто.

Ширина вашего изображения станет высотой вашего холста, а его высота станет шириной холста.

Оттуда вам просто нужно применить обычный

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...