Can I create composite/layered SvgIcons in material-ui? - svg

I would like to make custom SVG Icons by layering two or more existing material-ui icons together. For example, add a "+" icon layered over the top of another icon to indicate "Add ".
For example, if I want to make something similar to the AddAPhoto icon, but I'm adding a store, I would like to layer the "Add" icon on top of the "Storefront" icon.
I can't seem to find any documentation or examples of this, but I swear I've seen it done in the past. (It may have been Font Awesome)
Edit:
After playing around with things for a while I'm getting close. This gives me what I'm after, except the "Add" icon needs to have an opaque background to cover up what's under it.
import SvgIcon from "#material-ui/core/SvgIcon";
import StorefrontIcon from "#material-ui/icons/Storefront";
import AddIcon from "#material-ui/icons/Add";
<SvgIcon color="action" style={{height: 200, width: 200}}>
<AddIcon color="secondary" viewBox="0 0 50 50" />
<StorefrontIcon/>
</SvgIcon>

Related

Do I really just have three colors?

I have an Angular Material application.
The application has a button to click. I want it to look nice so I make it <button mat-button>Hello Button</button>.
Now I want to make the button show up in the "accent" color of my theme so I change it to <button mat-button color="accent">Button</button>. Works great.
Now I want to make the button show up as a slightly darker version of the "accent" color so I change it to <button color="accent A600">Slightly Darker Button</button>. No, that's definitely not it.
I read around Stack Overflow a bit and try some things and find that I can create a CSS class and apply that class to my button, but there's not really a way to say "make this my theme's accent color but a bit darker." It's just straight up hardcoding a color value.
As far as I can tell, Angular Material has "palettes" that I can't access in any meaningful way.
My question: Is it really true that button colors in Angular Material can only be "primary" or "accent" or "warn" or bypass the palette system altogether? What do I have to do to access the various lighter and darker shades on the palettes?
Or more directly, what goes in the [color] attribute? <button mat-button [color]="what-goes-here?">Slightly Darker Button</button>?
I think the easiest thing to change button color is to make something like this:
Inside your HTML:
<button mat-raised-button color="something">Click on me</button>
color="something" will generate a class then you will be able to make this in CSS:
.mat-success{
color: yellow;
background: purple;
}

Possible to use SVG sprites without needing <svg> for each instance?

I'm attempting to move from font icons (icomoon.io) to SVG sprites. Is it possible to use SVG sprites without needing < svg > markup for each icon instance?
What I really liked about the font icons was that I didn't have to clutter my HTML with any additional elements to get the icon to display. I usually just targeted a simple class on whatever element I wanted the icon to display and then used pseudo selectors to display the icon, e.g.:
<h1 class="news">News</h1>
h1.user:before {
font-family: 'icons';
content: '\news';
}
That made a lot of sense to me, and all of my icons were easily managed almost completely in CSS. I rarely had to touch my HTML as long as my markup contained appropriate classes.
I've since switched my build system to Grunt and thought I'd give SVG sprites a try. Almost every1 article2 I3 can4 find5 on the subject says you need to add an additional SVG element to your markup wherever you want each instance to display, e.g.:
<h1>
<svg class="icon">
<use xlink:href="#icon-news">
</svg>
News
</h1>
That seems like a step backwards to me, at least in the management of markup. To me, an icon is usually presentation that should be separate from document structure. Are we doing it this way simply because of the state of SVG support in browsers?
Ideally, I'd love to be able to do something like this:
<h1 class="news">News</h1>
h1.news:before {
display: inline-block;
width: px;
height: px;
background: url(icons.svg#news) no-repeat;
}
This post seems to be closer to what I'm looking for, but I'm not sure of browser support and how to do it automatically in a build system like Grunt.
SVGs can be loaded as files exactly the same way as other images using <img> tags or CSS background, and can be used as sprites exactly the same way too. The only difference is that you have to specify the size you want it (because it's scalable, so the browser doesn't automatically know how big it is like it does with PNGs).
Depending on how you want to use the image, loading them this way may or may not be suitable as some SVG features aren't available, but it can be done.

Targeting a g id in an SVG for rollovers

I'm working with an SVG file that has been output from Adobe Illustrator, so there is probably quite a bit of unnecessary code. After searching and searching I was able to come up with this.
<?xml-stylesheet type="text/css" href="SVG_css.css"?>
path:hover{
fill:#005289;
}
which gets the rollovers to work from the external stylesheet, but it of course targets every path as a rollover.
For instance, I need to target paths in a group so three elements highlight when rolled over. here is the code structure from Illustrator.
<g id="WIRE_ROOM">
<path fill="#BCBEC0" d="M357.3,24.4c0,0.6-0.6,1-1.4,1h-8.1c-0.8,0-1.4-0.5-1.4-1v-8.9c0-0.6,0.6-1,1.4-1h8.1c0.8,0,1.4,0.5,1.4,1
V24.4z"/>
<path fill="#BCBEC0" d="M357.3,51.4c0,0.6-0.6,1-1.4,1h-8.1c-0.8,0-1.4-0.5-1.4-1v-8.9c0-0.6,0.6-1,1.4-1h8.1c0.8,0,1.4,0.5,1.4,1
V51.4z"/>
<path fill="#BCBEC0" d="M376.7,24.4c0,0.6-0.6,1-1.4,1h-8.1c-0.8,0-1.4-0.5-1.4-1v-8.9c0-0.6,0.6-1,1.4-1h8.1c0.8,0,1.4,0.5,1.4,1
V24.4z"/>
</g>
I've tried associating the ID to the stylesheet, and didn't have any luck...I also tried associating a class directly into the SVG.
If I add class="locations" to the path it of course only rolls over that one element and not the group of elements. When I added the class like this nothing happened. g id="WIRE_ROOM" class="locations"
I would appreciate if someone could assist me with this, as I've searched and tried everything I know to try.
So in the case of "WIRE_ROOM" those are different pieces of equipment, and I need the hover to highlight all 3 of those areas to signify one common area. Thank you!
For future reference, the selector you're looking for is g#WIRE_ROOM:hover path or g.locations:hover path (I'd recommend using the class instead of an ID).
The hover state on the group is triggered when any of the child elements are moused-over, and then the selector applies the hover style to all the child paths.
You have to specifically mention the paths in the selector -- you can't rely on inheritance -- because your file directly sets fill colors on the paths, which takes precedence over any inherited style.

