14.12.2010

Ужыванне эфектаў SVG да кантэнту HTML

* Source text URL: http://weblogs.mozillazine.org/roc/archives/2008/06/applying_svg_ef.html





Уводзіны

Адна са стандартных вэб праблем тое, што цяжка выкарыстоўваць магчымасці SVG, накіраваныя на падвышэнне ўтрымання HTML. Напрыклад, няма ніякага разумнага спосабу для таго, каб замацаваць элемент HTML для не-прастакутнай вобласці, ці ўжыць альфа-маску да элемента HTML, ці ўжыць эфекты апрацоўкі малюнкаў, такія як колер маніпуляцыі каналамі для HTML элементаў. SVG мае гэтыя функцыі, але яны могуць быць ужыты толькі да SVG элементаў. Вы можаце ўстаўляць HTML у <foreignObject>, але гэта мае сур’ёзныя абмежаванні, у прыватнасці, вы не можаце ўжываць эфекты да HTML элементаў з дапамогай табліц стыляў без змены разметкі — капіявання з утрымання і пакласці яго ў выродлівыя фрагменты SVG –і парушэнне саміх CSS макетаў у гэтым працэсе.

Адзін з падыходаў да рашэння гэтай праблемы з’яўляецца стварэнне новых уласцівасцяў CSS для жаданага эфекту. Dave Hyatt рабіў гэта трохі ў Webkit, і падыход мае сваё месца. Аднак для складаных эфектаў такіх, як абразанне для адвольных формаў і карыстацкі модуль апрацоўкі малюнка, CSS насамрэч не да задачы. Адной з праблем з’яўляецца тое, што ў CSS не добрае кіраванне структураванымі каштоўнасцямі, такімі, як формы і фільтр апрацоўкі стэка- яны грувасткія; каб напісаць у CSS сінтаксіс выразу, яны патрабуюць новыя карыстацкія CSS сінтаксісы (напрыклад, @-кіраванне), і няма ніякіх стандартных DOM, каб сцэнары маніпулявалі кампанентамі гэтых структураваных значэнняў. Іншае пытанне ў тым, што мы павінны імкнуцца пазбягаць дублявання спецыфікацыі і рэалізацыі складаных функцый.

Так што я эксперыментаваў з больш эфектыўнымі спосабамі ўжывання SVG-эфектаў да ўтрымання HTML. Першым крокам з’яўляецца зрабіць SVG у “кліп-шляхі“, “Маска” і “фільтр” уласцівасцяў працы ва ўжыванні да ўтрымання HTML.

Clip-шляхі

Вось некаторая разметка XHTML, якая адсякае элементы да таго, каб фармаваць складзены прастакутнік з кола побач.

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:svg="http://www.w3.org/2000/svg">

<body style="background:#ccc; font-size:30px;">

<style>

p { width:300px; border:1px solid black; display:inline-block; margin:1em; }

iframe { width:300px; height:300px; border:none; }

b { outline:1px dotted blue; }

</style>

<p class="target" style="background:lime;">

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt

ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>

<iframe class="target" src="http://mozilla.org"/>

<p>Lorem ipsum dolor sit amet, consectetur adipisicing

<b class="target">elit, sed do eiusmod tempor incididunt

ut labore et dolore magna aliqua.</b> Ut enim ad minim veniam.</p>

