<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>SVG Wow!</title>
    <link>http://svg-wow.org/blog</link>
    <description></description>
    <pubDate>Mon, 03 Mar 2014 21:47:48 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Text Effects</title>
      <link>http://svg-wow.org/blog/2010/09/25/text-effects</link>
      <pubDate>Sat, 25 Sep 2010 15:22:00 EDT</pubDate>
      <category><![CDATA[yui]]></category>
      <category><![CDATA[text]]></category>
      <category><![CDATA[animation]]></category>
      <category><![CDATA[interactive]]></category>
      <guid isPermaLink="true">http://svg-wow.org/blog/2010/09/25/text-effects</guid>
      <description>Text Effects</description>
      <content:encoded><![CDATA[
<div id="description">
    <h3>Running the demo</h3>
    <p>
        Click the 'start svg demo' button on this page. When the page is loaded,
        you can click anywhere on the canvas to start the demo.
    </p>

    <h3>Play time!</h3>
    <p>
        I had never got around to play with SVG text as I wanted to and
        it finally happened with this demo. The demo shows how to
        access the content of SVG <code>&lt;text&gt;</code> elements and animate
        individual glyphs.
    </p>
    <p>
        The demo has a library of 'effects' which are succesively applied to
        quotes (from <a href="http://en.wikiquote.org/wiki/American_proverbs">
            http://en.wikiquote.org/wiki/American_proverbs</a>).
    </p>
    
    <h3>Breaking text into spans</h3>
    <p>
        All the effects work similarly. When applied, they first break down the
        text into a set of text spans which are then animated individually.
        The target text element (or elements, since the effect can apply to
        multiple lines of text) is (are) left unmodified and their display
        property is set to 'none'. The text spans are inserted after the
        text elemenet and are the target of the different animation effects.
        The key DOM API method used in the process of computing individual 
        glyph positions is <code>getStartPositionOfChar</code> on the
        <code>SVGTextContentElement</code> interface (see the
        <a href="http://www.w3.org/TR/2002/PR-SVG11-20021115/text.html#InterfaceSVGTextContentElement">specification</a>).
    </p>

    <p>

<div class="pygments_monokai"><pre><span class="c1">// Compute the different glyph positions and how many characters map to the</span>
<span class="c1">// same glyph position (may happen with ligatures).</span>
<span class="kd">var</span> <span class="nx">p</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
    <span class="nx">pos</span> <span class="o">=</span> <span class="p">[],</span>
    <span class="nx">curPos</span><span class="p">,</span>
    <span class="nx">n</span> <span class="o">=</span> <span class="p">..</span> <span class="cm">/* textContent length */</span>
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">p</span> <span class="o">=</span> <span class="nx">text</span><span class="p">.</span><span class="nx">getStartPositionOfChar</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">curPos</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span>
        <span class="nx">p</span><span class="p">.</span><span class="nx">x</span> <span class="o">!==</span> <span class="nx">curPos</span><span class="p">.</span><span class="nx">p</span><span class="p">.</span><span class="nx">x</span> <span class="o">||</span> <span class="nx">p</span><span class="p">.</span><span class="nx">y</span> <span class="o">!==</span> <span class="nx">curPos</span><span class="p">.</span><span class="nx">p</span><span class="p">.</span><span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">curPos</span> <span class="o">=</span> <span class="p">{</span>
            <span class="nx">p</span><span class="o">:</span> <span class="p">{</span><span class="nx">x</span><span class="o">:</span> <span class="nx">p</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">dx</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="nx">p</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">dy</span><span class="p">},</span>
            <span class="nx">n</span><span class="o">:</span> <span class="mi">1</span>
        <span class="p">};</span>
        <span class="nx">pos</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">curPos</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// Same position, just increase the text run length</span>
        <span class="nx">curPos</span><span class="p">.</span><span class="nx">n</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>



    </p>

    <h3>Effects and animations</h3>
    <p>
        As in several other demos on this web site, the animations are built
        by extending the <a href="http://developer.yahoo.com/yui/3/">YUI 3</a>
        JavaScript and CSS library to support SVG. The code also uses a
        concept of <code>Effect</code> to encapsulate a number of related
        animations so that they can be manipulated as a single abstraction.
        For example, the 'opacity-swipe' effect has one animation on the
        'fill-opacity' of each glyph, each animation starts when the previous
        one ends and the user can run the effect which internally starts the
        first animation, causing the whole animation chain to run. Likewise,
        the user can use the <code>onBegin</code> and <code>onEnd</code> events
        on the effect object to invoke specific code when the effect starts or
        ends.
    </p>
    <p>
        The following code snippet shows how the 'opacity-swipe' effect
        applies to the different text spans.
    </p>
    <p>

<div class="pygments_monokai"><pre><span class="c1">// ...</span>

<span class="c1">// toGlyphSpans is a utility method to break down the text in multiple</span>
<span class="c1">// elements.</span>
<span class="kd">var</span> <span class="nx">spans</span> <span class="o">=</span> <span class="nx">toGlyphSpans</span><span class="p">(</span><span class="nx">text</span><span class="p">),</span>
    <span class="nx">n</span> <span class="o">=</span> <span class="nx">spans</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span>
    <span class="nx">s</span><span class="p">,</span>
    <span class="nx">a</span><span class="p">,</span>
    <span class="nx">anims</span> <span class="o">=</span> <span class="p">[];</span>

<span class="c1">// duration, offset and easing a defined somewhere else in the code.s</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">s</span> <span class="o">=</span> <span class="nx">spans</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
    <span class="nx">a</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Animate</span><span class="p">({</span>
        <span class="nx">node</span><span class="o">:</span> <span class="nx">s</span><span class="p">,</span>
        <span class="nx">from</span><span class="o">:</span> <span class="p">{</span><span class="s1">&#39;fill-opacity&#39;</span><span class="o">:</span> <span class="mi">0</span><span class="p">},</span>
        <span class="nx">to</span><span class="o">:</span> <span class="p">{</span><span class="s1">&#39;fill-opacity&#39;</span><span class="o">:</span> <span class="mi">1</span><span class="p">},</span>
        <span class="nx">duration</span><span class="o">:</span> <span class="nx">duration</span><span class="p">,</span>
        <span class="nx">easing</span><span class="o">:</span> <span class="nx">easing</span>
    <span class="p">});</span>
    <span class="nx">anims</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">a</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">for</span> <span class="p">(</span><span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
     <span class="nx">anims</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">onBegin</span><span class="p">(</span><span class="nx">anims</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">i</span> <span class="o">*</span> <span class="nx">offset</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// The Effect utility provides a way to manipulate a group of animations</span>
<span class="c1">// as a single entity.</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Effect</span><span class="p">(</span><span class="nx">anims</span><span class="p">);</span>
</pre></div>



    </p>
    <h3>Music and Font</h3>

    <p>
        Music by <a href="/attributions.html#text-effects-audio">Roger Kidd</a>
        (with all my thanks).
    </p>

    <p>
        The font used in this demo is "GoodDog" and can be found on
        <a href="http://www.fontsquirrel.com/">Font Squirrel</a>. See the
        <a href="/attributions.html">attributions</a> page.
    </p>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
