ilyachalov (ilyachalov) wrote,
ilyachalov
ilyachalov

Category:

JavaScript: плющим мяч, язык SVG

Начало:
1. CSS: абсолютное позиционирование и содержащий блок
2. JavaScript: гоняю мяч по полю, CSS-анимация

В предыдущем посте при решении задачи «Передвиньте мяч по полю» к подразделу 2.1 «Введение в браузерные события» второй части учебника по JavaScript я написал, что наше решение универсально и будет работать при любых размерах HTML-элемента, представляющего мяч.

В окончательном варианте решения в стиле мяча ширина и высота HTML-элемента img, представляющего мяч, указаны со значениями 40px:
  #ball {                      /* стиль мяча */
    position: absolute;        /* позиционируем мяч относительно поля */
    left: 0;
    top: 0;
    width: 40px;
    height: 40px;
    transition: all 1s;        /* включить анимацию */
  }

Если менять эти размеры так, чтобы ширина и высота мяча оставались равными друг другу, то есть чтобы мяч оставался круглым, то всё работает так, как следует. (Но, наверное, не стоит задавать слишком маленькие маленькие размеры, вроде 1px, тогда мяч будет плохо видно, либо слишком большие размеры, вроде 250px, тогда мяч будет виден (вернее, часть мяча будет видна), но его невозможно будет двигать, потому что размеры мяча превысят размеры поля.)

Вот так футбольное поле и мяч выглядят в моём браузере при ширине и высоте HTML-элемента, представляющего мяч, в 20px:



Хорошо, а что произойдет, если мяч не будет круглым? Зададим, например, ширину HTML-элемента, представляющего мяч, в 35px, а его высоту оставим равной 20px. Я временно задал в стиле мяча границу HTML-элемента с красным цветом указанием border: 1px solid red;, чтобы было понятно, где находится граница этого элемента. Вот что получилось у меня в браузере:



Как видно на картинке, HTML-элемент img, представляющий мяч, растянулся на заданную ширину (высота осталась прежней), но изображение мяча не растянулось. При этом наша функция moveBall для передвижения мяча по щелчку мыши работает так, как требуется по условиям задачи, потому что она, как уже говорилось выше, универсальна. Но из-за того, что мяч не растянулся на заданную ширину, создается неприятное впечатление, будто справа и слева от мяча есть невидимое пространство (если убрать из стиля мяча красную границу), не дающее мячу приблизиться впритык к правой и левой сторонам футбольного поля (с верхней и нижней сторонами поля всё в порядке).

В чём проблема? Дело в том, что изображение мяча для HTML-элемента img, представляющего мяч на заданной в задаче HTML-странице, берется из файла формата SVG:
<img src="https://ru.js.cx/clipart/ball.svg" id="ball">

В отличие от растровых форматов изображения, вроде JPG, GIF или PNG, файл формата SVG представляет из себя не бинарный, а текстовый файл. Аббревиатура «SVG» расшифровывается как «Scalable Vector Graphics», что по-русски значит «масштабируемая векторная графика». Файл формата SVG написан на языке разметки SVG, визуально похожем на язык HTML. В файле SVG изображение задается с помощью тегов, содержащих информацию о ключевых точках изображения и другую информацию. При масштабировании изображения в формате SVG, как следует из названия этого формата, изображение не теряет качества (не замыливается и не пикселизируется), как при масштабировании изображений в растровых форматах.

Если в нашем случае изображение мяча преобразовать из формата SVG в растровый формат, то при изменении размеров HTML-элемента img будет соответственно меняться и размер содержащегося в этом HTML-элементе растрового изображения. Проблем не будет.

В случае же изображения в формате SVG его поведение при машстабировании содержащего его HTML-элемента img регулируется из самого этого файла SVG.

Я открыл файл ball.svg в текстовом редакторе и увидел, что корневой тег представляет из себя следующее:
<svg width="40px" height="40px" viewBox="0 0 40 40" ...>
  <!-- ...другие теги... -->
</svg>
На месте многоточия в теге svg в файле есть и другие свойства, но я не стал их оттуда выписывать, так как для темы данного поста они не имеют значения.

Так как я не разбираюсь в языке SVG, то почитал в интернете и узнал, что в данном случае (если в теге svg присутствует свойство viewBox) поведение изображения при масштабировании содержащего его HTML-элемента можно регулировать с помощью свойства preserveAspectRatio в теге svg. Вот так:
<svg width="40px" height="40px" viewBox="0 0 40 40" preserveAspectRatio="none" ...>
  <!-- ...другие теги... -->
</svg>

Тут подробнее:
https://css-tricks.com/scale-svg/

Я подредактировал файл ball.svg так, как было указано выше, и запустил заданную в задаче HTML-страницу с нашим скриптом для передвижения мяча. Теперь всё работает так, как требуется:



Теперь мяч можно плющить хоть по горизонтали, хоть по вертикали и менять размеры, как угодно.
Tags: Образование, Программирование
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments