svgweb: Нормализация поддержки векторной графики

Старые и допотопные браузеры все больше отходят на задний план, но поддержка пользователей этих браузеров все еще актуальна. Для таких случаев предназначена библиотека svgweb. Её основная цель корректное подключение SVG в HTML-страницы при отображении в разных браузерах. Особенно это касается Internet Explorer, ведь он даже в 9-ой версии не может толком распознать SVG-документы.

В руководстве по svgweb декларируется поддержка элементов video и audio, которая до сих пор не реализована в большинстве современных браузеров.

Использование библиотеки сводится к подключению основного svg.js вместе с использованием странных условных комментариев для разных версий Internet Explorer. Не слишком элегантный способ.

Думаю есть смысл попробовать её в действии.

Опубликовано в: Internet Explorer, JavaScript, JS-библиотека, SVG, Все записи | Помечено | Оставить комментарий

PottisJS: Еще один фреймворк для работы с SVG

Кроме RaphaelJS для работы с SVG есть еще интересные библиотеки. Одной из таких библиотек является PottisJS. Её преимуществами является отсутствие полного закрытия собой элемента SVG. После нее можно спокойно подправить получившееся DOM-SVG-дерево средствами нативного JavaScript. Впрочем, недостатки у нее тоже есть: фреймворк не слишком сильно проверен и находится в состоянии развития.

Использовать его можно следующим образом:
1. Создаем SVG-документ.

<svg id="svgRoot" version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>

2. Подключаем туда библиотеку:

<script xlink:href="pottis.js"></script>

3. Подключаем наш файл script.js

<script xlink:href="script.js"></script>

В котором пишем код:

var svg = document.getElementById("svgRoot");
var pottis = new Pottis(svg);
pottis.shape("circle", { cx: 110, cy: 110, r: 30, fill: "blue" });
pottis.text("Hi, my name is Pottis!", null, 200, 100);

Результат работы

После создания объекта pottis у нас появляется возможность создавать геометрические фигуры, текст, подписываться на события (Drag&Drop, Click), скрывать и показывать элементы и многое другое. Все это в удобной форме, без лишних подготовительных танцев с бубном.

Опубликовано в: JavaScript, JS-библиотека, SVG, Все записи | Помечено , | Оставить комментарий

SVG: Добавляем растровые изображения

Для использования растровых изображений в SVG предусмотрен специальный элемент image. Впрочем, изображение может быть и векторным. Особенно нового тут ничего нет:

<image
  x="0"
  y="20"
  width="100"
  height="100"
  xlink:href="myImage.png"/>

Любопытным атрибутом будет externalResourcesRequired, который может принимать true или false. Он определяет, нужно ли ждать пока внешний ресурс загрузится прежде чем показывать пользователю всю красоту.

Справка по элементу Image от W3C

Опубликовано в: SVG, Все записи | Помечено | Оставить комментарий

DOM: Интересные операции с узлами

Добрались мои руки до манипуляций с DOM-элементами через JavaScript. С родственниками текущего элемента я уже познакомился, создавать новые элементы научился, осталось научиться ими манипулировать.

Хотите клонировать элемент?

На помощь спешит метод cloneNode, который можно вызвать на любом понравившемся элементе с параметром true\false.
true — означает, что нужно брать не только сам узел, но всех его потомков.
false — предполагает, что нам нужен только сам узел.
В результате в ответ мы получим заинтересовававший нас узел.
Например:

var clonedElement = element.cloneNode(false);

Как его можно использовать?

Подменить существующий узел

С помощью метода replaceChild можно аккуратно заменить ненужный элемент. Первым аргументом идет новый узел, а вторым старый. Например, у нас есть элемент в котором есть другой элемент. Заменить старый вложенный элемент на новый можно следующим образом:

element.replaceChild(newElement, element.firstChild);

Встать перед определенным узлом

Для помещения одного узла перед другим можно использовать метод insertBefore. Его нужно вызывать на родительском узле, а в качестве аргументов передавать: новый узел и тот перед которым нужно поставить.

element.insertBefore(newElement, oldElement);

Узел-камикадзе

Для удаления элементов DOM-дерева есть метод removeChild. Часто можно встретить такой код, которым убирают текущий узел:

element.parentNode.removeChild(element);
Опубликовано в: JavaScript, Все записи | Помечено , , , , , | Оставить комментарий

SVG: Элементы video и audio

Оказывается в SVG уже давным давно запланировано богатое Media-содержимое.

В частности, элемент video предполагается использовать следующим образом:

<video
  xlink:href="myMovie.ogg"
  width="320" height="240"
  x="50" y="50"/>

Среди прочих отличий от video из HTML5 я бы выделил довольно типичный для SVG атрибут xlink:href.

Элемент audio, в свою очередь, предполагается похожим образом:

<audio xlink:href="myMusic.ogg"/>

И опять основное отличие от audio из HTML5 в xlink:href.
Примечательно, что в популярных браузерах поддержка этих элементов и тегов не реализована. Что же делать?
Нам на помощь спешит foreignObject. С его помощью можно обратиться к магии HTML5.

