Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Профиль создается, когда вы в первый раз заходите в developerWorks. Выберите данные в своем профиле (имя, страна/регион, компания) которые будут общедоступными и будут отображаться, когда вы публикуете какую-либо информацию. Вы можете изменить данные вашего ИБМ аккаунта в любое время.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

XML: Программирование с SVG

Представляет большую часть гибкого и портативного XML языка для графики

Дэвид Мерц, автор, Gnosis Software, Inc.
Author photo
Дэвид Мерц (David Mertz) - большой знаток в области открытых стандартов и только умеренно пугает многословием. С Дэвидом можно связаться по mertz@gnosis.cx его жизнь описывается более подробно на http://gnosis.cx/dW/. Предложения и комментарии по этой, предыдущей или будущей статьям приветствуются. Также вы можете посмотреть книгу Дэвида Text Processing in Python.

Описание:  Масштабируемая векторная графика (Scalable Vector Graphics - SVG) - это XML формат для описания масштабно-независимой графики, который поддерживается многими бесплатными и коммерческими приложениями. В этой статье Дэвид представляет опыт написания SVG скриптов и их использования для анимированных приложений и касается манипуляций с SVG при помощи DOM. Так как SVG файлы представляют собой XML, то мы можем преобразовывать или создавать их с помощью любых средств и библиотек, которые применимы для XML в общем.

Дата:  03.04.2006
Уровень сложности:  простой
Активность:  16741 просмотров
Комментарии:  


До того, как в 2001 году впервые был придуман SVG, были доступны несколько достаточно мощных форматов векторной графики. Postscript и его родственник PDF широко используются во многих приложениях. Множество форматов, специфичных для конкретных приложений, включает Postscript-based Adobe Illustrator (.ai), CorelDRAW (.cdr), Computer Grapher Metafile (.cgm), Windows Metafile (.wmf), Autocad (.dxf), Hewlett-Packard Graphics Language (.hpgl), WordPerfect (.wpg), и множество других. Для векторного рисования (которое даже может включать анимацию, звук и интерактивные свойства) общепринятым средством для информации, распространяемой через интернет, является Macromedia's SWF/Flash.

Основное отличие SVG от всех этих форматов состоит в том, что SVG - это частный случай XML. Это означает не только то, что одинаковые изображения, возможно, будут описываться в SVG намного универсальнее, чем в остальных графических форматах, но и то, что SVG более универсален при программном управлении графикой. В частности, мы можем управлять SVG при помощи интернет - браузеров (или других приложений), используя ECMAScript и Document Object Model (DOM). Важно, что мы можем преобразовывать и создавать SVG с помощью привычных XML-технологий, таких как XSLT, или с помощью библиотек, поддерживающих работу с XML . Можно комбинировать SVG с другими форматами XML, используя пространства имен. Более того, мы можем даже стилизовать SVG с помощью Cascading Style Sheets (CSS). В целом SVG - это дружественный игрок в XML и интернет-пространстве.

Кроме того, что SVG это XML-формат, он также является полностью открытым стандартом, публикуемым W3C (см. Ресурсы). В отличие от большинства форматов векторной графики, упомянутых выше, SVG свободен от действия любых патентов и ограничений охраны авторского права. Спецификация SVG полностью задокументирована. Как и другие W3C стандарты, спецификация сама по себе защищена авторским правом - но в рамках неограничивающих условий W3C, т.е. она позволяет широкое распространение и бесплатное воспроизведение и использование (так, например, никаких соглашений о конфиденциальности не присоединено к спецификации SVG).

Давайте начнем

Приятная особенность SVG: мы можем отображать его в большинстве современных интернет-браузеров непосредственно или используя plug-in. Точное состояние поддержки SVG не поддается точному определению, но используя правильные "заклинания" мы смогли бы отобразить SVG в Firefox/Mozilla, Khtml (Konqueror и Safari), Opera или Amaya. С помощью plug-in из Adobe или Corel можно даже уговорить Internet Explorer показывать SVG. Также существует множество автономных программ для просмотра SVG, многие из которых используют библиотеку Free Software Batik SVG Toolkit (часть Apache XML проекта - см. Ресурсы).

Во многих случаях вы будете видеть SVG файлы как автономные документы. В этих случаях такие файлы будут обрабатываться как MIME тип image/svg+xml, и, в общем случае, будут иметь расширение .svg. SVG файлы, сжатые при помощи Gzip, будут иметь расширение .svgz, и непосредственно поддерживаться большинством средств работающих с SVG. SVG - это просто XML файл с подходящим DTD. Мы убедимся в этом далее на нескольких примерах.