Change multiple colors of a SVG object

I have a SVG logo rendered to the canvas using fabric.js, the original SVG is all black in color but I need the user to be able to change the color of each different parts of the logo, resulting in a object with multiple colors, e.g.:
wikimediauruguay.org/images/5/53/Wikimedia-logo.png
How can I achieve this? If I just use object.setFill() it changes the color of the entire object but I need to change the color of every part separately to whatever colors the user choose. Thanks.
EDIT: found the solution, just posted my answer below in case somebody else has the same question.
Perhaps someone who knows something about fabric.js would answer in a way that makes more sense for your case, but with plain old svg, an object is often a <g< element with things ( like <rect>, <path>, <ellipse>) inside. Each child of the group, can have its own event handler:
<g>
<path onclick='handle(evt)' attrs=stuff />
<rect onclick='handle(evt)' attrs=stuff />
<circle onclick='handle(evt)' attrs=stuff />
</g>
The function activated by the click can then interrogate evt.target to see which of the subelements received the click, sorta like this:
if (evt.target.nodeName=="path") {evt.target.setAttribute("fill","purple")}
Solved mi problem in a very simple way: I just needed to edit the SVG on Illustrator so that every different colored part of the logo will be on a different layer, then when I loaded the SVG via fabric.loadSVGFromURL() each layer will be treated as a different object by fabric.js, then I just could edit each object (layer) separately (setFill(), etc).

Generating SVG font from multiple SVG graphics in Node.js

I'd like to create a Node.js app that allows users to combine a bunch of SVG icons into a custom web-font icon set. The only similar project I've found is this site which looks interesting but is pretty buggy.
Eventually I'd like this app to also output all the various cross-browser font files and the CSS to use these icons on a page using best practices. So the overal goal is to create an SVG icon framework.
But the first thing I want to get working is combining multiple SVG icons into a SVG font file. Must be possible if the above mentioned site is doing it but I'm having trouble finding any good info.
Could anyone point me in the right direction? Thanks!
Edit: I came across this service which looks very similar to my goal although I don't want to host the fonts and I'd like my service to be free (and possibly open-source as well).
Kind of late, but if anyone else will need it, i think this will do: https://github.com/sapegin/grunt-webfont
Like many of my big ideas, someone thought of it first :)
For anyone who may come across this, check out Keyamoon's font generator tool.
If you want to automate things there is an NPM package called svg-font-create.
Glyphter.com handles multi-path icons so that might be a good resource for you as well.
You may try svg-join for combine multiple SVG in one symbol collection.
This tool create two files for you.
The first is "svg-bundle.svg":
<svg ...>
<symbol id="svg1" ...>
<symbol id="svg2" ...>
</svg>
Every symbol is your separate SVG file.
The last one is "svg-bundle.css":
.svg_svg1,
.svg_svg2 {
width: 20px; // for example
height: 20px;
}
Now you may use it in your html:
<link rel="stylesheet" type="text/css" href="svg-bundle.css" />
...
<svg class="svg_svg1"><use xlink:href="svg-bundle.svg#svg1"></svg>
<svg class="svg_svg2"><use xlink:href="svg-bundle.svg#svg2"></svg>

Resources