холст поворачивается на 180 градусов вместо 90, когда я использую context.rotate - PullRequest
0 голосов
/ 04 февраля 2020

ОБНОВЛЕНИЕ - ЧАСТЬ II
Я заметил, что проблема возникает, когда я делаю ajax звонок, который я делаю перед поворотом изображения.
Я делаю это:

$.ajax({
    type:'POST',
    beforeSend: function(request) {
        request.setRequestHeader("Authorization", "Bearer {{ app('request')->token }}");
    },
    url: "my-url-to-rotate-image-on-server/90",
    success:function(data) {
        $('#my_id').rotate(90); // the rotate function is the code I wrote below
    },
    error: function(data) { }
});

Если я удаляю вызов ajax и просто поворачиваю изображение, оно работает.


Мне нужно повернуть изображение на 90 градусов, но изображение поворачивается на 180.
Это код (плагин jquery), который я нашел в сети и использую:

var p = this.get(0);
p.angle = 90;

if (p.angle >= 0) {
    var rotation = Math.PI * p.angle / 180;
} else {
    var rotation = Math.PI * (360+p.angle) / 180;
}
var costheta = Math.cos(rotation);
var sintheta = Math.sin(rotation);

var canvas = document.createElement('canvas');
var onLoad = false;
if (!p.oImage) {
    canvas.oImage = new Image();
    canvas.oImage.src = p.src;
    canvas.oImage.width = p.width;
    canvas.oImage.height = p.height;
    onLoad = true;
} else {
    canvas.oImage = p.oImage;
}

canvas.style.width = canvas.width = Math.abs(costheta*canvas.oImage.width) + Math.abs(sintheta*canvas.oImage.height);
canvas.style.height = canvas.height = Math.abs(costheta*canvas.oImage.height) + Math.abs(sintheta*canvas.oImage.width);

var context = canvas.getContext('2d');
context.save();
if (rotation <= Math.PI/2) {
    context.translate(sintheta*canvas.oImage.height,0);
} else if (rotation <= Math.PI) {
    context.translate(canvas.width,-costheta*canvas.oImage.height);
} else if (rotation <= 1.5*Math.PI) {
    context.translate(-costheta*canvas.oImage.width,canvas.height);
} else {
    context.translate(0,-sintheta*canvas.oImage.width);
}
context.rotate(rotation);

if (onLoad) {
    canvas.oImage.onload = function() {
        context.drawImage(canvas.oImage, 0, 0, canvas.oImage.width, canvas.oImage.height);
        context.restore();
    };
} else {
    context.drawImage(canvas.oImage, 0, 0, canvas.oImage.width, canvas.oImage.height);
    context.restore();
}

Я получаю, что размеры холста правильно повернуты (я имею в виду, старая ширина становится новой высотой, и наоборот) , но изображение поворачивается на 180 градусов вместо 90.

Я не знаю, как его отладить.

ОБНОВЛЕНИЕ
Я заметил, что происходит странное поведение только когда изображение sr c является URL-адресом http.
Если изображение sr c является блобом, код отлично работает.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2020

0 градусов указывает на восток при использовании cos (0), sin (0) и не на север, поэтому вы думаете, что это не работает, когда это действительно правильно.

Когда вы добавляете 90 градусов к Восток правильно указывает на юг, создавая впечатление, что он повернулся на 180 градусов.

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

Где у вас есть

 p.angle = 90;

Заменить на ...

 const POINT_NORTH = -90;
 p.angle = POINT_NORTH + 90;
0 голосов
/ 05 февраля 2020

Код, который вы взяли из net (который должен иметь ссылку / атрибуцию), очень старая школа (не менее 5 лет). Кроме того, код очень низкого качества.

Обратите внимание, что 2d контекст translate, scale, rotate и transform являются кумулятивными. Если вы наберете ctx.rotate(Math.PI/2) (90 градусов), а затем снова наберете ctx.rotate(Math.PI/2), вы фактически повернули Math.PI (180 градусов). Однако код каждый раз создает новый холст, поэтому это не будет причиной двойного поворота. Почему это происходит, не ясно в коде.

Вращение на холсте по часовой стрелке. 0 градусов в 3 часа.

Загрузите и поверните 90 градусов

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

Сначала функция поворота изображения и подгонка холста

// Rotates image 90 and sets canvas size to fit rotated image
function drawImageRot90(ctx, image) {
    ctx.canvas.style.width = (ctx.canvas.width = image.height) + "px";
    ctx.canvas.style.height = (ctx.canvas.height = image.width) + "px";
    ctx.setTransform(0, 1, -1, 0, ctx.canvas.width, 0);  // overwrite existing transform
    ctx.drawImage(image, 0, 0);
    ctx.setTransform(1, 0, 0, 1, 0, 0);                  // reset default transform
}

Затем функция загрузки изображения. Функция возвращает обещание, которое передаст изображение при загрузке.

// Return promise to provide loaded image as described in details AKA `p`
function loadImage(details) {
    return new Promise(loaded => {
        if (!details.oImage) {
            const img = new Image;
            img.src = details.src
            img.addEventListener("load",() => {
                    img.width = details.width;
                    img.height = details.height;
                    loaded(img);
                }, {once: true}
            );
        } else {
            loaded(details.oImage);
        }
    });
}

Соединение его

loadImage(this.get(0))
    .then((img) => {
        const canvas = document.createElement("canvas");
        drawImageRot90(canvas.getContext("2d"), img);
    })

Функция поворота с шагом 90

function drawImageRot(ang, ctx, image) { // ang must be 0, 90, 180, 270 or will default 180
    if (ang === 90 || ang === 270) {
        ctx.canvas.style.width = (ctx.canvas.width = image.height) + "px";
        ctx.canvas.style.height = (ctx.canvas.height = image.width) + "px";
        if (ang === 90) { ctx.setTransform(0, 1, -1, 0, ctx.canvas.width, 0) } 
        else { ctx.setTransform(0, -1, 1, 0, 0, ctx.canvas.height) }
    } else {
        ctx.canvas.style.width = (ctx.canvas.width = image.width) + "px";
        ctx.canvas.style.height = (ctx.canvas.height = image.height) + "px";
        if (ang === 0) { ctx.setTransform(1, 0, 0, 1, 0, 0) }
        else { ctx.setTransform(-1, 0, 0, -1, ctx.canvas.width, ctx.canvas.height) }
    }
    ctx.drawImage(image, 0, 0);
    ctx.setTransform(1, 0, 0, 1, 0, 0);   // reset default transform
}
0 голосов
/ 04 февраля 2020

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
	let img = document.querySelector('img');
	let width = img.naturalWidth, height=img.naturalHeight;
	let canvas = document.createElement('canvas');
	canvas.width = height;
	canvas.height = width;
	let ctx = canvas.getContext('2d');
	ctx.rotate(Math.PI/2);
	ctx.translate(0,-height);
	ctx.drawImage(img,0,0);
	document.body.appendChild(canvas);
}
body
{
	background-color: #333;
}
<img id='theImage' src='https://i.stack.imgur.com/Zqh6Am.png'/>
...