Более того, мы можем вставлять SVG документ в больший документ. В частности - в XHTML страничку. Другие составные XML форматы, такие как OASIS OpenDocument, также поддерживают (или будут поддерживать) встраивание в них SVG файлов. Мы можем включить SVG графику в XHTML страничку тремя способами:

  • Через тег <object>
  • Через тег <embed>
  • Как подключаемое пространство имен

К сожалению, какой именно из этих способов на самом деле будет работать, зависит от вашего браузера и его версии. Например, я создал следующий XHTML документ (его doctype должен поддерживать вложенность пространств имен).


Листинг 1. XHTML документ (svg-nested.html)
				
<?xml version="1.0" standalone="no"?>
<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"

"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>SVG as embedded object and nested namespace</title>
</head>
<body>

<h2>Object tag</h2>
<object type="image/svg+xml" data="standalone.svg">
Your browser is currently unable to display SVG images.
</object>
<h2>Nested namespace</h2>
<svg:svg version="1.1" width="5cm" height="4cm"
      xmlns:svg="http://www.w3.org/2000/svg">
  <svg:title>Four rectangles</svg:title>

  <svg:rect x="0.5cm" y="0.5cm" width="2cm" height="1cm"/>
  <svg:rect x="0.5cm" y="2cm" width="1cm" height="1.5cm"/>
  <svg:rect x="3cm" y="0.5cm" width="1.5cm" height="2cm"/>
  <svg:rect x="3.5cm" y="3cm" width="1cm" height="0.5cm"/>
  <!-- Show outline of canvas using 'rect' element -->
  <svg:rect x=".01cm" y=".01cm" width="4.98cm" height="3.98cm"
       fill="none" stroke="blue" stroke-width=".02cm" />

</svg:svg>
<h2>Embed tag</h2>
<embed id="svg3" src="standalone.svg" />
</body>
</html>
			

Safari/KHTML делают лучшие браузеры из тех, которые я пробовал. Несмотря на это, результаты получаются лучше, если файл имеет расширение .html, чем когда расширение .xml. В общем и целом, <embed> кажется наиболее успешным подходом. Вы могли бы увидеть документ, визуализированный, примерно, так:


Рисунок 1. Отображение svg-nested.html в интернет-браузере
Рисунок 1. Отображение svg-nested.html в интернет-браузере

Кстати, хотя примеры, которые я представляю в этой статье -это достаточно простые сочетания основных форм, текста, цвета, и так далее, SVG вполне способен изображать также сложные и привлекательные рисунки. Для наглядности здесь представлено знаменитое изображение тигра в формате PostScript, которое включено в Ghostscript и другие приложения, сформированное с помощью SVG (я только поправил его размеры):


Рисунок 2. Отображение SVG-картинки с тигром в интернет-браузере
Рисунок 2. Отображение SVG-картинки с тигром в интернет-браузере

Особенности SVG документов

Приведенный выше XHTML пример (см. листинг 1) показал нам основы SVG-графики. Внешний файл, на который там есть ссылка (standalone.svg), содержит такие же элементы, как и те, которые вставлены в XHTML, за исключением дополнительных спецификаторов пространства имен в тегах. SVG дает нам набор графических примитивов, при этом каждый примитив имеет различные XML атрибуты, которые дальше задают графику: цвет, размер, положение, заливку, параметры контура, и так далее. Однако, графические примитивы, такие как эллипсы, прямоугольники или многоугольники (или более усложненные <path> элементы, которые могут включать кубические или квадратические кривые Безье) часто включают внутрь <g> элементов для того, чтобы сгруппировать несколько примитивов вместе. Группа <g> обладает приятной особенностью - мы можем масштабировать, двигать, менять стиль, или другими словами модифицировать ее как целое. Модификации группы применяются к набору форм внутри нее (включая вложенные <g> группы). Это особенно полезно, когда пишется код SVG документов.

Забудьте о правилах

Стоит заметить что SVG документы не представляют собой XML документы в полном смысле этого слова. С точки зрения синтаксиса, SVG - это, несомненно, XML, но важная часть информационного наполнения SVG рисунка содержится внутри данных, разделенных запятыми или пробелами внутри SVG-атрибутов. Когда я говорю о информационном наполнении, я говорю не о XML Infoset, а только о более содержательном понятии: Что она содержит? Это разумный компромисс, так как использование дочерних элементов для каждой точки или дескриптора, который определяет отдельную кривую сделало бы SVG еще более многословным. Таким образом, такие методы обработки XML-уровня, как XSLT, не могут работать с path данными. Например, приведем path элемент квадратичной кривой Безье:


				
	<path d="M200,300 Q400,50 600,300 T1000,300"
      		      fill="none" stroke="red" stroke-width="5"  />
	  

