tangrams / tangram

WebGL map rendering engine for creative cartography
https://tangram.city
MIT License
2.22k stars 290 forks source link

SVG manipultaion via scene.yaml #727

Closed Tonidor closed 5 years ago

Tonidor commented 5 years ago

I'm currently trying to manipulate the color of some POI icons (SVG) and I need them to change whatever is not white. Is it possible to target a specific fill component via the tangrams draw/color property?

This is a part of my scene.yaml of the layer I wish to change:

    layers:
        containers:
            data: {source: containers}
            draw:
                container:
                    order: function() { return feature.sort_rank; }
                    priority: 2
                    size: global.feature_size
                    color: global.get_color
                     interactive: true

This is the funtion getColor that is referenced above:

  get_color: |
    function () {
    var b= {'r':1,'g':0,'b':0}
    var a= {'r':0,'g':1,'b':0}
    var total = 0;
    for(var idx in feature.pins.questions){
                var question = feature.pins.questions[idx]
                if (question.hasOwnProperty("answers"))  {
                    total += question.answers.length;
                    }
        }

total = total <= 0? 0 : total >= 100 ? 100 : total;

    var t = total / 100;
    var color= [a.r + (b.r - a.r) * t,
            a.g + (b.g - a.g) * t,
            a.b + (b.b - a.b) * t]
    return color;
    }

Icon style:

<style>
 .cls-1{isolation:isolate;}.cls-2{opacity:0.6;mix-blend-mode:multiply;}.cls-3{fill:#fff;}.cls4{fill:#37474f;}
</style>

This is how it look's so far: image

bcamper commented 5 years ago

Unfortunately you cannot access the raw SVG like that, because it's already been rasterized into a WebGL texture by that point. The rasterization is quite low-level in the browser, it's the result of creating an <img>/Image with the SVG as src.

Interesting idea though! :)

bcamper commented 5 years ago

Sorry I actually misinterpreted what you were trying to do.

You can apply color to SVG icons, but by default it's going to just multiply the color you provide the pixel value of the SVG. So white pixels will end up being the color you set (white is all 1 * color). Black pixels would stay black (0 * color). Other colors will multiply component-wise. So you might be able to arrange that to work. Or, you could also write a custom style (under styles) and use a filter shader block to do something more custom: https://tangrams.readthedocs.io/en/latest/Overviews/Shaders-Overview/#filter