Подтвердить что ты не робот

Установка transform-origin в группе SVG, не работающей в FireFox

У меня возникла проблема с преобразованием источника в Firefox (v.18 +, другие версии не тестировались). Браузеры Webkit работают, как ожидалось.

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

Здесь код:

<!DOCTYPE html>
<html> 
    <head>
        <title>TEST</title>
        <style>
            #test{
                -webkit-transform-origin: 50% 50%;
                transform-origin: center center;

                -webkit-animation: prop 2s infinite;
                animation:         prop 2s infinite;
            }

            @-webkit-keyframes prop {
              0%    { -webkit-transform: scale(1,1);}
              20%   { -webkit-transform: scale(1,.8);}
              40%   { -webkit-transform: scale(1,.6);}
              50%   { -webkit-transform: scale(1,.4);}
              60%   { -webkit-transform: scale(1,.2);}
              70%   { -webkit-transform: scale(1,.4);}
              80%   { -webkit-transform: scale(1,.6);}
              90%   { -webkit-transform: scale(1,.8);}
              100%  { -webkit-transform: scale(1,1);}
            }

            @keyframes prop {
              0%    { transform: matrix(1, 0, 0, 1, 0, 0);}
              20%   { transform: matrix(1, 0, 0, .8, 0, 0);}
              40%   { transform: matrix(1, 0, 0, .6, 0, 0);}
              50%   { transform: matrix(1, 0, 0, .4, 0, 0);}
              60%   { transform: matrix(1, 0, 0, .2, 0, 0);}
              70%   { transform: matrix(1, 0, 0, .4, 0, 0);}
              80%   { transform: matrix(1, 0, 0, .6, 0, 0);}
              90%   { transform: matrix(1, 0, 0, .8, 0, 0);}
              100%  { transform: matrix(1, 0, 0, 1, 0, 0);}
            }
        </style>
    </head>
    <body>
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 16 16">
            <g id="test">
                <rect fill="#404040" x="7.062" y="3.625" width="1.875" height="8.75"/>
            </g>
        </svg>
    </body>
</html>

Спасибо за вашу помощь!

4b9b3361

Ответ 1

Я пытаюсь повернуть простую графику cog svg вокруг своей центральной точки, используя переход CSS. У меня была такая же проблема, как с Firefox; трансформированное происхождение, казалось, не имеет никакого эффекта.

Решение заключалось в том, чтобы нарисовать исходную форму svg так, чтобы ее центр находился в координате 0, 0:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
    <rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
</svg>

Затем добавьте группу вокруг него и переведите в нужную позицию:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
    <g transform="translate(150, 100)">
        <rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
    </g>
</svg>

Теперь вы можете применять css-переходы, которые должны работать в Firefox (я добавляю класс в тег HTML с помощью JavaScript на основе пользовательского действия (js-rotateObject) и использую Minimizr для проверки того, что браузер может обрабатывать преобразования и переходы (.csstransforms.csstransitions):

#myObject{
    transform: rotate(0deg);
    transition: all 1s linear;
}

.csstransforms.csstransitions.js-rotateObject #myObject{
    transform: rotate(360deg);
}

Надеюсь, что это поможет.

Ответ 2

Ответ на

@PatrickGrey отлично работал у меня, но мне нужно было обрабатывать гораздо более сложные SVG с несколькими путями. Я смог выполнить это исправление с помощью Inkscape, но это был многоступенчатый процесс. Я рекомендую сделать это с открытым редактором Inkscape XML, чтобы вы могли смотреть, что происходит.

  • Выберите элементы, которые вы хотите преобразовать, и выберите "Объект" > "Группа" , чтобы создать новую группу. Перетащите эту группу так, чтобы она была центрирована в верхнем левом углу документа. Это применит к группе атрибут transform="translate(…, …)".

  • Выберите "Объект" > "Разгруппировать" в меню. Это будет "сглаживать" атрибут преобразования, применяя любые преобразования координат к элементам в группе.

  • Необходимо выбрать исходные элементы. Выберите "Объект" > "Группа" , чтобы вернуть их в группу. Если вы используете CSS для преобразования элементов, добавьте в эту группу атрибут ID или class (редактор XML подходит для этого бита, или вы можете изменить идентификатор группы, щелкнув его правой кнопкой мыши и выбрав "Свойства объекта". Классы должны быть добавлены через редактор XML или позже в текстовый редактор.)

  • С выбранной группой выберите "Объект" > "Группа" еще раз. Это создает новую группу вокруг исходной группы.

  • Переместите эту новую группу в нужное место в документе. Если вы проверите DOM с помощью редактора XML, вы увидите, что transform="translate(…, …)" добавлен во внешнюю группу.

  • Любые преобразования CSS теперь могут быть применены к внутренней группе, и они будут обрабатываться последовательно с помощью Chrome и Firefox.