А это многоугольник, описывающий пентаграмму:


				
	<polygon fill="red" stroke="blue" stroke-width="10"
       	      points="350,75  379,161 469,161 397,215
                  423,301 350,250 277,301 303,215
                  231,161 321,161" />
	  

Добавление стиля

Ранее я упоминал, что мы сожем использовать CSS селекторы и синтаксис, чтобы модифицировать вид SVG-рисунков. Как с HTML, так и с форматами, поддерживающими CSS, можно или определить CSS информацию внутри документа, или задать ссылку на внешнюю таблицу стилей. Очень простой пример встроенного CSS:


Листинг 2. Простой CSS пример (inline-styled.svg)
				
<?xml version="1.0" standalone="no"?>
<!-- By ref:
  <?xml-stylesheet href="mystyle.css" type="text/css"?>
-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"

"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="10cm" height="5cm" viewBox="0 0 1000 500"
    xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <style type="text/css"><![CDATA[
      rect {
        fill: red;
        stroke: blue;
        stroke-width: 3
      } ]]>

    </style>
  </defs>
  <rect x="200" y="100" width="600" height="300"/>
</svg>
			

Если мы можем преобразовать любой целый тег с помощью CSS, то мы, возможно, обнаружим, что использование селекторов класса - это наилучшее применение CSS и SVG. Например, мы могли бы определить множество типов прямоугольников в таблице стилей, а затем присоединить XML атрибут class для каждого из них в своем рисунке, вместо того, чтобы повторять полный список цветов, заливок, штриховки, и других атрибутов, которые мы определяем для класса. Простым изменением таблицы стилей, можно изменять общий вид вашей диаграммы для того, чтобы сделать ее более подходящей в различных ситуациях.

Элементы повторного использования

За рамками использования CSS, листинг 2 иллюстрирует другую приятную особенность SVG: мы можем включать доопределенное содержимое внутрь SVG документа - содержимое, которое определяется или внутри, или снаружи визуализируемого документа. Один из способов использовать доопределенное содержимое как часть SVG рисунка - с помощью элемента <image>. В своей идее, <image> в SVG очень похож на тег <img> в HTML: элемент просто заставляет приложение рисовать содержимое внешнего рисунка - которое само по себе может быть или SVG, или растровым изображением в JPEG или PNG формате - внутри текущего SVG контекста. Мы можем изменять размер и размещать внешнее изображение почти так же, как если бы оно было обычным графическим элементом. Например:


Листинг 3. Включение внешнего SVG рисунка в текущее изображение
				
<image x="200" y="200" width="100px" height="100px"

xlink:href="http://example.org/external.svg">
			

Возможно, более интересными, чем тег <image> покажутся дополнительные элементы <defs> и <use>. Первый элемент, который мы видели в CSS примере, позволяет нам создавать SVG элементы, которые при определении визуализируются не непосредственно - обычно модель визуализации SVG рисует каждый объект в точности в таком порядке, как они возникают в SVG документе, причем каждый следующий накладывается на предыдущий. Но <style> немного атипичен в том смысле, что мы на самом деле не можем визуализировать его позднее, сам по себе.

Мы можем включать любые графические элементы, какие хотите, в <defs>, включая <g> группы и элементы <symbol> (символы похожи на группы; но размеры статьи не позволяют подробнее остановиться на этом вопросе). За пределами определения можно использовать (<use>) графические элементы, определенные в рамках <defs> -- даже в <defs> другого внешнего SVG документа. Например:


Листинг 4. Использование доопределенных графических элементов
				
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"

"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="7cm" height="3cm" viewBox="0 0 70 30" version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>'use' with a 'transform' attribute</desc>
  <defs>

    <rect id="MyRect" x="0" y="0" width="40" height="5"/>
  </defs>
  <use xlink:href="#MyRect" transform="translate(10,23) rotate(-30)" />
  <use xlink:href="#MyRect" transform="translate(20,3) rotate(30)" />
  <use xlink:href="http://example.org/foo.svg#OtherRect"/>
</svg>
			

