Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Масштабирование в svg без потери качества (https://javascript.ru/forum/misc/45703-masshtabirovanie-v-svg-bez-poteri-kachestva.html)

simple 12.03.2014 22:43

Масштабирование в svg без потери качества
 
Собственно вопрос в заголовке. Экспериментирую с SVG. Нужно сжать некую структуру элементов в 2 раза по оси Y, картинка получается замыленной из-за трансформации.
<svg>
<g transform="scale(1, 0.5)">
 <path .../>
 <path .../>
 <path .../>
</g>
</svg>


Конечно есть вариант на JS координаты заново пересчитывать при изменения размера окна, но может есть более элегантное решение, подскажите пожалуйста кто знает :)

Aetae 13.03.2014 12:06

viewBox относительный задать. А там уж как хочешь размер самого svg меняй.

simple 23.03.2014 22:33

спасибо, помогло. но появилась новая проблема, цвет линии я явно указываю черным а на деле получается какой то светлосерый, это особенность viewBoxa менять цвет или я что то неправильно делаю?

Aetae 23.03.2014 22:38

simple, если линия однопиксельная попробуй сдвинуть на 0.5px.
Ещё может быть если цвет black, а не #000.(маловероятно)
Но вообще такого быть не должно.)

Octane 23.03.2014 22:45

https://gist.github.com/pepelsbey/1888739

simple 23.03.2014 22:46

ну вот например я так делаю:
<svg width="300" height="300" viewBox="0,0, 3000,3000">
<path d="M1 1 V1500" stroke-width="1" stroke="#000000"/>
</svg>


Мне нужно получить тонкую вертикальную черную линию, а на деле получается очень светлая линия.

Aetae 23.03.2014 23:10

Ну она и получается очень тонкой: 0.1px в данном случае. Какбэ причины "свелости" очевидны, не?)

simple 24.03.2014 14:46

почему 0.1? ведь в stroke-width = 1? а как тогда сделать линии толщиной в 1px что то я не догоняю.

Aetae 25.03.2014 13:18

Хе, хе. В этом весь подвох viewBox.
Тут уж выбирайте - либо относительность размеров, либо точные пиксели.

Цитата:

Сообщение от simple (Сообщение 304022)
почему 0.1? ведь в stroke-width = 1?

Потому что
Цитата:

Сообщение от simple (Сообщение 303956)
<svg width="300" height="300" viewBox="0,0, 3000,3000">

Т.е. на 300 пикселей 3000 точек viewBox'а. А stroke-width(как и всё остальное) считается в этих самх относительных единицах, а не пиксилях. Просто по дефалту они равны пикселям.)

simple 25.03.2014 21:17

Вот теперь до меня дошло, как оказалось я неправильно понял систему координат в viewBox. Спасибо.

т.е получается что бы было все красиво придется все таки расcчитывать на JS координаты и потом уже рисовать по ним. Пытаюсь сделать простенькую визуализацию данных. Знаю что велосипед, просто охота разобраться для себя в тонкостях SVG.

Aetae 25.03.2014 21:34

Ну ещё можно не задавая viewBox указывать размеры простых фигур в процентах и из оных склеивать то что нужно. При этом пиксели остаются пикселями. Вот только баг то или фича - не знаю.)
...
Ещё вот что нагуглил:
Цитата:

vector-effect="non-scaling-stroke" is an SVG 1.2 Tiny feature that forces the stroke width to be exactly what you specify, no matter what scaling or unit transforms are in effect. It is supported by FF and Chrome (maybe others) but not IE (so far) unfortunately. If you can live with that, then it is the simplest solution to your problem.
Вроде работает:
<svg width="300" height="300" viewBox="0,0, 3000,3000">
    <path d="M1 1 V1500" stroke-width="1px" stroke="#000000" vector-effect="non-scaling-stroke"/>
</svg>

simple 25.03.2014 21:47

О, это кажется то что мне нужно! Благодарю!
Хоть цвет и все равно не чисто черный, но это уже что то. Буду копать дальше, должно же что то быть обязательно.

PS. Хотя я наверное изначально неправильно подхожу к задачи. Делаю линейный график цен, на холсте к примеру 600х300, допустим ценовой минимум 2000 и максимум 3000 у графика, вот как это все правильно нарисовать на холсте с заданным размером. Я делаю следующее, прогоняю массив цен на поиск мах и мин значения, вычисляю коэффициент масштаба, создаю новый массив цен по заданному коэффициенту уже подогнанный под размер холста. Рисую. Но что то мне это не очень нравиться. Криво все равно как то.