<style>.target { clip-path: url(#c1); }</style>

<svg:svg height="0">

<svg:clipPath id="c1" clipPathUnits="objectBoundingBox">

<svg:circle cx="0.25" cy="0.25" r="0.25" id="circle"/>

<svg:rect x="0.5" y="0.2" width="0.5" height="0.8"/>

</svg:clipPath>

</svg:svg>

</body>

</html>

Такім чынам, мы палучаем блокавы элемент, <iframe>, і ўсе ўбудаваныя элементы абразаюцца ў clipPath. ClipPath формы маюць каардынаты адносна абмежавальнай рамкі з абразаемым аб’ектам.

Вось візуалізацыі:

ok

Вы не можаце бачыць яго ў гэтым прыкладзе, але хіт-тэставання залежаць ад ClipPath, як вы і чакалі; падзеі ад націску мышы ў адсечанай вобласці праходзяць да элемента (ам) ўнізе.

Адзін са складаных кропак інтэграцыі з’яўляецца апрацоўка элементаў, якія генеруюць некалькі CSS скрынак, такія як убудаваныя элемент тут. Я не чакаю выразку і маскіроўку, каб знайсці вялікія карысці там, але фільтры могуць быць карыснымі для Inlines. Падыход, які робіць большасць сэнсу ўжывання эфектаў да ўсіх элементаў адразу, і робіць SVG “абмежавальным у рамках аб’екта” прастакутнікам аб’ядноўвае ўсе межы скрынак для элемента і яго геаметрычных нашчадкаў, а таксама любыя абрысы на элементах ці нашчадках. Гэта карысна, а таксама ўяўляецца ў адпаведнасці з духам спектру SVG.

СlipPath маскі і фільтраванне змесціва можна таксама выкарыстоўваць у “userSpaceOnUse” адзінак. У SVG “прасторы карыстача” ўсталёўваецца праглядам SVG, утрымоўвалым адпаведнаму ўтрыманню. У нас няма такога вакна для не-SVG-змесціва, таму я раблю “прасторы карыстача” прастакутнікам, які з’яўляецца аб’яднаннем ўсіх меж-боксаў для пацярпелых элементаў. Прасторы карыстача ў CSS піксельных блокаў, як і ў clipPath масках і фільтраванні змесціва, можа паказаць даўжыню ў CSS пікселях, а таксама адсотак у адносінах да памеру пацярпелых элементаў.

Сцэнары

Лёгка дадаць дынамізму ў прыведзеным вышэй прыкладзе:

<button onclick="toggleRadius()">Toggle radius</button><br/>

<script>

function toggleRadius() {

var circle = document.getElementById("circle");

circle.r.baseVal.value = 0.40 – circle.r.baseVal.value;

}

</script>

SVG DOM не такі чысты, як гэта магло быць, але гэта досыць.

маскі

Замяніце блок “clip-path” вышэй “Маскай”:

<style>.target { mask: url(#m1); }</style>

<svg:svg height="0">

<svg:mask id="m1" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">

<svg:linearGradient id="g" gradientUnits="objectBoundingBox" x2="0" y2="1">

<svg:stop stop-color="white" offset="0"/>

<svg:stop stop-color="white" stop-opacity="0" offset="1"/>

</svg:linearGradient>

<svg:circle cx="0.25" cy="0.25" r="0.25" id="circle" fill="white"/>

<svg:rect x="0.5" y="0.2" width="0.5" height="0.8" fill="url(#g)"/>

</svg:mask>

</svg:svg>

Зараз прастакутнік будзе афарбаваны напаўпразрыстым градыентам і форма, якая выкарыстоўваецца, будзе як альфа-маска, а не проста абразанне.

Вось візуалізацыі:

ok

Па спектру SVG маскі не ўплываюць на хіт-тэставанні, таму мерапрыемствы будуць атрыманы нават там, дзе ўтрыманне маскіруцца. Гэта было б разумна, калі ажыццяўляць SVG паказальнік падзей уласнасці для не-HTML-утрыманняў, каб даць аўтарам спосаб барацьбы з гэтым.

Фільтр

Замяніце блок “Маска” з некаторымі фільтрамі:

<style>

p.target { filter:url(#f3); }

body:hover p.target { filter:url(#f5); }

b.target { filter:url(#f1); }

body:hover b.target { filter:url(#f4); }

iframe.target { filter:url(#f2); }

body:hover iframe.target { filter:url(#f3); }

</style>

<svg:svg height="0">

<svg:filter id="f1">

<svg:feGaussianBlur stdDeviation="3"/>

</svg:filter>

<svg:filter id="f2">

<svg:feColorMatrix values="0.3333 0.3333 0.3333 0 0

0.3333 0.3333 0.3333 0 0

0.3333 0.3333 0.3333 0 0

0 0 0 1 0"/>

</svg:filter>

<svg:filter id="f3">

<svg:feConvolveMatrix filterRes="100 100" style="color-interpolation-filters:sRGB"

order="3" kernelMatrix="0 -1 0 -1 4 -1 0 -1 0" preserveAlpha="true"/>

</svg:filter>

<svg:filter id="f4">

<svg:feSpecularLighting surfaceScale="5" specularConstant="1"

specularExponent="10" lighting-color="white">

<svg:fePointLight x="-5000" y="-10000" z="20000"/>

</svg:feSpecularLighting>

</svg:filter>

<svg:filter id="f5">

<svg:feColorMatrix values="1 0 0 0 0

0 1 0 0 0

0 0 1 0 0

0 1 0 0 0" style="color-interpolation-filters:sRGB"/>

</svg:filter>

</svg:svg>

Фільтры халодные, таму я вырашыў трохі перабраць тут. Блок элементаў атрымлівае ў краі выяўленне скруткі фільтра. <iframe> канверсуецца ў адценнях шэрага. Убудаваныя элементы размыты. Пры навядзенні курсора на цела, замяніце фільтры; <iframe> атрымлівае ў краі выяўлення фільтру, блок атрымлівае пераўтварэння каляровога каналу, які прымае альфа-канал для зялёнага канала, ствараючы Punch-Out эфект, і ўбудаваны элемент атрымлівае 3D-эфект асвятлення.

Вось візуалізацыі:

ok

ok

Фільтры не ўплываюць на хіт-тэставанні.

Абмеркаванне

Усе гэтыя эфекты цалкам жывуць. Вы можаце абраць маштабаванне, змену DOM, выклікаць contenteditable і г.д., і ўсё выдатна працуе. Эфекты ўжываюцца для нанясення адбору і нават малюнак курсору ў той час, як ён знаходзіцца ў пацярпелых элементах.

Эфекты наступных мадэляў складае SVG, калі элемент мае фільтр, абразанне і маскіроўкі, то фільтр ужываецца ў першую чаргу варта адсячэнні і/ці маскіроўкі. Яны паводзяць сябе як CSS “празрыстасць” у тым, што яны індукуюць псеўда-кладкі кантэксту для элемента. Яны не ўплываюць на макет, хоць “фільтр” можа вырабіць маляванні за межамі элемента (напрыклад, цяні). У наш час у маёй рэалізацыі “фільтр” можа насамрэч уплываць на макет, таму што калі “Фільтр” афарбован за межамі элемента, то можна паказаць палосы прагорткі, так што карыстач можа пракручваць, каб убачыць перапоўненыя фарбы, але я думаю, што гэта варта лічыць памылкай.

Паколькі мы яшчэ не падтрымліваем выдаленыя спасылкі ўтрымання ў Gecko, вы павінны пакласці эфекты ўбудаваных фрагментаў у дакуменце. Гэта выродліва, а таксама азначае, што вы не можаце выкарыстоўваць гэтыя эфекты ў не-XML HTML. Як толькі мы рэалізуем спасылкі на выдаленыя ўтрыманні, гэтыя праблемы знікнуць, аўтары CSS табліцы стыляў змогуць зрабіць спасылкі эфектаў у дапаможных дакументаў SVG. Шматлікія эфекты могуць быць захаваны ў адзіны дакумент SVG, амартызаваць кошт дадатковых рэсурсаў. Аўтары нават у стане выкарыстоўваць такія прылады, як Inkscape для стварэння SVG-эфектаў і спасылкі на іх з CSS.

У спектры ўзроўняў ёсць вельмі мала, што трэба сказаць. Няма новых сінтаксіса і не патрабуецца. У спецыфікацыях павінна быць напісана дакументаванне рашэнняў па пытаннях, якія я згадаў вышэй (не абавязкова ж рашэнні, якія я зрабіў).

Замест спектру мы павінны вырашыць, колькі з гэтага ўзяць у Gecko і калі. Прыемна, што няма новага сінтаксісу, але гэта таксама азначае, што няма зручнага спосабу выкарыстання-МОЗ прэфікса, каб ізаляваць нестандартныя функцыі. Мы маглі б стварыць новыя “-moz-filter’/’-moz-clip-path’/’-moz-mask” ўласцівасці, якія паводзяць сябе як існыя уласцівасці, акрамя таго, яны таксама дастасоўныя да HTML. Можа быць, гэта не варта. Сёе-тое для абмеркавання.

Я раблю tryserver прама цяпер, і я буду абнаўляць гэты пост са спасылкай, калі яны будуць гатовыя. Вось спасылка на мой рэпазітар Mercurial. (Нажаль, я выпадкова пхнуў копіі НССБ і NSS да гэтага рэпа, так што не слепа выцягвайце з яго, калі ў вас усё ў парадку з гэтым.) Некалькі дэма:

clipPath

маскі

Фільтр

У нейкі момант я адпраўлю адказ пра іншую працу, якую я зрабіў на гэтай галіне, што вядзе да гэтых функцый, з некаторай больш падрабязнай інфармацыяй пра рэалізацыю. Таксама я планую дадаць яшчэ некалькі асаблівасцяў хуткім часам.

У бок

Прыемны пабочны эфект падавання больш SVG-HTML інтэграцыі з’яўляецца тое, што яна дае SVG вагу на вэб. Вы не можаце рабіць усе гэтыя эфекты з дапамогай Flash ці Silverlight, а паколькі яны не стандарты, то яны, верагодна, ніколі не будуць запрошаны ў гэтай партыі.

Абнаўленне Mac будавання, Linux будавання, Windows зборкі.

ok ok