Установка 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>
Спасибо за вашу помощь!
Ответы
Ответ 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 браузером. Я использовал это в текущем проекте, и он работает как прелесть.