<foreignObject>
  <div xmlns="http://www.w3.org/1999/xhtml">
    <video src="videoSample.ogg"></video>
  </div>
</foreignObject>

Вместо выделенного жирным фрагмента можно поместить любой HTML-код.

Вопросы, комментарии и прочие мысли по теме приветствуются!

Опубликовано в: SVG, Все записи | Помечено , , , | Оставить комментарий

Элемент audio из HTML5

Вслед за заметкой про элемент video из HTML5 пришло время разобрать элемент audio, который уже вполне сносно поддерживается в современных браузерах.

Пример HTML разметки

<audio controls="controls">
  <source src="google_chrome_only.mp3"/>
  <source src="firefox_opera_chromium_chrome.ogg"/>
</audio>

Поддерживаемые форматы

В заметке про video-элемент мне сделали резонное замечание про отсутствие внятной информации о поддерживаемых форматах. Исправляюсь.
Элемент audio предполагает поддержку более чем одного формата. На данный момент лучше всего играет OGG. Он поддерживается в браузерах Opera, Firefox, Google Chrome, Chromium. MP3 проигрывается только в Google Chrome. В Internet Explorer версии 9 видна грандиозная белая фига (своими собственными глазами видел). Вероятно в Safari тоже проигрывается OGG, но для моей Ubuntu Safari не выдавали.
Контейнер WAV используется весьма редко, т.к. не принят за стандарт передачи аудио-данных по сети и лично я его стараюсь избегать. В большинстве случаев файлы в формате WAV весят довольно много, а если хорошо упакованы — могут не на всех платформах проигрываться.

Популярные параметры элемента audio

autoplay позволяет браузеру автоматически начать воспроизведение, когда тот будет готов.
controls включает стандартные элементы управления, кнопки: play, pause и управление громкостью.
loop запускает проигрывание музыки по кругу. Про этот атрибут хорошо написал Вячеслав Олиянчук.

Управление элементом audio из JavaScript

Элемент audio поддерживает весь набор методов, событий и свойств элемента video. Точнее, они оба соответствуют интерфейсу MediaElement.

Ссылки:
Элемент разметки audio на сайте W3C
Подробная статья на сайте Opera про HTML5 audio и video
Форматы медиа-содержимого от Mozilla
Документация c сайта Mozilla
Десять отличных HTML5 Audio проигрывателей

Опубликовано в: HTML5, Все записи | Помечено , , , , | Оставить комментарий

SVG: Оформление текста

Пришло время разобраться с тем, как можно придавать «особенное» оформление текстовым фрагментам в SVG.

Начну с простых атрибутов:
Для указания шрифта в SVG можно использовать атрибут font-family.

font-family="arial"

Определить начертание поможет font-style, для него можно использовать всего пару значений: normal и italic. Третье возможное значение oblique практически ничем не отличается от italic, хотя может быть там есть какой-то семантический подтекст. Последнее значение all является дефолтным.

font-style="italic"

Еще одним способом отделить небольшой фрагмент от остального текста является font-variant, который также как и font-style может принимать значение normal. Отличием является второе возможное значение — small-caps.

font-variant="small-caps"

Придать словам вес поможет font-weight, который принимает широкий диапазон значений от чисел 100-900, до именованных normal, bold и all. Думаю в реальной жизни есть смысл ограничиться числами или именованными значениями. Тем более, что на практике разницу между 300 и 400 на мой глаз не видно.

font-weight="800"

Про атрибут font-stretch говорить что-либо бессмысленно, т.к. все значения в браузерах Chrome и Opera для меня выглядят одинаково.
Свойство font-size соответствует всем хтмльным премудростям и в данном случае про него можно промолчать.
смотреть примеры использования этих свойств

Из любопытного стоит отметить следующий набор трюков:
Свойство rotate, может принимать одно или несколько чисел разделенных запятой.
Если число одно — то каждая буква текста будет повернута ровно на этот градус.

rotate="42"

А если чисел несколько, то каждой букве будет соответствовать свой градус.

rotate="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"

kerning и letter-spacing в общем означают одно и тоже свойство — расстояние между буквами. В Chrome работают оба, а вот в Opera атрибут kerning никак не проявляется. Для чего нужно два свойства с одной функциональностью — для меня загадка.

letter-spacing="10"

Свойство word-spacing определяет расстояние между словами.

word-spacing="25"

Подробнее стоит разобрать атрибут text-decoration, который может принимать значения: underline (подчеркивание), overline (надчеркивание) и line-through (зачеркивание).
смотреть как это работает

Это неполный обзор возможностей офрмления текста в SVG. На данный момент многие браузеры поддерживают способы оформления частично, поэтому стоит осторожно присматриваться к новым особенностям и уверенно использовать проверенные.

Ссылки:

Оформление букв и шрифты в SVG
Оформление текста в SVG

Опубликовано в: SVG, Все записи | Помечено , | Оставить комментарий

