-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Выбрать движок SVG для React: система координат #2
Comments
По анимации - предварительно варианты react-svgpathplayer - анимация путей SVG (использует Snap.svg) Анимация с React+SVG. Требуется, например, анимировать перемещение точки - это изменение координат X и Y у кружочка. чел задаётся аналогичным вопросом и сам себе отвечает еще какая-то анимация в react-native (похоже, прям покадрово рисуют) Паттерны React интересный момент про Function as children+Render callback - проверить, имеет ли отношение к анимации
|
Трансформ координат Coordinate Systems, Transformations and Units SVG Transformation Understanding SVG Coordinate Systems and Transformations (Part 1) — The viewport, viewBox, and preserveAspectRatio |
По координатам. Inkscape Coordinates Inkscape: why do coordinates in GUI and XML differ? В инкскейпе, похоже, с направлением координаты Y такая же шизофазия. В GUI ноль у Y находится в нижнем левом углу, координата идет вверх, а в SVG - ноль Y находится в верхнем левом углу, координата идет вниз. Конвертация происходит каким-то образом налету, в редакторе XML по X координаты совпадают, а по Y отличаются на высоту документа. Причем, если поменять размер документа в свойствах (0 внизу сохраняется, значит по логике верхний ноль должен улететь к новой верхней границе документа), конвертация (по крайне мере, в отрытом документе) сходу не происходит, т.е. реальный 0 SVG вообще не понятно, где повисает и как от него считать. После сохранения документа с новым размером (A4->US Legal) тоже ничего не поменялось - 0 SVG по Y висит по центру документа (там, где была верхняя граница A4), бу-га-га. Итого, имеем:
Делать трансформ - зеркальное отражение по Y (со смещением)
минусы:
Не делать трансформ - оставлять стандартную систему координат, рисовать элементы рабочего поля и маркеры по Y с предварительной конвертацией из визуальных координат в систему координат SVG
минусы:
Еще вариант - вообще не переворачивать координаты, использовать 0 в левом верхнем углу
минусы
Третий вариант - не вариант. Второй уже попробовал в DrawingCanvas 6eb1203 : головомойка с пересчетом точек вылезла во всей красе (особенно, с прямоугольником) - абсолютная шизофрения. Стоит попробовать первый вариант - попробовать перевернуть глобальные координаты. |
Короче, вариант с перевернутыми координатами внутри группы g норм. Код получается можно сказать чистый (по сравнению с предыдущими ручными пересчетами). По поводу "нестандартного" кода я тоже перегнул - трансформы с переворотами вполне стандартны, люди позабористее вещи делают и ничего. Всего имеем 3 прямоугольника:
В теге svg задаем параметры width/height для svg (размер виджета) и область просмотра viewBox. <svg
id="svg2"
version="1.0"
x="0.00000000"
y="0.00000000"
width={this.props.screen.width}
height={this.props.screen.height}
viewBox={"" +
-30 + " " +
-30 + " " +
(this.props.fold.dimX + 60) + " " +
(this.props.fold.dimY + 60)}> Дальше группа - перевернутая и сдвинутая на место, как в Inkscape. Внутри группы координаты относительно нижнего левого угла прямогольника fold.dimX x fold.dimY <g id="layer1"
transform={"scale(1, -1)" +
" translate(0, -" + this.props.fold.dimY + ")"
}>
<line
x1={0}
y1={0}
x2={this.props.fold.dimX}
y2={this.props.fold.dimY}
style={{fill:"none", stroke:"black", strokeWidth:1, strokeDasharray:"2 1"}}/>
<rect x="0" y="0" width={this.props.fold.dimX} height={this.props.fold.dimY}
style={{fill:"none", stroke:"black", strokeWidth:1, strokeDasharray:"2 1"}}/>
<text transform={"scale(1, 1)"}
x={-10} y={-10}
style={{fontSize: "12px"}}>0</text>
<text transform={"scale(1, -1)"}
x={this.props.fold.dimX} y={-10}
style={{fontSize: "12px"}}>x</text>
<text transform={"scale(1, -1)"}
x={-10} y={this.props.fold.dimY}
style={{fontSize: "12px"}}>y</text>
</g> Проблемы:
|
Немного про трансформации с SVG vs CSS (много несуразностей) - на тему переворачивания текста и масштабирования толщины линий Transforms on SVG Elements SVG Animation and CSS Transforms: A Complicated Love Story из последнего ссылка на библиотеку для анимации с JS GreenSock's GSAP здесь тоже вычисляют расстояние для перемещения вручную и еще про толщину линий и внешние размеры элемента (такой проблемы нет, но статья хорошая, пусть будет ссылка для коллекции) |
С толщиной линии решается добавлением стиля vector-effect:"non-scaling-stroke" <rect x="0" y="0" width={this.props.fold.dimX} height={this.props.fold.dimY}
style={{fill:"none", stroke:"black", strokeWidth:1, strokeDasharray:"3 3",
vectorEffect:"non-scaling-stroke"}}/> обсуждают такую опцию в Инкскейпе с размером текста так не работает (очевидно)
Не совсем так. Если область viewBox больше, чем область SVG, то в меньшую сторону действительно отмасштабируется (прямоугольник сожмется и впишется в видимую область). Если viewBox меньше, чем область SVG, то прямоугольник останется маленьким (возможно, решается специальной опцией, была статья выше). Еще. Если указать ширину viewBox порядка width=300000000 (300 млн - это 30см в нанометрах, высота аналогично), прямоугольник скукоживается в маленький в левый нижний угол (очевидно, баг), если width=30000000 (убрать один ноль), то ок (во всю область SVG). Очевидно, это где-то близко к пределу размерностей, с которыми работает движок отрисовки/масштабирования. |
По поводу поворота вокруг центра
да, вот так выглядит норм:
<text transform={"scale(1, -1)" + " translate(0, "+(10)+")"}
x={-10} y={0}
style={{fontSize: "12px"}}>0</text>
<text transform={"scale(1, -1)" + " translate(0, "+(10)+")"}
x={this.props.fold.dimX} y={0}
style={{fontSize: "12px"}}>x</text>
<text transform={"scale(1, -1)" + " translate(0, "+(-this.props.fold.dimY)+")"}
x={-10} y={0}
style={{fontSize: "12px"}}>y</text> Но есть еще способ. вот здесь Understanding SVG Coordinate Systems and Transformations (Part 2) — The transform Attribute и здесь (здесь просто CSS) 2.20. CSS3 трансформации пишут про какое-то новое свойство CSS transform-origin, которое можно задать как transform-origin: 50% 50% вот так не работает (тект поворачивается вокруг начала координат) <text transform={"rotate(45)"}
x={-10} y={50}
style={{fontSize: "12px", transformOrigin: "50% 50%"}}>AAA</text> так тоже не работает (поворачивает вокруг начала координат) <text
x={-10} y={50}
style={{fontSize: "12px",
transformOrigin: "50% 50%", transform: "rotate(45deg)"}}>AAA</text> для scale тем более. В инспекторе ок, дело не в реакте <text x="-10" y="50" style="font-size: 12px; transform: rotate(-45deg); transform-origin: 50% 50% 0px;">AAA</text> ДОБАВЛЕНО <text
x={0} y={-10}
style={{fontSize: "12px",
transform: "scale(1, -1)",
transformOrigin: "50% 50%"}}>AAA</text>
вот так текст будет точно в начале координат повернут как нужно <text
x={0} y={0}
style={{fontSize: "12px",
transform: "scale(1, -1)",
transformOrigin: "50% 50%"}}>AAA</text> transformOrigin 50% 50%, кстати, в этом случае тоже не нужен, т.к. для CSS это значение, похоже, стоит по умолчанию. Одна проблема, Inkscape это свойство не поддерживает (точнее, это пока не проблема, пока нет потребности экспортить-импортить такой код). вот так координаты рисовать норм (значение по Y со знаком минус) <text
x={-10} y={10}
style={{fontSize: "12px",
transform: "scale(1, -1)"}}>0</text>
<text
x={this.props.fold.dimX} y={10}
style={{fontSize: "12px",
transform: "scale(1, -1)"}}>x</text>
<text
x={-10} y={-this.props.fold.dimY}
style={{fontSize: "12px",
transform: "scale(1, -1)"}}>y</text> |
Еще про анимацию https://sarasoueidan.com/blog/svg-transformations/
|
Коммит с человеческим вариантом системы координат
Остались проблемы:
|
Здесь основной вопрос порешали - рисуем ванильным SVG без левых прибамбасов, закрываю |
Выбрать движок SVG для React - рисовать рабочую область станка - обычная координатная плоскость.
Требования:
Анимация(плавное перемещение и изменение размера точки - рабочий инструмент). Желательно, с поддержкой родных механизмов React.анимация здесь Анимация SVG в React #3про анимацию отдельно здесь
#3
The text was updated successfully, but these errors were encountered: