Spłaszczanie matrycy SVG przekształca się w Inkscape
Mam darmowy plik clipart SVG stworzony pierwotnie w Inkscape, który modyfikuję do użytku w grze JavaScript na Windows 8. Zawiera wiele instancji ścieżki z transformatą macierzy zastosowaną na otaczającej grupie, jak to:
<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
<path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
</g>
Chcę spłaszczyć tę transformację, nakładając ją wcześniej na ścieżkę w Inkscape, aby zmniejszyć pracę przeglądarki podczas animacji. Jednak po podłączeniu 6 wartości matrycy do parametrów A B C D E F w Inkscape i zastosowaniu go, to nadaje ścieżce zupełnie inny obrót i skalowanie do tego, co robi silnik IE10.
Sprawdzałem wiele razy, czy mam poprawnie zmapowane 6 wartości. Co robię źle?
EDIT: OK, oto zrzuty ekranu przed i po IE10 i Inkscape. W przypadku IE10 SVG znajduje się bezpośrednio wewnątrz ciała pustego dokumentu HTML (renderowanie jest dokładnie takie samo w Firefoksie). W Inkscape po prostu otworzyłem plik SVG" przed", który zawiera tylko element path, wybrał ścieżkę i podłączył 6 wartości przekształć macierz w obiekt > Przekształć > macierz. Niewiele wiem o matrycach, chcę tylko móc wstępnie zastosować te przekształcenia w taki sam sposób, jak robi to przeglądarka, a najlepiej zrozumieć, dlaczego jest różnica w Inkscape. Dzięki.
5 answers
Krótka odpowiedź
Podczas wpisywania params macierzy transformacji w Inkscape, upewnij się, że masz zaznaczoną opcję "Edytuj bieżącą macierz", ponieważ jeśli zastosujesz nową macierz transformacji do obiektu, to w rzeczywistości mnożysz tę nową macierz z istniejącą macierzą transformacji obiektu, więc upewnij się, że edytujesz ją zamiast tego.
Długa Odpowiedź
Jak przeliczyć wszystko samodzielnie.
Najpierw spróbujmy zrozumieć transformację matryce trochę.
Macierz transformacji jest szybkim i sprytnym narzędziem do stosowania przekształceń afinicznych (transformacji, która zachowuje linie proste) do wektora.
Tak więc, jeśli masz wektor (powiedzmy współrzędne 2d) i macierz transformacji i pomnożysz te dwa razem, skończysz z przekształconymi współrzędnymi, z zastosowanymi transformacjami zdefiniowanymi w macierzy transformacji.
Obliczanie x'
i y'
odbywa się tak:
x' = a*x + c*y + e
y' = b*x + d*y + f
Następnie musimy zrozum trochę format svg.
Zgodnie ze specyfikacją W3C svg transformata matrix
przyjmuje dokładnie te 6 parametrów (a,b,c,d,e,f) jako argumenty.
Dlatego, z twojego przykładu,
<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
Mamy następujące paramy macierzy transformacji:
a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223
Teraz, jeśli mamy następującą współrzędną przykładową: x=27, y=-9
, możemy ją przekształcić, używając wcześniej zdefiniowanej macierzy transformacji tak:
x' = a*x + c*y + e
x' = 0.443*27 + -0.896*-9 + 589.739
x' = 609.764
y' = b*x + d*y + f
y' = 0.896*27 + 0.443*-9 -373.223
y' = −353.018
Fajne, co? Możesz uzyskać więcej informacji tutaj
Ale to nie wszystko. Musimy również zrozumieć dane ścieżki svg.Zgodnie ze specyfikacją W3C svg path dspecification każda litera w danych ścieżki reprezentuje instrukcję. Każda z par liczb, które następują po instrukcji, reprezentuje wartość współrzędnych.
Z twojego przykładu mamy następującą ścieżkę:
<path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
Tutaj widzimy, że obiekt path używa jednej bezwzględnej instrukcji moveto
(Wielkie Litery M ), względnej smooth curveto
cubic Bézier curve (lowercase s), relative lineto
instruction (lowercase l ), and another relative smooth curveto
cubic Bézier curve instruction, nastepnie closepath
instruction (lowercase z).
M486,313
jest tłumaczone na absolute moveto x=486, y=313s27-9,43-29
jest nieco bardziej skomplikowane do odczytania, ponieważ niektóre śpiączki są pomijane, ponieważ nie są potrzebne, jeśli liczba ujemna jest ujemna, więc znak minus działa jak śpiączka - w każdym razie, to przekłada się na relatywnie gładki krzywizna Beziera x=27, y = -9, x=43, y=-29 (jeden punkt docelowy i jeden punkt kontrolny)
I tak dalej.
Jak więc zastosować i usunąć macierz transformacji z grupy svg? Tak:
// we read the transformation matrix params
// <g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223
// we read the path data, and transform each instruction
// <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
M486, 313 Absolute move to
x' = a*x + c*y + e = a*486 + c*313 + e = 524.589
y' = b*x + d*y + f = b*486 + d*313 + f = 200.892
Przejście do instrukcji jest teraz M524.589,200.892
S27-9,43-29 - smooth curveto, powtórz ten sam proces dla każdej współrzędnej, ale ustaw e
i f
(parametry translacji) na 0, ponieważ jest to Instrukcja względna, a nie absolutna.
Teraz jest
s20.025,20.205,45.033,25.680999999999997
L26,4,1,23-22,5
stanie się
l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497
S-25-6-48-3
stanie się
s-5.698999999999999,-25.058000000000003,-18.576,-44.337
I z pozostanie z
Więc wynikowa przekształcona ścieżka będzie:
<path d="M524.589,200.892s20.025,20.205,45.033,25.680999999999997l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497s-5.698999999999999,-25.058000000000003,-18.576,-44.337z" />
Mam nadzieję, że to ma dla ciebie sens.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-27 14:00:59
Możesz upiec koordy wybierając ścieżkę, a następnie używając Path - > Union (CTRL++). Mam nadzieję, że to pomoże
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-05 17:35:22
Wklej w miejscu może Ci pomóc:
- Kliknij dwukrotnie grupę w Inkscape, aby ją wprowadzić.
- Zaznacz wszystkie Zawartość grupy, naciskając Ctrl + A, A skopiuj za pomocą Ctrl+C.
- Kliknij dwukrotnie na zewnątrz grupy, aby opuścić grupę.
- Edit > Wklej w miejsce (Ctrl+Alt+V) – w tym momencie do wklejanych obektów zostaną zastosowane przekształcenia grupowe.
- Grupa obiekty ponownie (Ctrl + G)
- Przenieś nową grupę do tej samej głębokości co oryginalna i Usuń oryginalną grupę . (Jest to prawdopodobnie łatwiejsze z edytorem XML, Ctrl + Shift+X.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-25 08:41:02
Po odpowiedzi @ andraaspar, możesz również spróbować rozgrupować (Ctrl-U) i ponownie grupować (Ctrl-G). U mnie zadziałało.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-11 20:37:52
Dzięki ArtBIT za wszystkie informacje ! Miałem pewne problemy z tym w aplikacji PHP i napisałem bibliotekę, która manipuluje danymi czcionek (z pliku SVG) i robi na niej jakiekolwiek przekształcenia. Każdy zainteresowany może spróbować z Githuba:
Https://github.com/kartsims/easysvg
Przykład użycia:
require 'easySVG.php';
$svg = new EasySVG();
$svg->setFont("paris-bold-webfont.svg", 100, "#000000");
$svg->addText("Simple text display");
$svg->addAttribute("width", "800px");
$svg->addAttribute("height", "100px");
echo $svg->asXML();
Przykład manipulacji danymi SVG:
$def = 'YOUR SVG DEFINITION HERE';
$easySVG = new EasySVG();
// rotate by 40°
$rotated_def = $easySVG->defRotate($def, 40)
// rotate by 40° with center at (200,100)
$rotated_def2 = $easySVG->defRotate($def, 40, 200, 100)
// scale transform : width*4
$scaled_def = $easySVG->defScale($def, 4)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-21 13:13:38