Aetae 25.03.2014 21:52

simple, если не смущает традиционное "but not IE" - то да.)

Georgiy_M 25.03.2014 23:31

Сейчас тоже работаю с SVG, штатное маштабирование, очень портит картинку. Главный плюс SVG между точками например x1 и X2 не обязательно растояние должно быть целым числом. поэтому самым красивым способом оказалось ввести некий коэфициент(множитель), который вичисляю перед началом прорисовки, а затем на него перемножаю координаты

Aetae 26.03.2014 00:16

Цитата:

Сообщение от Georgiy_M (Сообщение 304314)
Сейчас тоже работаю с SVG, штатное маштабирование, очень портит картинку. Главный плюс SVG между точками например x1 и X2 не обязательно растояние должно быть целым числом. поэтому самым красивым способом оказалось ввести некий коэфициент(множитель), который вичисляю перед началом прорисовки, а затем на него перемножаю координаты

Если масштабировать готовый растр снаружи с помощью css - естесно картинка испортится. При правильном же viewBox вектор остаётся вектором, что мы выше и выяснили.

simple 26.03.2014 11:41

Georgiy_M, https://developer.mozilla.org/ru/doc...hape-rendering

Georgiy_M 26.03.2014 18:09

спасибо за ссылку
 
спасибо за ссылку и за вашу тему, сейчас мне это полезно.
По теме SVG
1 не сталкивалис с проблемой определение координат мыши в блоке SVG? как эту проблему корректнее решать, намекните.

2 MS на своём сайте в разделе для разработчиков описывает применение SVG, но по факту самое полезное в IE не работает.

simple 26.03.2014 20:05

Georgiy_M,
1. Еще не сталкивался. Но думаю ничего сложного, так как SVG - это часть DOM-дерева, следовательно там все также как и с обычными DOM элементами. Вешаем обработчик события и получаем координаты clientX clientY объекта Event.

Если Вы об этом, то:
<svg width="400" height="200" onclick="alert(event.clientX + ' / ' + event.clientY)">
<rect x="0" y="0" width="400" height="200" fill="red" stroke="black"/>
</svg>


2. В IE там другая архитектура, VML называется. Я забил на IE.

simple 30.03.2014 22:08

Кто нибудь знает атрибут cs в теги path за что отвечает? Разбирал библиотеку amCharts и там везде присутствует этот атрибут.
<path cs="100, 100" d="..."/>
Нагуглить ничего по нему не получилось.

Aetae 31.03.2014 00:07

simple, скорее всего левый атрибут, используемый библиотекой. В спеке его нет.

simple 02.04.2014 00:05

Aetae, да так и есть, разобрался. Вот еще прошу объяснить по viewBox, что то я запутался совсем. Создаю холст 600х300, устанавливаю координаты viewBox(0, 0, 800, 600), т.е по оси Х 800/600 = 1.33 единицы на 1 px. Так? Или неправильно я считаю? И рисунок по этим координатам получается не с нулевой точки X как описано в элементе path, а немного смещен в право на процентов 20, почему так? Что я не правильно делаю?

<svg width="600" height="300" viewBox="0,0, 800, 600" shape-rendering="crispEdges">
<path d="M0 10, H10 V140 H0 Z" stroke="#D7523F" fill="#D7523F" vector-effect="non-scaling-stroke"/>
</svg>


А если сделать по оси X 1200px, (0, 0, 1200, 600), т.е в 2 раза больше оригинала, то все нормально рисует.

<svg width="600" height="300" viewBox="0,0, 1200, 600" shape-rendering="crispEdges">
<path d="M0 10, H10 V140 H0 Z" stroke="#D7523F" fill="#D7523F" vector-effect="non-scaling-stroke"/>
</svg>


Конечно можно указать атрибут preserveAspectRatio = "xMinYMid, meet" тогда все выравнивается на любых координатах, но все же почему так получается?

XAPuTOH 07.11.2017 13:13

Наткнулся на эту темку при поиске своей проболеммы:
SVG у меня состоит из других SVG(символы) нарисованных по определенным координатам в головном SVG.
Так вот при масштабировании в сторону уменьшения изображения у символов начинают пропадать элементы. Например есть линия которая при масштабе 100% имеет толщину 2 пикселя. Рисую несколько таких символа рядом. начинаю уменьшать всю картинку. У части символов эта линия пропала. Уменьшаю дальше. У некоторых линии появились а у некоторых пропали.
В общем как-то безконтрольно происходит отрисовка нового масштаба.

Вопрос как победить данный недуг?


Часовой пояс GMT +3, время: 16:38.