'Customizing a Blockly toolbox' img field with svg inside ???

428 views
Skip to first unread message

Licorne Magique

unread,
May 24, 2021, 6:47:27 PM5/24/21
to Blockly

Hi,
I was working on tweaking toolbox, again, and while I was loking at using svg as icon (https://blocklycodelabs.dev/codelabs/custom-toolbox/index.html?index=..%2F..index#5) I tried something that seems impossible.

In "createIconDom_()", the "const iconImg = document.createElement('img');" cannot be "converted in const iconImg = document.createElement('svg'); ", is that true?
I wanted, like an icon, when it's selected, add something like this : "this.iconDom_.style.fill = this.colour_;" but if it's not a svg field it's impossible.

Do you have any idea to help me?
May thanks.

Licorne Magique

unread,
May 24, 2021, 7:14:12 PM5/24/21
to Blockly
Update, the next code works but I still have no svg in white in my toolbox....

    createIconDom_() {
        const iconImg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        iconImg.setAttribute("width", "25px");
        iconImg.setAttribute("height", "25px");
        iconImg.setAttribute("version", "1.1");
        iconImg.style.verticalAlign = "middle";
        iconImg.style.fill = 'white';
        iconImg.setAttribute("src", "./media/" + this.toolboxItemDef_['toolboxitemid'] + ".svg");
        return iconImg;
    }

Beka Westberg

unread,
May 25, 2021, 4:42:51 PM5/25/21
to blo...@googlegroups.com
Hmm that's weird.

I'm not super familiar with the new toolbox code, but it looks like it should be appended if you're returning the element from your function... Are you overriding the createDom_ method as well? Or just the createIcondDom_ method? If you're overriding both make sure your createDom_ method is correctly appending your icon.

Other things you might try for debugging:
1) Examine the elements of your page to see if the icon exists, but isn't visible.
2) Double check that the path to your toolboxitem.svg is correct.
3) Post the complete code for your toolbox so that people here can try it out.

I hope that gives you some places to start! Best wishes,
--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/902cb2ce-bd14-4c44-aae7-866d393c8bf2n%40googlegroups.com.

Licorne Magique

unread,
May 25, 2021, 4:58:21 PM5/25/21
to Blockly
Hi,
here's my code:

class TweakCategories extends Blockly.ToolboxCategory {
    constructor(categoryDef, toolbox, opt_parent) {
        super(categoryDef, toolbox, opt_parent);
    }
    addColourBorder_(colour) {
        this.rowDiv_.style.backgroundColor = colour;
    }
    setSelected(isSelected) {
        var labelDom = this.rowDiv_.getElementsByClassName('blocklyTreeLabel')[0];
        if (isSelected) {
            this.rowDiv_.style.backgroundColor = 'white';
            labelDom.style.color = this.colour_;
            this.iconDom_.style.fill = this.colour_;
        } else {
            this.rowDiv_.style.backgroundColor = this.colour_;
            labelDom.style.color = 'white';
            this.iconDom_.style.fill = 'white';
        }
        Blockly.utils.aria.setState(/** @type {!Element} */(this.htmlDiv_), Blockly.utils.aria.State.SELECTED, isSelected);

    }
    createIconDom_() {
        const iconImg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        iconImg.setAttribute("width", "25px");
        iconImg.setAttribute("height", "25px");
        iconImg.setAttribute("version", "1.1");
        iconImg.style.verticalAlign = "middle";
        iconImg.style.fill = 'white';
        iconImg.setAttribute("src", "./media/" + this.toolboxItemDef_['toolboxitemid'] + ".svg");
        return iconImg;
    }
}

Thanks to debugger in Chromium, I see that the icon exists, and if I change the balise from 'svg' to 'img' it appears.
Thanks for helping.

Beka Westberg

unread,
May 26, 2021, 6:13:24 PM5/26/21
to blo...@googlegroups.com
Oh der I should have thought of that! Glad it's working for you now. Best of luck on your project :D
--Beka

Licorne Magique

unread,
May 26, 2021, 7:25:14 PM5/26/21
to Blockly
Well no it does not work as I wanted , sorry :-D
With SVG balise, I wanted it to change from white to category colour. But if I use img balise, the svg file stays black.
I hope finish my project (just a starter pack in fact :-D) in june and publish a v1with automatic typing.
Thanks for your help, hope you have a new idea...

