-
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
Рисовать метки на осях координат и рабочий инструмент одним размером вне зависимости от масштаба рабочей области #8
Comments
Так, самый правильный способ масштабировать одну часть картинки и не масштабировать вторую - мог бы быть использовать атрибут vector-effect="non-scaling-size" (по аналогии с vector-effect="non-scaling-stroke" для немасштабируемой толщины линии). Проблема в том, что эта фича есть в черновике спецификаций SVG 2.0: Но вообще нигде не реализовано. Обсуждение в багзиле Мозилы (есть патч, но не хотят добавлять, пока в остальных браузерах не изъявят желание добавить фичу тоже) еще обсуждение для Мозилы (есть предложения с альтернативами) Тикет для Хромиума Инкскейп Таблица фич SVG2 - строка 40 (нигде не рализовано) Еще варианты Non Scaling Objects / constrained transforms => Preserve descendant elements' size while scaling the parent element
Keeping SVG elements to a fixed size while position scales Еще предлагают использовать elem.getCTM() в яваскрипте (в этом случае еще придется отлавливать события масштабирования). var circle = document.getElementById('c');
var root = document.getElementById('root');
var matrix = circle.getCTM();
circle.r.baseVal.value /= matrix.a; Еще getCTM() и другие варианты Scale independent elements How to draw non-scalable circle in SVG with Javascript |
еще близко к теме Как попасть мышкой в элемент на отмасштабированном SVG SVG coordinates with transform matrix ответ в виде интерактивного демо: How do you convert screen coordinates to document space in a scaled SVG? везде предлагают использовать getScreenCTM() про режимы мастшабирования с viewBox и preserveAspectRatio в SVG единицы измерения SVG |
How to Scale SVG
предлагают использовать вложенные блоки SVG |
про масштабирование (изменение размера окна) - есть событие onresize. https://www.w3schools.com/JSREF/event_onresize.asp <body onresize="myFunction()"> Но приклеить его можно только к окну window или тегу body (на div не сработает). В реакте сделал следующее: render: function() {
window.onresize = function() {
console.log("resize");
}
...
} все работает, сыпет в консоль сообщениями при любом изменении размеров окна или страницы. |
Для радиуса кружочка сработало вот так: window.onresize = function() {
console.log("resize");
var circle = document.getElementById('tool_x_y');
var matrix = circle.getCTM();
circle.r.baseVal.value = toolMM.z_radius / matrix.a; здесь toolMM.z_radius - целевое значение радиуса (вычисленное заранее или константа). делать так, как в примере выше (использовать значение радиуса из элемента): circle.r.baseVal.value /= matrix.a; нельзя, т.к. при множественных изменениях размеров окна значение радиуса в дефолтное значение сбрасываеться не будет и при множественных делениях на коэффециент улетит в ноль. |
Решение с кружочком и надписями, не зависящими от масштаба. Еще осталось разобраться с крестиком внутри кружочка с рабочим инструметом (это понятно) и боковыми отступами (это, похоже, будет похитрее). это отрабатывает только при изменении размеров окна: render: function() {
var lab_txt_size = 12;
window.onresize = function() {
//console.log("resize");
var circle = document.getElementById('tool_x_y');
var matrix = circle.getCTM();
document.getElementById('tool_x_y').r.baseVal.value = toolMM.z_radius / matrix.a;
document.getElementById('lab_xy_0').style.fontSize = lab_txt_size / matrix.a;
document.getElementById('lab_x').style.fontSize = lab_txt_size / matrix.a;
document.getElementById('lab_y').style.fontSize = lab_txt_size / matrix.a;
document.getElementById('lab_z_0').style.fontSize = lab_txt_size / matrix.a;
document.getElementById('lab_z').style.fontSize = lab_txt_size / matrix.a;
}
...
} при перересовке (и даже первой отрисовке) виджета средствами реакта колбэк вызван не будет и масштаб может быть покорежен. Помогает вот такой хак (или, может, вполне справедливое решение): componentDidMount: function() {
window.onresize();
},
componentDidUpdate: function() {
window.onresize();
} componentDidMount вызывается после первой отрисовки виджета, componentDidUpdate - после каждой перерисовки, оба - после render (это значит, что все элементы уже отправлены в ДОМ). React.Component, The Component Lifecycle |
готово дело |
не зависят от текущего масштаба:
|
Подзадача отсюда отдельным тикетом
Выбрать движок SVG для React: система координат
#2
При достаточно большом реальном размере рабочей области 300000x200000 (микрометры) с масштабированием рабочей области к видимым размерам на экране было две проблемы:
С полем 300x200 в обоих случаях всё ок.
Первая проблема решилась добавлением стиля vector-effect:"non-scaling-stroke" к линии или прямоугольнику
#2 (comment)
Со второй проблемой нужно разобраться в этом тикете.
Видятся решения:
для затравки:
How to Scale SVG
https://css-tricks.com/scale-svg/
там идет тема, как сделать разные области SVG с разным масштабом
The text was updated successfully, but these errors were encountered: