Integrating Enyo and Snap.svg

edited September 2016 in Enyo 2.7
I am trying to integrate snap.svg in to Enyo and having a problem. The code below works, until render() is called. The problem seems to be that generateHtml in HTMLStringDelegate.js doesn't know about the content added by snap.svg and clears out "svg".

Uncomment "this.render();" to see it.

http://jsfiddle.net/Kloodge/g7MLS/2031/

var ready = require('enyo/ready'),
    kind = require('enyo/kind'),
    Toolbar = require('onyx/Toolbar'),
    Application = require('enyo/Application');

ready(function() {
    var MySample = kind({
        name: "MySample",
        paper: null,
        components: [
            {kind: Toolbar, content: "Your sample here."},
            {tag: "svg", name:"svg"}
        ],
        rendered: function(){
            this.inherited(arguments);
            if(!this.paper && this.$.svg.hasNode()){
                this.paper = Snap("#"+this.$.svg.hasNode().id);
                circle = this.paper.circle(10, 10, 10);
                circle.attr({
                    fill: "#bada55",
                    stroke: "#000",
                    strokeWidth: 5,
               });
               //this.render();
            }
        }
    });

    new Application({view: MySample});
});
Is there any way to do this short of adding the content statically to "svg"?

Comments

  • You shouldn't need to call render() from within the rendered callback as that will restart the render flow which was at completion when rendered was called.

    What was the purpose of adding the render() call?
  • edited September 2016
    It is just to show the problem in the example. In the project, it is called later as things are added and updated dynamically. Any time render is called in the future, svg is getting cleared.
  • Gotcha. In general, I haven't found it necessary to manually call render on a component unless you are changing the hierarchy (and even then you can render individual components/subtrees). But, if you find you must, you're correct that enyo will recreate all children under the assumption they will rebuild their respective subtree. When you're using a third-party library that operates directly on the node outside of Enyo, you'll encounter the kind of issue you are seeing.

    In the case of Snap, it appears it maintains its subtree state within its own object (this.paper in your example) and it doesn't require a node to define that subtree so you can build it outside of rendered and then inject into the DOM during rendered. Here's a quick example based on yours. Tapping the SVG will cause a rerender to show it still renders as expected.

    http://jsfiddle.net/g7MLS/2034/

    Hope that helps!
Sign In or Register to comment.