Just wanted to let you know a couple of nice tools I’ve been using while incorporating some SVGs into our code. My workflow has been:
- Design SVG in Figma
- Export as SVG (batch export using ctrl shift e)
- Use bash script & Scour to:
- optimize the SVGs in a batch
- convert the filenames to legal cpp variable names
- add
R"svgDELIM(
- Paste the SVGs + variable names into VS Code
- Use Inline SVG Preview to make sure I don’t get things mixed up.
Hope that’s useful.
6 Likes
Sounds pretty cool … tell us more about the “convert filenames to legal cpp variable names” and “add R"svgDELIM(” steps - why are they necessary, what do they provide you, etc?
I dream of a day I can just compose the entire interface for an app in SVG, name things properly, and get a fully integrated component that’s just waiting to be wired up …
2 Likes
Thanks! I didn’t know about Scour and made svg-simplify
to help with two features lacking in JUCE’s SVG implementation. Do you know if those (css rule aggregation so styles come from a single group and inlining masks into gradients) are supported by Scour?
Sorry @yairadix , I’ve don’t really know but I get the impression Scour doesn’t go that deep into converting elements.
@anon48770766, I declare the SVG strings in code as raw strings so I don’t have to worry about escaping quotes, etc. The ‘svgDELIM’ is the raw string delimiter. See
https://en.cppreference.com/w/cpp/language/string_literal
The ‘convert the filenames to legal cpp variable names’ is because in Figma I use variants which get named things like ‘button,size=mini,state=active,mouse=hover’ and I might want to use ‘button_size_mini_state_active_mouse_hover’ as the variable name. So you could have bash generate the declarations for you.
Hope that makes sense…
2 Likes
Sounds cool, would love to see some sample code of how you’re effectively using SVG …
I just learnt, to further tidy your Figma SVGs, uncheck ‘clip content’ in Figma (if you’re not using it). This can remove unecessary defs + attributes in your SVG.
Source: More control over Figma SVG exports: Levi McGranahan
1 Like
Sure. After exporting from Figma and running my little script, I might have something like this:
auto settingsicon_mouse_over =
R"svgDELIM(
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">...</svg>
)svgDELIM";
auto settingsicon_mouse_normal =
R"svgDELIM(
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">...</svg>
)svgDELIM";
auto settingsicon_mouse_down =
R"svgDELIM(
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">...</svg>
)svgDELIM";
These will go to create a DrawableButton, which will be a member of some containing component.
DrawableButton settingsicon;
Then, in the constructor of the component which contains the DrawableButton:
auto x_settingsicon_mouse_over {XmlDocument::parse (String (settingsicon_mouse_over))};
jassert(x_settingsicon_mouse_over != nullptr);
auto d_settingsicon_mouse_over {Drawable::createFromSVG (*x_settingsicon_mouse_over)};
jassert(d_settingsicon_mouse_over != nullptr);
auto x_settingsicon_mouse_normal {XmlDocument::parse (String (settingsicon_mouse_normal))};
jassert(x_settingsicon_mouse_normal != nullptr);
auto d_settingsicon_mouse_normal {Drawable::createFromSVG (*x_settingsicon_mouse_normal)};
jassert(d_settingsicon_mouse_normal != nullptr);
auto x_settingsicon_mouse_down {XmlDocument::parse (String (settingsicon_mouse_down))};
jassert(x_settingsicon_mouse_down != nullptr);
auto d_settingsicon_mouse_down {Drawable::createFromSVG (*x_settingsicon_mouse_down)};
jassert(d_settingsicon_mouse_down != nullptr);
settingsicon.setImages(x_settingsicon_mouse_normal.get(), x_settingsicon_mouse_over.get(), x_settingsicon_mouse_down.get());
settingsicon.setButtonText("Settings");
settingsicon.setClickingTogglesState(false);
settingsicon.setEdgeIndent(0);
_settingsMenuButton.onClick = [this]() { menuButtonClicked(); };
addAndMakeVisible(&settingsicon);
Add to resized()
of the containing component:
settingsicon.setBounds(x, y, w, h);
I believe this is the most up-to-date way to do this with JUCE…
1 Like
Ah yes indeed, this looks like a smooth way to do it - especially given that, to address perhaps a bit of churn that is generated by tweaking/UI, doing builds etc., the code for the constructor could probably be being generated by your script and included in a header, or maybe I misunderstood that it is already?
Just the SVG definitions are being generated at the moment, the rest is in a function for reuse with other components.
To extend the code generation, a big time saver would be to generate code for resized() that arranges components based on Figma’s auto layout…