Рисование изображения в холсте под углом БЕЗ поворота холста

Я рисую изображение в HTML 5, используя холст в JavaScript. Мне нужно нарисовать его под углом. Я знаю, что это можно сделать, применив функцию rotate (angle), используя контекст холста. Но мне нужно сделать это без поворота самого холста.

Просьба предложить возможный подход для этого, если это возможно.

Ответ 1

На самом деле вы можете нарисовать все, что хотите, чтобы превратиться в заставку на холсте и нарисовать ее на своем основном холсте. Я использовал этот код в Google IO Talk:

rotateAndCache = function(image,angle) {
  var offscreenCanvas = document.createElement('canvas');
  var offscreenCtx = offscreenCanvas.getContext('2d');

  var size = Math.max(image.width, image.height);
  offscreenCanvas.width = size;
  offscreenCanvas.height = size;

  offscreenCtx.translate(size/2, size/2);
  offscreenCtx.rotate(angle + Math.PI/2);
  offscreenCtx.drawImage(image, -(image.width/2), -(image.height/2));

  return offscreenCanvas;
}

затем кешируйте его с помощью:

rotobj = rotateAndCache(myimg,myangle)

и в вашем drawcode:

mycontext.drawImage(rotobj,x_coord,y_coord)

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

Ответ 2

Когда вы применяете преобразование на холсте, вы не поворачиваете холст. вы просто говорите, что все вы. Собираетесь рисовать, будут преобразованы определенным образом. Если вы хотите избежать трансформации, чтобы повлиять на другие команды, используйте методы save() и restore(). Они позволяют сохранять и восстанавливать настройки холста.

ctx.save();
ctx.rotate(30);
ctx.drawImage();
ctx.restore();

Ответ 3

Я поддержал @PeterT - отличный отрывок и хорошо работает - спасибо за это! Мне нужно было внести 3 небольших изменения, чтобы заставить меня работать для меня:

1. макс ширины и высоты недостаточно: если вы думаете о повороте квадрата, вам нужен круг, диаметр которого является диагональю квадрата (var diam).
2. холст должен быть переведен обратно (или использовать сохранение/восстановление).
3. координаты объекта x и y должны быть скорректированы для размера холста.

Итак, я закончил с:

    rotateAndCache = function(image,angle) {
        var offscreenCanvas = document.createElement('canvas');
        var offscreenCtx = offscreenCanvas.getContext('2d');

        var size = Math.max(image.width, image.height);
        var diam = 2*((size/2)*Math.sqrt(2));                 // needs to be saved
        offscreenCanvas.width = diam;
        offscreenCanvas.height = diam;

        offscreenCtx.translate(diam/2, diam/2);
        offscreenCtx.rotate(angle);
        offscreenCtx.drawImage(image, -(image.width/2), -(image.height/2));
        offscreenCtx.translate(-diam/2, -diam/2);

        return offscreenCanvas;
}


И отрегулированное положение ничьей (необходимо сохранить в rotateAndCache):
mycontext.drawImage(rotobj,x-(diam-width)/2,y-(diam-height)/2);

Ответ 4

Это невозможно, и вам, вероятно, это не нужно. Попробуйте следующее:

context.save() // Save current state (includes transformations)
context.rotate()
... draw image ...
context.restore() // Restore state