I use Inkscape to edit existing SVG files like this one (simplified, for readability purposes):
<svg>
<style type="text/css">
.st0{fill:#AFAA96;stroke:#AFAA96;stroke-miterlimit:10;}
.st1{fill:none;stroke:#738282;stroke-width:16;stroke-miterlimit:10;}
</style>
<rect x="0.5" y="0.5" class="st0" width="99" height="99"/>
<path class="st1" d="M10 10"/>
</svg>
As you can see, there are 2 css classes "st0" and "st1", applied to a <rect> and a <path>
I don't want the SVG to contain CSS classes.
I need that every SVG element contains all the corresponding styles of the associated class.
Is there a way, using Inkscape, to transform (automatically) the previous SVG into this ?
<svg>
<rect x="0.5" y="0.5" width="99" height="99" fill="#AFAA96" stroke="#AFAA96" stroke-miterlimit="10"/>
<path fill="none" stroke="#738282" stroke-width="16" stroke-miterlimit="10" d="M10 10"/>
</svg>
Thankyou in advance :)
Current solution inside inkscape:
select all
cut
paste (now all objs will get direct styling)
remove linked CSS styles from selected objects in CSS dialog
when all objects unlinked from any styles, you can remove empty styles.
Related
I'm using an external svg file for my graphics. I have a few that are multi color and look something like this.
<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">
<symbol viewBox="0 0 300 220" id="some_logo">
<path id="shape01" d="...." />
<path id="shape02" d="...." />
<path id="shape03" d="...." />
</symbol>
<symbol>...</symbol>
<symbol>...</symbol>
<symbol>...</symbol>
</svg>
of course using it in the HTML looks like this.
<svg>
<use xlink:href="../../assets/symbol_sprite.svg#some_logo" />
</svg>
The problem I'm having is I would like to target the #shape01, #shape02 and #shape03 ids to apply different css fills. So far I tried
<use xlink:href="../../assets/symbol_sprite.svg#some_logo/#shape01" />
<use xlink:href="../../assets/symbol_sprite.svg#some_logo#shape01" />
<use xlink:href="../../assets/symbol_sprite.svg#some_logo>#shape01" />
just to see if I could find a way of targeting them but nothing happened. I went to googling everything I could think of that might get a result but didn't get anything. How can we target those elements?
Basic needs:
I am working on a Qt application that replaces colors in an svg.
A nice implementation is to parse the svg xml, and replace the colors as found with a good color match.
Unfortunately, the application must run on a platform with very limited speed and memory, and loading the svg into the QSvgRenderer from an xml (or text string) is extremely slow.
So - my current implementation is to string replace the occurrences of hex known colors in the QByteArray loaded by the renderer.
A big limitation - if I want to replace a fill color with a pen color, and they match, I end up with a broken blob.
A second limitation: I can only have 2 defined colors, a fill and a pen.
What I would like:
I want to be able to create a "parameterized" svg, where I can replace "color1", "color2", "color3" defined at the top, with whatever colors the user chooses.
Note - the svg has to be loaded by the QSvgRenderer, so the parameter values can't be in an outside html or js.
The svg must be self-contained... with no outside caller requirement.
But I can replace in code the parameter value before load.
I just want to be able to replace parameters in a single location, instead of actual values inside the xml everywhere they occur.
What I have tried:
I have read in the svg documentation that it is possible to create parameterized values. This is from an example, as much as I understand it...
w3.org example
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 110 40" width="100%" height="100%">
<title>Reusable Button</title>
<desc>Takes parameters from parent document's embedding element.</desc>
<defs>
<ref id="paramFill" param="color" default="blue"/>
<ref id="paramText" param="text-label">button</ref>
<ref id="paramStroke" param="outline" default="navy"/>
</defs>
<g>
<rect id="button_rect" x="5" y="5" width="100" height="30" rx="15" ry="15" fill="url(#paramFill)" stroke="url(#paramStroke)" />
<text id="button_label" x="55" y="30" text-anchor="middle" font-size="25" fill="black" font-family="Verdana">
<tref xlink:href="#paramText" />
</text>
</g>
</svg>
Unfortunately Qt doesn't load it and browsers show as error.
Second example: from S.O: Define color in SVG
<?xml version="1.0"?>
<svg width="704" height="702" xmlns="http://www.w3.org/2000/svg">
<style>
.myfill { fill:red }
</style>
<g fill="blue">
<rect x="0" y="0" width="704" height="702" class="myfill" />
</g>
</svg>
This loads in browser correctly as red, but Qt loads it with blue - so clearly it does not support the parameter value.
Is there any possible version of svg that uses parameters, that can be supported by Qt ?
Can somebody please help fix either of my examples or give a correct / better example ?
Thank you.
Qt version: 4.8
A long, long time ago, when some SVG renderers did not support style sheets, I solved this with XML entities:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY red "#ff0000">
]>
<svg width="704" height="702" xmlns="http://www.w3.org/2000/svg">
<g fill="blue">
<rect x="0" y="0" width="704" height="702" fill="&red;" />
</g>
</svg>
Background
I have a set of SVG icons that all have drop shadows. To make this work in Chrome, I can't just use filter:drop-shadow. I have to use filter:url(#drop-shadow), and define the drop shadow in my <defs> section.
I also have multiple instances of these icons on the page (they are filetype icons in a list of files), so I am using <use> to keep my page DRY.
Code
Exernal SVG File
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<filter id="drop-shadow">
<feGaussianBlur xmlns="http://www.w3.org/2000/svg" in="SourceAlpha" stdDeviation="4"/>
..... more filter lines, shortened for brevity
</filter>
</defs>
<symbol id="download-pdf">
<path filter="url(#drop-shadow)" d="" fill="">...</path>
</symbol>
<symbol id="download-zip">
..... another icon
</symbol>
... more icons
</svg>
Inline SVG on the Page
<svg>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="URL_OF_EXTERNAL_SVG"></use>
</svg>
See minimal working example here: http://h.andymercer.net/chrome-svg-bug/
Problem
The problem is that Chrome isn't finding the #drop-shadow link, and so is breaking the icons. Firefox, conversely, displays the icons perfectly.
Firefox:
Chrome:
If you notice, the Chrome screenshot DOES show some portion of the icon. It is displaying the portions that don't use the drop shadow filter.
I can't figure out why this is, because the drop shadow is in the <defs> that is on the same page as the <symbol>.
Question
Is there something I am missing, or is this a Chrome bug?
Edit
Per comments, I was asked for a MCVE. I hadn't done that because the problem inherently requires external URLs, which is typically frowned upon here. However, to demonstrate the problem, take a look at this:
http://h.andymercer.net/chrome-svg-bug/
In Firefox, you can see the icon. In Chrome, it is blank.
In Chrome, <defs> must be located inside the same <svg>.
In your case:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<filter id="drop-shadow">
<feGaussianBlur xmlns="http://www.w3.org/2000/svg" in="SourceAlpha" stdDeviation="4"/>
</filter>
</defs>
<symbol id="download-pdf">
<path filter="url(#drop-shadow)" d="" fill="">...</path>
</symbol>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#download-pdf"></use>
</svg>
Conforming to modern browsers capabilities, it's easier and cleaner to create different external svg files, one for each icon, then embed them using <object> or <img> tags.
<object> lets javascript access and modify SVG code via DOM, while <img> embed SVGs denying DOM access to them. So, in your case using <img> should be a better choice.
Please I want to know how to make something similar to sunrise using css3.
Below is a sample.
This article (though it talks about animating the rays also) decribes making a suburst pattern http://designrshub.com/2013/01/css3-keyframe-animations.html.
But, I would use an svg image. See Is Starburst effect doable in CSS3?
the SVG:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="512px" height="512px" viewBox="-256 -256 512 512"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Burst</title>
<defs>
<g id="burst">
<g id="quad">
<path id="ray" d="M0,0 -69,-500 69,-500 z" />
<use xlink:href="#ray" transform="rotate(30)"/>
<use xlink:href="#ray" transform="rotate(60)"/>
<use xlink:href="#ray" transform="rotate(90)"/>
</g>
<use xlink:href="#quad" transform="rotate(120)"/>
<use xlink:href="#quad" transform="rotate(240)"/>
</g>
<radialGradient id="grad" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" stop-color="white" stop-opacity="0.65"/>
<stop offset="100%" stop-color="black" stop-opacity="0.65"/>
</radialGradient>
<!-- a circle mask -->
<mask id="m"><circle r="256" fill="white"/></mask>
</defs>
<!-- added a mask and scaled it to a different aspect ratio below. scale(x,y) -->
<g mask="url(#m)" transform="scale(1, 0.75)">
<use xlink:href="#burst" fill="lightslateblue"/>
<use xlink:href="#burst" fill="darkslateblue" transform="rotate(15)"/>
<circle r="360px" fill="url(#grad)" />
</g>
</svg>
Yes, it is possible.
Working demo: https://codepen.io/lethargic/full/RRYdxX
I've written a vanilla CSS version as well as a Sass mixin at github.com/pestbarn/starburst.css.
Cross-browser?
As far as I can tell, yes. Needs testing in IE versions below 11, but seems well supported otherwise (full browser support as of 2019).
Animatable?
Yep, like you would animate any other elements.
Caveats?
Alas, there is. Using colors that are far from another on the color wheel will create jagged edges. I'd recommend using colors that are close to one another.
Also, since the effect is created using pseudo elements, you will in some cases need to explicitly set the element's height and width.
Using the Sass mixin, you can simply do the following:
#include starburst(both, 11, #184256, #194052);
This will create a starburst/sunburst effect with the colors you asked for, with the bursts being 11 degrees apart (smaller number = tighter burst).
I have easily made a mask with a PNG (black circle, transparent background) and using -webkit-mask-image:url(images/mask.png) for browsers like chrome. But i am having serious issues getting the mask to show in Firefox using SVG
<svg>
<defs>
<mask id="mask" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
<image width="78px" height="78px" xlink:href="images/mask.png"/>
</mask>
</defs>
<foreignObject width="78px" height="78px" style="mask: url(#mask);">
<img src="images/avatar-sample.jpg" />
</foreignObject>
</svg>
I really cannot see why this isn't working!
According to http://www.w3.org/TR/SVG/propidx.html you can apply a mask to container elements and graphics elements. Unfortunately <foreignObject> is in neither of these lists so the correct rendering for that element is to ignore the mask property. IE and Firefox are therefore correct in their rendering of this example.
Because IE does not understand the "foreign" object, you have to work around it with javascript and check if you can support it, if so inject it in, and if not avoid it. then you have to use IE's built in color filters to create your own chromakey effect specifically for IE. this site below shows you how to do it with examples.
http://thenittygritty.co/css-masking
You could rewrite your svg like this to make it work in all svg-supporting browsers:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="mask" maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse">
<image width="78" height="78" xlink:href="images/mask.png"/>
</mask>
</defs>
<image xlink:href="images/avatar-sample.jpg" width="78" height="78"/>
</svg>