Monday, August 11, 2014

Simple SVG Images Sometimes are Simpler


I can't remember to remember what I forgot to forget. Or something like that.

A while back, I settled on an asset-based solution for SVG images that relied on AJAX requests to load said assets. This allowed me to work with individual SVG images for the base pizza and toppings like pepperoni, green peppers and sausage. After quite a bit of difficulty working with it, I wound up loading these assets via core-ajax. This was a little awkward, but it did solve some issues I was facing and the solution was bolstered by the fact that it worked in both the Dart implementation as well as the JavaScript equivalent.

Happy to have a decent solution, I quickly moved on to the next challenge. I have not given it another moments thought since… until I tried to screencast the solution. At this point, I am only attempting to generate a proof-of-concept screencast before getting started on the screencasts proper for readers of the “Extras” version of Patterns in Polymer. I hope to produce something in the range of 5-10 minutes and then get down to the real work. Only my first two passes at this project took 30+ minutes to complete.

And so I come back to the core-ajax solution that loads assets thusly:
<link rel="import"
      href="bower_components/core-ajax/core-ajax.html">
<polymer-element name="x-pizza">
  <template>
    <core-ajax
       auto
       id="pizza.svg"
       url="/packages/svg_example/images/pizza.svg"
       on-core-response="{{responseReceived}}"></core-ajax>
    <core-ajax
       auto
       id="pepperoni.svg"
       url="/packages/svg_example/images/pepperoni.svg"
       on-core-response="{{responseReceived}}"></core-ajax>
    <!-- ... -->
  </template>
  <script type="application/dart" src="x_pizza.dart"></script>
</polymer-element>
The effort of typing those in the screencast was a drag, not to mention the responseReceived() callback. So after 30+ minutes of fighting this in the screencast, I finally stopped and asked if there might be an easier way.

There is. The solution that I wind up using will be more SVG-like:
<link rel="import" href="../../../packages/polymer/polymer.html">
<polymer-element name="x-pizza">
  <template>
    <svg
       id="base_svg"
       width="300" height="300">
      <image
         id="svg_pizza"
         width="300" height="300"
         xlink:href="packages/svg_example/images/pizza.svg"></image>
      <image
         id="svg_pepperoni"
         style="display:none"
         width="32" height="32"
         xlink:href="packages/svg_example/images/pepperoni.svg"></image>
    <!-- ... -->
  </template>
  <script type="application/dart" src="x_pizza.dart"></script>
</polymer-element>
This solution is so much cleaner than my core-ajax solution that I have to ask: why on earth would I have used core-ajax in the first place? This SVG approach seems a no-brainer.

And it would be a no-brainer except that my brain has forgotten that the core-ajax loading was done so that I could get direct access to the underlying SVG to manipulate it. Specifically, I wanted to animate filters like drop shadows.

And less than three month removed from that enormous pain, I had completely forgotten it. In my defense, my daughter was only 2 months old at the time, so sleep deprivation was pretty severe. Still I hope that I remember any other important information that I have forgotten that I forgot.

Anyhow, as long as I do not attempt to introduce filters or otherwise manipulate the underlying SVG path of these SVG assets, the <image> approach works just fine:



I really had to get the animation working 3 months ago so that I could properly state that I understood the problem space. That said, I am under no requirement to present the most complete solution in the book or the screencast. In fact, as I have been finding, the most complete solution could very well be inappropriate. So I will switch to this simpler approach, but (maybe) mention the more complex approach.


Day #149

No comments:

Post a Comment