Спасибо @PatrickGrey.co.uk за первоначальное понимание. Самое сложное было выяснить, как применить начальное преобразование к координатам сложных объектов, не прибегая к вытягиванию волос и обширной математике. Трюк "Group, move, Ungroup" был задокументирован несколькими местами в StackOverflow, но я забыл его до сегодняшнего дня. Надеемся, что эти шаги могут спасти кого-то еще из-за большого количества горя.

Ответ 3

Как и в Firefox 55 (выпущен 8 августа 2017 года), теперь поддерживается свойство CSS "transform-box". Установка его в "fill-box" будет имитировать изображение Chrome относительно трансформации в деревьях SVG.

transform-origin: center; /* or transform-origin: 50% */
transform-box: fill-box;

Обновление 2017-9-14

Вы можете выбрать элементы, которые вам нужны в структуре SVG, или, как указывает Том в комментариях, вы можете просто применить его ко всем подэлементам элемента SVG (если стиль не мешает чему-либо еще вам пытаются достичь):

svg .my-transformed-element {
    transform-origin: center; /* or transform-origin: 50% */
    transform-box: fill-box;
}

или

svg * {
    transform-origin: center; /* or transform-origin: 50% */
    transform-box: fill-box;
}

Ответ 4

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

-moz-transform-origin: 25px 25px;
-ms-transform-origin:  25px 25px;
-o-transform-origin: 25px 25px;
-webkit-transform-origin:  25px 25px;
transform-origin: 25px 25px;

Некоторые браузеры по-прежнему не поддерживают преобразование-начало с процентными значениями, как они должны - по крайней мере, не во всех ситуациях. Если у вас нет фиксированного значения px, рассчитайте по одному на javascript и используйте библиотеку по вашему выбору (например, jQuery, Greensock и т.д.), Чтобы установить значение.

Ответ 5

FWIW, я смог решить мою проблему с Greensock, используя TweenMax для анимации отдельных путей внутри, и это работало в браузерах Firefox Gecko и Webkit (Safari/Chrome). Он лучше справляется с расчетом происхождения (не точно конечно, как, но это сработало для меня)

Если бы SVG с двумя передачами, я хотел бы вращаться внутри другой формы. Поэтому я дал каждой передаче уникальный идентификатор (id = "gear1", id = "gear2" ), а затем повернул их с помощью Greensock, что-то вроде этого:

TweenMax.to("#gear1", 3.2, { 
  repeat: -1, //repeat infintely 
  ease: Linear.easeNone,  //no easing, linear motion 
  rotation:360,  //amount to rotate (full) 
  transformOrigin:"center"  //transform origin that WORKS :) 
});

То же самое для # gear2 с немного отличающимся временем и отлично работает в браузерах.

Ответ 6

В соответствии с комментариями в этот отчет об ошибках значение по умолчанию для Firefox transform-box Firefox отличается от Chrome. Начиная с Firefox 55, это свойство теперь можно установить без установки флага.

Это исправило проблему для меня:

transform-box: fill-box
transform-origin: center center

Ответ 7

Отсутствует -moz-transform-origin из вашего кода css.

#test{
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    ...
}

Ответ 8

В качестве дополнения вы можете отключить анимацию для версий Firefox, которые не поддерживают transform-box: fill-box

Вот так:

@supports (-moz-transform: rotate(0deg)) and (not (transform-box: fill-box)) {
    #test {
        animation: none;
    }
}

Первое утверждение - это просто проверить, включен ли firefox, так как вы не хотите отключать его в других браузерах. Второй оператор проверяет, поддерживается ли transform-box -property браузером. Я использовал это в текущем проекте, и он работает как прелесть.