Beka Westberg

unread,
May 27, 2021, 4:29:53 PM5/27/21
to blo...@googlegroups.com
Hmm, so the issue is just changing the color of the svg icon? Do any of the solutions posted here work for you?

And publishing your project is super exciting! Be sure to post here once you're ready to show it off to people :D I'd love to check it out.

--Beka

Licorne Magique

unread,
May 27, 2021, 4:57:45 PM5/27/21
to Blockly
I cannot understand why it does not work. The SVG file exists, as I explained with img balise, but impossible to change fill attribute. Here's is my inspector on toolbox:
Image 1.png
But it has no effect at all on SVG file, none of your solution worked. Sorry.
And I choosed SVG file to change color of icons, the same way as text in the Toolbox Codelab. Maybe I should change to png with filter instead...

And yes of course I'll publish it here, all on Apache licence or BSD3 for some other project based on it, it will also replace BlocklyDuino with a v2(020) because I started few releases last year.

Licorne Magique

unread,
Jun 6, 2021, 4:59:18 AM6/6/21
to Blockly
Hi,
sorry to annoy you, but is there a bug on toolbox ? or something impossible to do? Does SVG supported or not ?
Maybe this could be in documentation.
Many thanks.

Beka Westberg

unread,
Jun 6, 2021, 5:25:16 PM6/6/21
to blo...@googlegroups.com
Hello,

I don't think it's an issue with the toolbox, I think the issue is just that SVG cannot be colored using CSS in this way. Although I could be wrong, I'm definitely not an SVG or CSS expert haha.

I think you might be able to change it using css filters rather than the fill attribute? (link, link) but again I really don't know :/

Sorry I can't be more help :/
--Beka

Licorne Magique

unread,
Jun 7, 2021, 9:45:31 AM6/7/21
to Blockly
Many thanks for your help.
I already tried your links, but after 2hrs on this, I needed to use invert style, and add js to calculate invert filter values from rgb...
Well it works but it's surelly not a good solution.
Meanwhile I needed to use img balise to use my tweak code, not working with svg, very weird...
Thanks.

Maribeth Bottorff

unread,
Jun 7, 2021, 9:57:43 PM6/7/21
to Blockly
Hi,

This problem isn't specific to the toolbox, but just trying to use svg in html. I'm not an expert in svg, so maybe someone who knows more can offer more insight, but from what I can tell, trying to use css on an external svg isn't supported. You're using an external svg because you're referencing an external URL. However, I don't think your markup is correct. You can either use the img tag, like you did get working, or an object. For example, the following code works for me:

createIconDom_() {
var toolboxIcon = document.createElement('object');
toolboxIcon.setAttribute('type', 'image/svg+xml');
return toolboxIcon;
}

But this is still an external svg, and you can't use css to change it. You may be able to do something like the second answer here: https://stackoverflow.com/questions/9872947/changing-svg-image-color-with-javascript where you get the SvgDocument separately. Then you could get the internal path names and alter their styles.

Otherwise, you could inline your svg, so instead of having an <object> that references a file, you put the svg code directly in. If you open your svg in a text editor, you'll see all the svg code. If you were to put that directly into the code, it would be an "inline" svg, and you might have an easier time styling it. https://css-tricks.com/using-svg/#using-inline-svg
Here's some other ideas and links: https://stackoverflow.com/questions/22252409/manipulating-external-svg-file-style-properties-with-css , researching "inline" vs "external" svg

So to summarize, this problem is related to styling svgs in general, and not a problem specific to the toolbox. The toolbox should support an svg in the icon dom.

Licorne Magique

unread,
Jun 8, 2021, 4:32:16 AM6/8/21
to Blockly
Hi,
many thanks for all this explanation I understand the behaviour of SVGs much better. It allows me to understand why using an img or svg tag does not have the same impact in the toolbox.
I had used the same method as you, but I choosed not to use the SVG path modification but a filter, like in this example: https://codepen.io/sosuke/pen/Pjoqqp
That way I can put the svg I want and still have the same behaviour as with the Font Awesome icons.
Thank you very much for all these details.
Reply all
Reply to author
Forward
0 new messages