Настройка преобразования-происхождения в группе SVG не работает в Firefox

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

Вот код:

#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);
  }
}
<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>


person kevinstueber    schedule 28.02.2013    source источник
comment
FWIW, предположительно исправлено в Firefox 19 beta 3, хотя у меня все еще возникают проблемы в Firefox 22. Список ошибок Mozilla: bugzilla.mozilla.org/show_bug.cgi?id=828286   -  person Toph    schedule 08.07.2013
comment
Тьфу, извините, неправильно прочитал, я не уверен, что эта ошибка связана с...   -  person Toph    schedule 08.07.2013
comment
transform-origin не поддерживается для элементов SVG в Firefox. Пожалуйста, проголосуйте за ошибка #923193), чтобы получить поддержку.   -  person dotnetCarpenter    schedule 21.05.2014
comment
@dotnetCarpenter исправлено в Firefox 41+   -  person zigomir    schedule 25.08.2015
comment
@zigomir да ты прав! Тем не менее, это все еще не браузер Firefox по умолчанию. Но да, проблема исчезнет со следующей версией Firefox. Тест: bug1013421.bmoattachments.org/attachment.cgi?id=8425610   -  person dotnetCarpenter    schedule 11.09.2015


Ответы (8)


Я пытался повернуть простую графику svg cog вокруг ее центральной точки, используя переход 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);
}

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

person Websemantic    schedule 23.05.2013
comment
Для тех, кто сталкивается с той же проблемой, этот ответ полезен. Если вы пытаетесь применить анимацию к элементу ‹path›, она все равно может не работать в Firefox. Здесь есть удобное исправление: stackoverflow.com/a/18943090/1869285 - person Fingel; 26.09.2013
comment
Firefox v42 теперь поддерживает тег -moz-transform-origin. - person voam; 05.11.2015
comment
Умный способ сделать это. Хотелось бы, чтобы firefox собрал их какашки вместе. - person Marcos Pereira; 31.03.2016
comment
Вот Codepen, чтобы доказать вашу точку зрения (без Javascript). Спасибо за совет. :) codepen.io/schafeld/pen/zwjodP - person Oliver Schafeld; 12.05.2017

Начиная с 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;
}

or

svg * {
    transform-origin: center; /* or transform-origin: 50% */
    transform-box: fill-box;
}
person Jim    schedule 09.08.2017
comment
Пожалуйста, отредактируйте свой ответ, чтобы указать, на каком элементе(ах) должна быть установлена ​​эта поддержка CSS. (SVG? G? Путь/Прямая/и т. д.) Это похоже на HTML box-sizing, поэтому мы хотим svg * { transform-box: fill-box; }? РЕДАКТИРОВАТЬ: я закончил тем, что сделал последнее. svg * {} - person Tom; 14.09.2017
comment
Обновлено, и спасибо за информацию, Том! - Что касается элемента, это могут быть любые элементы в структуре SVG, для которых вам нужен стиль (например, для анимации) - <g>, <circle>, <path>, что угодно. - person Jim; 15.09.2017
comment
Это должен быть принятый ответ. Простое svg * { transform-box: fill-box; } исправило все анимации для меня. - person Husky; 27.09.2017
comment
Это должен быть ответ сейчас! - person jaminroe; 24.04.2018
comment
Я бы хотел, чтобы это поле преобразования: поле заполнения работало, но оно не выглядит следующим образом: codepen.io/MSCAU /pen/XyXoba. Я что-то упускаю? - person MSC; 08.11.2018
comment
@MSC - преобразование вращения не вращается вокруг точки, о которой вы думаете. Вы можете добавить половину пикселя для компенсации: codepen.io/jimbo2150/pen/VVgWGj - person Jim; 01.12.2018
comment
@ Джим - да. В большинстве случаев люди не используют такие маленькие блоки с SVG, поэтому это остается незамеченным. Команда Firefox отметила это как ошибку и присвоила ей приоритет 3: bugzilla.mozilla.org /show_bug.cgi?id=1505932 - person MSC; 02.12.2018
comment
@MSC - После некоторого тестирования я подумал, что это может быть ошибка, но я не был уверен. Спасибо. - person Jim; 02.12.2018

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

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

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

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

  4. Выбрав группу, снова выберите Объект > Группа. Это создает новую группу вокруг исходной группы.

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

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

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

person thirdender    schedule 12.07.2013
comment
Эта техника отлично сработала для меня. Большое спасибо @ Thirdender!! - person Paolo Mioni; 06.03.2014
comment
Рад, что это помогло :-) Если вы можете помочь отредактировать мой ответ, чтобы он был понятнее, пожалуйста, не стесняйтесь. Я все еще чувствую, что это очень запутанно, когда я перечитывал это сегодня… :-p - person thirdender; 06.03.2014

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

Это решило проблему для меня:

transform-box: fill-box;
transform-origin: center center;
person LandonSchropp    schedule 03.09.2017
comment
В моем случае это было причиной проблемы. - person dodo254; 24.02.2021

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

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

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

person Hafenkranich    schedule 01.09.2015

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 с немного другим временем и отлично работает в разных браузерах.

person Jesse    schedule 21.07.2016

Отсутствует -moz-transform-origin в вашем коде CSS.

#test{
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    ...
}
person Andrei Todorut    schedule 18.01.2018

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

Нравится:

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

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

person SoBiT    schedule 18.01.2018