На листинге 4 одинаково определенные прямоугольники визуализированы с использованием двух различных деформаций, а затем также отображается внешне определенный элемент (наименование id наводит на мысль, что это также прямоугольник, но вы не можете быть в этом уверены из его фрагмента - фактически, внешнее содержимое могло бы быть изменено между просмотрами).


Анимация и написание скриптов

Как я уже упоминал, можно писать SVG скрипты, используя ECMAScript. В принципе, это позволяет SVG документам взаимодействовать с пользовательскими действиями. Чтобы поддерживать пространство интернет-приложений, SVG также содержит элемент <a> - такой же, как в HTML - для гиперссылок. Простое взаимодействие, основанное на щелчке кнопки мыши, в SVG модифицирует документ в определенные графические элементы. Пример на листинге 5 - тривиальный, но можно легко обеспечить отклик SVG графики, например, на щелчок (или нажатие) мыши по областям карты или объектам блок-схемы:


Листинг 5. Обеспечиваем отклик SVG формы на щелчок (или нажатие) мыши
				
<svg>
  <title>ECMAScript function for an onclick event</title>
  <desc>Simplified from 
   http://www.w3.org/TR/SVG11/images/script/script01.svg</desc>
  <script type="text/ecmascript"> <![CDATA[
      function circle_click(evt) {
      var circle = evt.target;
      var currentRadius = circle.getAttribute("r");
      if (currentRadius == 100)
        circle.setAttribute("r", currentRadius*2);
      else
        circle.setAttribute("r", currentRadius*0.5);
    } ]]>

  </script>
  <!-- Act on each click event -->
  <circle onclick="circle_click(evt)" cx="300" cy="225" r="100" fill="red"/>
</svg>
			

Мы также можем использовать ECMAScript и DOM для анимации SVG графики. Например, код на листинге 6 создает интересный эффект того, что текст растет и становится менее прозрачным:


Листинг 6. Анимация SVG с помощью JavaScript
				
<svg viewBox="0 0 400 200"
     onload="StartAnimation(evt)" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <script type="text/ecmascript"><![CDATA[
    var txt, step=0;
    function StartAnimation(evt) {
      txt = evt.target.ownerDocument.getElementById("Text");
      ShowAndGrowElement();
    }
    function ShowAndGrowElement() {
      step = step+1;
      if (step > 200) return;
      // Scale text string gradually until it is 20 times larger
      txt.setAttribute("transform", "scale("+ step/10 +")" );
      // Make the string more opaque
      txt.setAttribute("opacity", step/200);
      // Call ShowAndGrowElement again 50 milliseconds later.
      setTimeout("ShowAndGrowElement()", 50)
    }
    window.ShowAndGrowElement = ShowAndGrowElement
  ]]></script>
  <g transform="translate(50,150)" fill="red" font-size="7">
    <text id="Text">SVG</text>

  </g>
</svg>
			

Строгое написание SVG кода

Использование ECMAScript предоставляет нам полную гибкость программирования. Но если все, что мы хотим, это анимация, SVG имеет тег <animate> и связаные с ним теги (такие как <animateMotion> или <animateColor>). Они достаточно гибки и позволяют нам анимировать каждый элемент SVG документа независимо и различными способами. Например, код на Листинге 6 дает тот же эффект расти-и-становиться-непрозрачным, как и методы, показаные на листинге 5:


Листинг 6. Анимация только с SVG
				
<svg viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(50,150)" fill="red" font-size="7">
    <text id="Text">SVG
      <animateTransform attributeName="transform" attributeType="XML"
              type="scale" from="0" to="20" begin="0s" dur="10s"
              fill="freeze" />
      <animate attributeName="opacity" attributeType="CSS"
               from="0" to="1" begin="0s" dur="10s" repeatCount="1" />

    </text>
  </g>
</svg>
			


Вывод

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


Ресурсы

Научиться

Получить продукты и технологии

  • Загрузите Batik - Java технологию, основанную на SVG Toolkit из Apache.

Об авторе

Author photo

Дэвид Мерц (David Mertz) - большой знаток в области открытых стандартов и только умеренно пугает многословием. С Дэвидом можно связаться по mertz@gnosis.cx его жизнь описывается более подробно на http://gnosis.cx/dW/. Предложения и комментарии по этой, предыдущей или будущей статьям приветствуются. Также вы можете посмотреть книгу Дэвида Text Processing in Python.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML
ArticleID=107303
ArticleTitle=XML: Программирование с SVG
publish-date=04032006
author1-email=mailto:mertz@gnosis.cx?subject=Program with SVG&cc=dwxed@us.ibm.com
author1-email-cc=