/ / SVG transform-origin nie działa w Chrome - google-chrome, svg

SVG transform-origin nie działa w Chrome - google-chrome, svg

Mam aplikację opartą na SVG, która w dużym stopniu wykorzystuje transformacje, takie jak translacja, obrót i skalowanie. Chociaż nie mam problemu w przeglądarce Firefox, w przeglądarce Chrome transform-origin nieruchomość nie jest brana pod uwagę. Wydaje się, że stosuje domyślną wartość klienta użytkownika 0px 0px 0.

Oto przykład (JSFiddle):

<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(0,0) scale(0.5) rotate(45)" style="transform-origin: 100px 100px;">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>

problem pochodzenia transformacji

Jak widać, Chrome stosuje całą transformację z lewego górnego rogu kształtu niezależnie od zdefiniowanego pochodzenia, podczas gdy Firefox szanuje zdefiniowane pochodzenie.

Czy brakuje mi czegoś na temat tego, jak transform-origin działa z SVG?

Czy ktoś rzeczywiście znalazł sposób na naprawienie tego bez kompensowania tłumaczeniami?

Odpowiedzi:

6 dla odpowiedzi № 1

Odpowiadam na własne pytanie, aby w pełni wyjaśnić, o co chodzi transform-origin właściwości funkcji transformacji SVG 1.1 i jak rozwiązać ten problem w Chrome 48.


Po pierwsze, transform-origin to czysta właściwość CSS 3, w ogóle nie jest związana z SVG 1.1. Pomimo tego, że transform brzmi bardzo podobnie transform-origin, mają zastosowanie do różnych systemów. transform istnieje w CSS 3 i SVG 1.1, ale mają oddzielne implementacje. transform-origin istnieje tylko w CSS 3 i dlatego nie powinien wpływać na SVG 1.1. Fakt, że transform-origin nie ma wpływu na SVG w Chrome 48.

Więc dlaczego transform-origin dotyczy SVG w przeglądarce Firefox 44? Cóż, powód nie jest do końca jasny, ale wydaje się, że jest to część ciągłych wysiłków Mozilli, aby powoli wprowadzić obsługę SVG 2 w Firefoksie. Rzeczywiście, z SVG 2, wszystko stanie się transformacją CSS 3 (bez oddzielnej implementacji), a zatem SVG otrzyma wsparcie dla transform-origin. Dowiedziałem się o tym w doskonałym artykule na temat Układy współrzędnych SVG od Sary Soueidan.


Jak można to przezwyciężyć w Chrome 48. Jest to dość proste, ale jeśli chcesz zastosować translate(), scale() i rotate() w tym samym czasie nadal będziesz musiał obliczyć przesunięcie wywołane skalowaniem i skompensować je w swoim tłumaczeniu.

Tak jak Bobby Orndorff wspomniany w swojej odpowiedzi, faktycznie możliwe jest zapewnienie środka obrotu dla rotate() funkcji, zapewniając dodatkowe parametry x i y. To już jest duża poprawa. Ale niestety scale() funkcja nie obsługuje takich rzeczy i zawsze będzie skalowany od lewego górnego rogu swojego rodzica. Dlatego nadal będziesz musiał poprawić swoje tłumaczenie, aby zasymulować skalę wokół środka.

Oto ostateczne rozwiązanie, które działa w Chrome 48 i Firefox 44:

<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(50,50) scale(0.5) rotate(45, 100, 100)">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>

1 dla odpowiedzi nr 2

Przykładem jest mieszane pochodzenie transformacji CSS z rozszerzeniemTransformacja SVG. Chociaż transformacja CSS i transformacja SVG są podobne, istnieją różnice. Na przykład transformacja CSS może być 2D i 3D, podczas gdy transformacja SVG jest tylko 2D. Funkcja obracania transformacji CSS akceptuje kąt jako liczbę połączoną z jednostką (np. Degs, grad, rad, turn), podczas gdy transformacja SVG akceptuje kąt jako liczbę (z domniemaną jednostką stopni) wraz z opcjonalnymi parametrami drugim i trzecim (x, y) reprezentujące pochodzenie rotacji.

Aby przykład działał w FireFox i Chrome, możesz użyć transformacji CSS zamiast transformacji SVG. Na przykład...

<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g style="transform: translate(0,0) scale(0.5) rotate(45deg); transform-origin: 100px 100px;">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>

Aby przykład działał w FireFox, Chrome i IE, możesz użyć funkcji obracania transformacji SVG z opcjonalnymi parametrami drugim i trzecim zamiast źródła transformacji CSS. Na przykład...

<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(0,0) scale(0.5) rotate(45,200,200)">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>