Tonight seems a good opportunity to verify that my recent approach to an SVG Polymer custom element will work as well in JavaScript as it has in Dart.
I start with a
bower update
which, thanks to my non-explicit version dependency in bower.json
installs Polymer 0.3.1:➜ js git:(master) ✗ grep -C1 Polymer/polymer bower.json "dependencies": { "polymer": "Polymer/polymer" } ➜ js git:(master) ✗ bower update ... polymer#0.3.1 bower_components/polymer ├── core-component-page#0.3.1 └── platform#0.3.1 ...I fire up a Python simple server (it's in my shell history):
➜ js git:(master) ✗ python -m SimpleHTTPServer 8000 Serving HTTP on 0.0.0.0 port 8000 ...And... everything still works:
Refreshing.
It works, but those are the in-application drawn SVG elements:
// ...
_svgSausage: function() {
var el = document.createElementNS("http://www.w3.org/2000/svg", "circle");
el.setAttribute('r', '3');
el.setAttribute('fill', 'brown');
return el;
},
// ...
In the Dart version, I switched to an asset loading approach that lent itself better to a designer workflow. I relied on the <core-ajax>
Polymer element in Dart, so let's see how it works in JavaScript. I add core-ajax to the list of dependencies:➜ js git:(master) ✗ bower install -S Polymer/core-ajax
Then, I copy the SVG assets into the JavaScript version of this
<x-pizza>
element:➜ js git:(master) ✗ mkdir assets/images ➜ js git:(master) ✗ cp ../dart/lib/images/* assets/images/ ➜ js git:(master) ✗ ls assets/images green_pepper.svg pepperoni.svg pizza.svg sausage.svgNext, I teach the template to use
<core-ajax>
to load these assets. I need the appropriate <core-ajax>
tags for each asset and need to link in the core-ajax.html
definition:<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../bower_components/core-ajax/core-ajax.html"> <polymer-element name="x-pizza"> <template> <core-ajax auto id="pizza.svg" url="../../assets/images/pizza.svg" on-core-response="{{responseReceived}}"></core-ajax> <!-- ... --> </template> <script src="x_pizza.js"></script> </polymer-element>The rest of the effort flows fairly smoothly from here. I no longer have Futures, so I use a state variable to tell the graphics when all SVG toppings have loaded:
// ...
svgContent: {},
svgLoaded: false,
responseReceived: function(e, detail, node){
this.svgContent[node.id] = detail.response;
var numLoaded = Object.keys(this.svgContent).length,
numDefined = this.shadowRoot.querySelectorAll('core-ajax').length;
if (numLoaded == numDefined) {
this.svgLoaded = true;
this._updateGraphic();
}
if (node.id == 'pizza.svg') this._updateGraphic();
},
/* Start SVG Code */
svg: null,
_updateGraphic: function() {
this.$['pizza'].innerHTML = this.svgContent['pizza.svg'];
if (!this.svgLoaded) return;
this._addWholeToppings();
this._addFirstHalfToppings();
this._addSecondHalfToppings();
},
// ...
That aside, this follows the core-ajax loading convention that I was able to use in Dart closely. Well, except that manipulating SVG in JavaScript is ugly as sin: _svgSausage: function() {
var ns = "http://www.w3.org/2000/svg";
var group = document.createElementNS(ns, "g");
group.innerHTML = this.svgContent['sausage.svg'];
var svg = group.querySelector('svg');
var mouseCircle = document.createElementNS(ns, "circle");
mouseCircle.setAttribute('r', '15');
mouseCircle.setAttribute('cx', '15');
mouseCircle.setAttribute('cy', '15');
mouseCircle.setAttribute('style', 'opacity:0');
group.appendChild(mouseCircle);
// ...
}
Compare that to the equivalent Dart: _svgImage(basename) {
var svg = new GElement()
..append(
new CircleElement()
..setAttribute('r', '15')
..setAttribute('cx', '15')
..setAttribute('cy', '15')
..setAttribute('style', 'opacity:0')
)
..append(new SvgElement.svg(svgContent['$basename.svg']));
// ...
}
Method cascades and proper constructors really help. That aside, the JavaScript code flows nicely given my experience from Dart. I will likely take tomorrow to see if there are any JavaScript specific improvements that I can realize (maybe checking out snap) , but this seems promising.Day #86
No comments:
Post a Comment