Центрировать объект на основе вращения

#javascript #math #canvas #geometry

#javascript #математика #холст #геометрия

Вопрос:

Мне нужно центрировать объект на холсте на основе его вращения. Я не могу разобраться в математике.

введите описание изображения здесь

Какая информация у меня есть?

  • координаты x и y верхнего левого угла (см. Красный круг изображения)
  • ширина и высота объекта
  • значение поворота в градусах

Что я пробовал до сих пор?

 // center horizontally 
if (curretElement === null) return;
curretElement.x((canvas.width() / 2) - ((curretElement.width() * curretElement.scaleX()) / 2));
canvas.draw();

// center vertically
curretElement.y((canvas.height() / 2) - ((curretElement.height() * curretElement.scaleY()) / 2));
canvas.draw();
  

Это центрирует изображение, когда оно не повернуто.

currentElement является выбранным объектом.

canvas это комната, в которой объект должен быть центрирован.

Комментарии:

1. Я предполагаю, что координаты x, y в верхнем левом углу — это информация, которую вы хотите вычислить, в отличие от информации, которая у вас есть? Другими словами, привязкой положения объекта является верхний левый угол, независимо от угла?

2. Правильно, поэтому для этого вам нужно сначала вычислить вектор от центра объекта до его верхнего левого угла. Это (-width * scale / 2, -height * scale / 2) , как вы уже подсчитали. Добавьте это в центр холста, и у вас будут координаты для angle = 0, опять же, как вы уже делаете. Для другого угла все, что вам нужно сделать, это повернуть вектор перед добавлением его в центр холста. Для этого вы можете использовать 2D матрицу вращения .

3. Похоже, вы используете FabricJs … можете ли вы опубликовать полный, но минимальный фрагмент кода вашего проекта

4. я использую конвайс

Ответ №1:

Вы можете вычислить координаты таким образом:

  1. представьте, что ваш объект находится в центре холста
  2. вычислите координаты верхнего левого угла относительно центра холста
  3. поверните объект вокруг центра холста и вычислите, где заканчивается верхний левый угол относительно центра холста
  4. переведите относительные координаты верхнего левого угла обратно в абсолютные координаты

Вот функция, которая выполняет вычисление:

 function calculateXY(canvasWidth, canvasHeight, width, height, angle) {
    //calculate where the top left corner of the object would be relative to center of the canvas
    //if the object had no rotation and was centered
    const x = -width / 2;
    const y = -height / 2;

    //rotate relative x and y coordinates by angle degrees
    const sinA = Math.sin(angle * Math.PI / 180);
    const cosA = Math.cos(angle * Math.PI / 180);
    const xRotated = x * cosA - y * sinA;
    const yRotated = x * sinA   y * cosA;

    //translate relative coordinates back to absolute
    const canvasCenterX = canvasWidth / 2;
    const canvasCenterY = canvasHeight / 2;
    const finalX = xRotated   canvasCenterX;
    const finalY = yRotated   canvasCenterY;

    return { x: finalX, y: finalY };
}
  

Комментарии:

1. это работает. моя ошибка заключалась в том, что я взял не середину объекта, а координаты x и y верхнего левого угла (см. Изображение) большое спасибо!

Ответ №2:

ОБНОВЛЕНИЕ: первая попытка действительно плоха, поэтому я обновляю код. которые на самом деле работают и удерживают ваш левый угол в центре контейнера, просто заполните ввод угла

я хочу прокомментировать и спросить больше, но я не могу, а эта штука (баунти) заманчива

Не сильно зависит от Java script. может быть, это то, что вам нужно для второй попытки.

Угол — это контейнер и содержимое в before. Вращайте, но он остается там. помогает ли это? прокомментируйте это.

     <!DOCTYPE html>
    <html lang="en">
    <body>
        <style>
        body{
          margin:0;
        }
        #container{
          display :flex;
          position: absolute;
          width:100%;
          height:100%;
        }
        #ram{
          display:flex;
          background-color:black;
          position:absolute;
          margin:auto;
          top:50%;
          right:50%;
        }
        #ram::before{
          content: "";
          position:absolute;
          height:40px;
          width:400px;
          background-color: #000;
        }
        </style>
        <input type="number" id="a" onchange = "forf()">
        <div id = "container">
        <div id = "ram">
        </div>
        </div>
        <script>
        function forf(){
          var a = document.getElementById("a").value;
        document.getElementById("ram").style.transform = "rotate("   a   "deg)";
        }
        </script>
    </body>
    </html>  

Комментарии:

1. к сожалению, это мне совсем не помогло. но в любом случае спасибо за ваши усилия.