SVG: Отображение текста

В SVG можно рисовать не только фигуры, но и отображать текст. Сделать это можно с помощью тега <text>. Например так:

<text x="10" y="20">MyText</text>

смотреть

Текст будет отрисован в левом верхнем углу браузера. Для изменения положения текста можно заменить значения атрибутов x и y на другие.

Стоит также отметить, что в SVG нет стандартного способа вывести большой объем текста с автоматическим переносом слишком длинных строк. Все переносы нужно определять явно. Именно для этого предназначен тег <tspan>. Его нужно размещать внутри тега <text>. Предыдущий пример можно развить следующим образом:

<text x="10" y="20">
  <tspan x="10">MyText1</tspan>
  <tspan x="10" dy="1.5em">MyText2</tspan>
  <tspan x="10" dy="1.5em">MyText3</tspan>
</text>

смотреть

В данном случае, у каждого следующего элемента tspan есть атрибут dy, который определяет смещение относительно предыдущего элемента.

Кроме этого есть еще возможность использовать один текстовый фрагмент многократно. Для этого нужно поместить определение текстового фрагмента в секцию def.

<def>
  <text id="mText">MyText</text>
</def>

стоит отметить, что у этого текстового фрагмента бесполезно пытаться определить шрифт, цвет, кегль и прочие параметры. Все это будет недоступно к использованию. Особенности отрисовки лучше поместить в том месте, где текст будет использоваться.
Подключить определенный текстовый фрагмент можно с помощью элемента <tref />

<text x="10" y="20">
  <tref xlink:href="#mText"/>
</text>

смотреть

Для работы атрибута xlink:href нужно подключить соответствующий namespace.

xmlns:xlink="http://www.w3.org/1999/xlink"

О том как и где это нужно делать можно прочитать в заметке про подключение ресурсов в SVG.

Предыдущий пример можно развить до запуска текста по определенной траектории. Для этого опишем в разделе def еще один элемент:

<path id="myPath"
    d="M10,100 Q120,80 200,100 M200,100 Q300,120 400,100" />

о том, как составить параметр d можно прочитать в заметках о простых и сложных контурах в SVG.

После определения пути его можно начать использовать:

<text>
  <textPath xlink:href="#myPath">
    <tref xlink:href="#mText"/>
  </textPath>
</text>

смотреть

С другой стороны, совсем не обязательно подключать текст через ссылку, можно просто поместить его в элемент <textPath/>

Вот вроде бы и все. Если я что-то забыл или перепутал — прошу меня поправить и дополнить.
Темы которые еще нужно рассмотреть:
Оформление текста в SVG

Опубликовано в: SVG, Все записи | Помечено , , , | 1 Комментарий

SVG: Ограничиваем область видимости с помощью clip-path

Сегодня мне посчастливилось узнать еще одну интересную технику работы с SVG. Оказывается, можно нарисовать фигуру, а потом показывать ее по частям. Например, можно определить окружность и потом смотреть на прямоугольник сквозь рамки этой окружности.

Приступим к экспериментам. В SVG-документе создадим элемент clipPath внутри которого опишем окружность, которая и будет формой для обрезки.

<clipPath id="myClip" x="0" y="0">
  <circle cx="120" cy="120" r="70"/>
</clipPath>

теперь в документе можно использовать эту форму следующим образом:

<rect
  id="rect1"
  x="0" y="0"
  width="240" height="245"
  clip-path="url(#myClip)"
/>

в данном случае интересен атрибут clip-path в котором указывается ссылка на форму для обрезки.

Стоит также отметить, что фигур в clipPath можно положить неколько.

А вот и пример использования clipPath

Опубликовано в: SVG, Все записи | Помечено | Оставить комментарий

JS Task: Преобразуем JSON в XML

Пожалуй, пришло время еще для одной задачки. Нужно написать функцию, которая будет получать на вход JSON, а на выходе выдаст XML без потери информации.
Например, на вход получаем:

{
  "head": {
    "nose": "big",
    "eye": ["left","right"],
    "mouth": 1
  },
  "body": {
    "hands": {
      "left": [1,2,3],
      "right": "steal"
    }
  }
}

а на выходе, например, такой XML:

<root>
  <head name="head" type="object">
    <nose name="nose" type="string" value="big"></nose>
    <eye name="eye" type="object" instanceof="Array">
      <item name="item" type="string" value="left"></item>
      <item name="item" type="string" value="right"></item>
    </eye>
    <mouth name="mouth" type="number" value="1"></mouth>
  </head>
  <body name="body" type="object">
    <hands name="hands" type="object">
      <left name="left" type="object" instanceof="Array">
        <item name="item" type="number" value="1"></item>
        <item name="item" type="number" value="2"></item>
        <item name="item" type="number" value="3"></item>
      </left>
      <right name="right" type="string" value="steal">
      </right>
    </hands>
  </body>
</root>

А ведь можно сделать лучше!

Опубликовано в: JavaScript, XML, Все записи | Помечено | 2 Комментариев