it-swarm.com.ru

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

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

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

Вот код:

<!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>

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

23
kevinstueber

Я пытался повернуть простую графику 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);
}

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

23
Websemantic

Начиная с Firefox 55 (выпущен 8 августа 2017 г.), теперь поддерживается свойство CSS «transform-box». Установка его в «fill-box» будет имитировать настройку Chrome относительно transform-Origin в деревьях 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;
}
14
Jim

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

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

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

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

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

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

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

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

7
thirdender

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

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

transform-box: fill-box
transform-Origin: center center
2
LandonSchropp

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

-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 и т.д.), Чтобы установить это значение.

1
Hafenkranich

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

#test{
    -webkit-transform-Origin: 50% 50%;
    -moz-transform-Origin: 50% 50%;
    ...
}
0
Andrei Todorut

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

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

0
Jesse

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

Как это:

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

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

0
SoBiT