We are implementing icons in our Ionic / Cordova app that uses SVG icons and whenever exported from Adobe XD, and implemented in the iOS version of the app, the gradient part of the icon shows correctly on Web (Chromium based browsers like Edge / Chrome) and Android but not on iOS.
This is how the icon looks normally in Chrome/Edge/Android and in XD:
And this what the icon looks like once in Cordova - iOS:
As you can see, the dot on the icon that has normally a gradient appears black. We cannot figure out why.
Here is the code of the SVG that Adobe XD produces:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a{fill:#fff;opacity:0;}.b{fill:none;stroke:#5d5d5d;stroke-linecap:round;stroke-width:1.5px;}.b,.c{stroke-miterlimit:10;}.c{stroke:#fff;fill:url(#a);}</style><linearGradient id="a" y1="0.5" x2="1" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#d9315d"/><stop offset="1" stop-color="#dc2224"/></linearGradient></defs><g transform="translate(0 0)"><rect class="a" width="24" height="24"/><g transform="translate(-1047.065 -371.769)"><path class="b" d="M1057.747,389.029v-4.016a3.157,3.157,0,0,0-.211-1.137l-.07-.183a2.228,2.228,0,0,0-.4-.662l-.8-.921-.566-.653-4.345-5.017a.224.224,0,0,1,.169-.37h18.052a.223.223,0,0,1,.169.37l-4.923,5.685-.658.76a3.359,3.359,0,0,0-.552.883h0a3.179,3.179,0,0,0-.253,1.243v9.081a.224.224,0,0,1-.355.182l-2.889-2.074" transform="translate(-1.701 -1.801)"/><circle class="c" cx="4.593" cy="4.593" r="4.593" transform="translate(1047.565 372.269)"/></g></g></svg>
Because we thought maybe Adobe XD produces some non compliant code of some sort, we decided to just put it through some SVG sanitizer like this one: http://svg.enshrined.co.uk/ , producing the following code:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
<defs>
<style>.a{fill:#fff;opacity:0;}.b{fill:none;stroke:#5d5d5d;stroke-linecap:round;stroke-width:1.5px;}.b,.c{stroke-miterlimit:10;}.c{stroke:#fff;fill:url(#a);}</style>
<linearGradient id="a" y1="0.5" x2="1" y2="0.5" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#d9315d"></stop>
<stop offset="1" stop-color="#dc2224"></stop>
</linearGradient>
</defs>
<g transform="translate(0 0)">
<rect class="a" width="24" height="24"></rect>
<g transform="translate(-1047.065 -371.769)">
<path class="b" d="M1057.747,389.029v-4.016a3.157,3.157,0,0,0-.211-1.137l-.07-.183a2.228,2.228,0,0,0-.4-.662l-.8-.921-.566-.653-4.345-5.017a.224.224,0,0,1,.169-.37h18.052a.223.223,0,0,1,.169.37l-4.923,5.685-.658.76a3.359,3.359,0,0,0-.552.883h0a3.179,3.179,0,0,0-.253,1.243v9.081a.224.224,0,0,1-.355.182l-2.889-2.074" transform="translate(-1.701 -1.801)"></path>
<circle class="c" cx="4.593" cy="4.593" r="4.593" transform="translate(1047.565 372.269)"></circle>
</g>
</g>
</svg>
Which at first look does some cleaner, but still does not fix our issue.
Most of the icons we use have this gradient in some form or another. And we have other examples of these icons unable to use the gradient in Cordova - iOS version.
So rendering SVG likely has less to do with Cordova, but with specific browser ability to handle SVG.
In your case it seems like you apply "gradient" using url(...) reference within css.
Safari introduced a requirement for the url in this case to feature "absolute" path.
Try the same icon but change the way you refer url from:
fill:url(#a)
to:
fill:url(https://yourwebsite.com/yourpage/#a)
Basically you need something like this for Safari:
fill: url( {{ location.href }}#filterOrGradientId )
It is a pain to work around this issue. So one suggestion could be also to try referring the gradient using fill attribute on the svg circle element.
Example from MDN:
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="myGradient" gradientTransform="rotate(90)">
<stop offset="5%" stop-color="gold" />
<stop offset="95%" stop-color="red" />
</linearGradient>
</defs>
<!-- using my linear gradient -->
<circle cx="5" cy="5" r="4" fill="url('#myGradient')" />
</svg>
I've a problem with custom font icons generated from svg using fontello. On PC, icons works fine, but on iOS browsers I haven't transparency. All source svg contains fill-rule: evenodd.
I can't find solution for my problem, if You know how solve this issue, please help.
On PC custom fontello icons works fine, but on iOS I've a problem. I'm not sure if the Android works well, but iOS has a higher priority.
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72">
<defs>
<style>
.cls-1 {
fill-rule: evenodd;
}
</style>
</defs>
<path class="cls-1" d="M0,20V33l2,5,2,4,4,4,3,3,6,3,3,1H33l3-1,6-3,1-2h2v1l1,4L66,72h1l5-5V66L52,46l-2-1-2-1V43l2-3,1-1,1-3,1-3V20l-2-5-2-4L45,7,40,3,38,2,33,0H20L15,2,10,5,7,8,5,10,3,13,1,17Zm16-9-3,3-3,4L9,21,8,27l1,6,2,4,4,4,3,2,2,1,5,1h4l4-1,4-2,4-3,2-4,2-6V25l-1-5-1-2-2-3-3-3-3-2L28,8,21,9l-3,1Z"/>
</svg>
Effect on Desktop (ok): https://ibb.co/9pfZFnf
Effect on iOS (not ok): https://ibb.co/Y846vb0
Apparently it didn't get the css rules. Please try to use the css like this, although I'm not very sure this will work.
<style type="text/css">
<![CDATA[
.cls-1 {
fill-rule: evenodd;
}
]]>
</style>
Alternatively you can reverse the second part of the d attribute (the hole) so that you don't need to use the fill-rule: evenodd;
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72">
<path class="cls-1" d="M0,20V33l2,5,2,4,4,4,3,3,6,3,3,1H33l3-1,6-3,1-2h2v1l1,4L66,72h1l5-5V66L52,46l-2-1-2-1V43l2-3,1-1,1-3,1-3V20l-2-5-2-4L45,7,40,3,38,2,33,0H20L15,2,10,5,7,8,5,10,3,13,1,17Z
M18,10L21,9L28,8L35,10L38,12L41,15L43,18L44,20L45,25L45,29L43,35L41,39L37,42L33,44L29,45L25,45L20,44L18,43L15,41L11,37L9,33L8,27L9,21L10,18L13,14L16,11z"/>
</svg>
I have a minimal sample project that produces corrupt graphics on a Google Pixel XL and a Xiaomi Mi6, but works correctly on a Samsung Galaxy S6.
Setting android:hardwareAccelerated=false fixes the corrupt graphics but leads to issues with animations and scrolling leaving trails.
The sample project uses MvvmCross, however I have been able to reproduce the behaviour without MvvmCross.
The project code can be found at https://github.com/stevedcc/Xamarin_Broken_Graphics.git
View:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/mainLogo"
android:src="#drawable/company_logo_1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:adjustViewBounds="true" />
<ImageView
android:id="#+id/main_image"
android:layout_width="wrap_content"
android:layout_height="350dp"
android:layout_below="#drawable/main_image1"
android:adjustViewBounds="true"
android:src="?attr/main_image"/>
<TextView
android:id="#+id/mainScanText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/main_image"
android:gravity="center"
android:textSize="24sp"
android:text="Title" />
</RelativeLayout>
Styles:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<attr name="company_logo" format="reference" />
<attr name="main_image" format="reference"/>
<attr name="company_color" format="reference" />
<attr name="splash_background" fromat="reference" />
<color name="company_color_1">#7f7f7f</color>
<style name="CompanyTheme"
parent="#android:style/Theme.Material.NoActionBar">
<item name="company_logo">#drawable/company_logo_1</item>
<item name="main_image">#drawable/main_image1</item>
<item name="android:colorBackground">#000000</item>
<item name="company_color">#color/company_color_1</item>
</style>
</resources>
Expected Result as displayed by a Galaxy S6
Actual Result as displayed by a Pixel XL
Can anyone tell me how to fix the Corrupt graphics?
I found the answer myself:
<item name="android:colorBackground">#000000</item>
leads to the issue, if replaced by
<item name="android:colorBackground">#android:color/black</item>
then the project works.
I have an image (in jpg and svg format) that I'd like to generate a pattern I can use as a fill for an SVG image I am working on. Is there any tool or technique to accomplish this?
Sure just put the image (jpg or svg) in a pattern.
<defs>
<pattern id="image1" width="100%" height="100%">
<image xlink:href="image.jpg" width="100" height="100" />
</pattern>
</defs>
Then you can use it as a fill attribute like this: fill="url(#image1)" />
I have an ItemsControl with items templated as a UserControl.
My ItemsControl.Items Panel is templated as a Canvas.
For now, I set these my usercontrol's width and height properties manually and it looks like this:
<ItemsControl x:Name="curveList"
ItemsSource="{Binding SplineVMList}"
Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="canvas" Margin="46,60,83,46"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:SplineControl Width="300" Height="300" Canvas.Bottom="0" Canvas.Left="0" IsSelected="{Binding IsSelected, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Bottom" Value="0"/>
<Setter Property="Canvas.Left" Value="0"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
What I want is to bind width and height properties of my usercontrol to those of my Canvas.
Is it just possible?
Have you tried a relative source binding?
e.g.
Width="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType=Canvas}}"