Svg issues on Safari - javascript

I am using svg icons for expanding and collapsing a component. They are rendering correctly as you can see in the following image:
but when I expand a component and perform an action the svgs begin to look like this:
I have verified there is absolutely no change in the svg component and they return to the correct view after I expand another component. This issue is occuring at multiple locations where I am using svg icons. I am using React and the svg icons are loaded as components. This only occurs on Safari and no other browser
Edit
The code for the svg is :
export const CollapseIcon = () => (<svg
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
width="24"
height="24"
viewBox="0 0 24 24">
<defs>
<path
id="gt4gdtq39a"
d="M7.146 9.146c.174-.173.443-.192.638-.057l.07.057L12 13.293l4.146-4.147c.174-.173.443-.192.638-.057l.07.057c.173.174.192.443.057.638l-.057.07-4.5 4.5c-.174.173-.443.192-.638.057l-.07-.057-4.5-4.5c-.195-.196-.195-.512 0-.708z"
/>
</defs>
<g fill="none" fillRule="evenodd">
<g>
<g transform="translate(-956 -290) translate(956 290)">
<mask id="reyuf8n5tb" fill="#fff">
<use xlinkHref="#gt4gdtq39a" />
</mask>
<use fill="#000" fillRule="nonzero" xlinkHref="#gt4gdtq39a" />
<g fill="#F7274A" mask="url(#reyuf8n5tb)">
<path d="M0 0H24V24H0z" />
</g>
</g>
</g>
</g>
);
and I am using it as a simple component like:
{expanded ? <CollapseIcon /> : <ExpandIcon />}

Related

Trying to change the color of an svg using an onclick event. Its saying it cant assign the color because its underfined

heres my svg file, its just a face as I am practicing
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 720 720" style="enable-background:new 0 0 720 720;" xml:space="preserve">
<g id="skin">
<circle class="skin" cx="364.42" cy="383" r="278"/>
</g>
<g id="mouth">
<path class="mouth" d="M172.92,383c127.67,0,255.33,0,383,0c0,105.05-86.45,191.5-191.5,191.5S172.92,488.05,172.92,383z"/>
</g>
<g id="hair">
<path id = "hair" class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
<g id="eyes">
<g>
<circle class = "eyes" cx="251.17" cy="271.25" r="52.4"/>
<circle class = "eyes" cx="477.67" cy="271.25" r="52.4"/>
</g>
</g>
</svg>
I'm trying to change the hair to blue using a button and an onclick event here:
<button class="blueButton" onclick="hair.style.fill='blue';"></button>
it does not change the color so I was wondering if anyone knew where I was going wrong with this...
Thank you!
You can't just reference the hair element. Instead, call document.getElementById('hair') to get it.
<button class="blueButton" onclick="document.getElementById('hair').style.fill='blue';">Button</button>
Here is a fiddle you can see it work in https://jsfiddle.net/679nLv3p/
You have two SVG objects with the same id hair. Remove the group one.
<g>
<path id = "hair" class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
Working jsbin example

how to use svg into lightning component in Salesforce

I am following this tutorial : https://archive-2_1_4.lightningdesignsystem.com/resources/lightning-svg-icon-component-helper on how to use svg on lightning component but for some reason it is not working for my case:
I have already created the component svgIcon and added all the code into it.
In my case it does not seem to work since its showing a non sense blue square.
I uploaded the svg file into static resource and tried smth like this:
<c:svgIcon svgPath="{!$Resource.feedIcon}" category="standard" size="large" name="user" />
While this part on the tutorial looks as following:
<c:svgIcon svgPath="/resource/slds214/assets/icons/standard-sprite/svg/symbols.svg#user" category="standard" size="large" name="user" />
Dosnt specify where does they store the svg and also dont know what #user stands for in this case
The svg file I uploaded to salesforce static resources looks as below:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="82px" height="82px" viewBox="0 0 82 82" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 55.2 (78181) - https://sketchapp.com -->
<title>Group 4</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icons-for-svg-export" transform="translate(-119.000000, -118.000000)" fill="#8B8D8E">
<g id="Group-4" transform="translate(120.000000, 119.000000)">
<g id="Group-3" stroke="#8B8D8E" stroke-width="0.4">
<g id="chat">
<path d="M68.2614576,11.7212036 C60.7001948,4.16069852 50.6693958,0 39.979772,0 C29.2899367,0 19.2593492,4.16069852 11.6980863,11.7212036 C-2.91552041,26.3339658 -3.9306097,49.72521 9.17822921,65.5056316 C7.8922944,68.0929603 5.8291323,71.1039699 2.76758412,72.6094747 C1.2957998,73.3363284 0.467405755,74.9094868 0.720913785,76.5331741 C0.974421815,78.1568613 2.22652736,79.4253669 3.85033192,79.6788567 C4.61106745,79.7976733 5.69381525,79.9158558 7.01273359,79.9158558 C10.5485257,79.9158558 15.758232,79.0866759 21.0861293,75.2481778 C27.0229533,78.4441778 33.5185944,80 39.9632802,80 C50.3144,80 60.5646663,75.9921564 68.2779494,68.2796421 C75.8390008,60.7189256 80,50.6899085 80,40 C80,29.3111486 75.8216633,19.2810744 68.2614576,11.7212036 Z M65.0303403,65.0489696 C53.6129644,76.4655204 35.9369638,78.7314944 22.0335601,70.5631637 C21.12017,70.0213003 19.9868898,70.1906458 19.2593492,70.9181338 C19.1916907,70.9521721 19.1238207,71.0024894 19.0734997,71.0528068 C14.4896347,74.6048341 9.99013149,75.3488126 7.01273359,75.3488126 L6.99624183,75.3488126 C10.429489,72.8458396 12.5949846,69.1253125 13.863582,66.2331196 C14.066769,65.7426308 14.1005982,65.2348057 13.9817729,64.7614417 C13.9314519,64.3047796 13.7456024,63.8481176 13.4233787,63.4755998 C1.04229177,49.4882108 1.68483631,28.1779502 14.9125005,14.9512418 C28.7317539,1.13298696 51.2112983,1.13298696 65.0130028,14.9512418 C78.8495937,28.7692852 78.8495937,51.2307148 65.0303403,65.0489696 Z" id="Fill-1"></path>
</g>
</g>
<path d="M40,39 C45.5228475,39 50,34.5228475 50,29 C50,23.4771525 45.5228475,19 40,19 C34.4771525,19 30,23.4771525 30,29 C30,34.5228475 34.4771525,39 40,39 Z M40,34 C37.2385763,34 35,31.7614237 35,29 C35,26.2385763 37.2385763,24 40,24 C42.7614237,24 45,26.2385763 45,29 C45,31.7614237 42.7614237,34 40,34 Z" id="Oval" fill-rule="nonzero"></path>
<path d="M53.3820358,52.1419451 L53.3820358,58.0287934 L58.3820358,58.0287934 L58.3820358,52.0610237 C58.3820358,50.6620146 57.7745968,49.3319332 56.7172836,48.4157917 L56.7172836,48.4157917 C47.0341731,40.0255636 32.5627654,40.3598339 23.2773818,49.188209 C22.7810083,49.660152 22.5,50.3150789 22.5,51 L22.5,58.0287934 L27.5,58.0287934 L27.5,52.1101962 C34.9103462,45.7645802 45.9109476,45.7203441 53.3820358,52.1419451 Z" id="Path-3" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg>
Any idea how can I use svg icons in lightening component?
Add Svg in static resources and use like this.
"{!$Resource.delawareSVGs + '/Icons/exclamation-mark.svg'}"

SVG inside v-for loop cause page loading slow down

I am using SVG inside component named SvgIcons.vue like this:-
<template>
<div class="svg__icon" v-if="iconType">
<svg :height="dimension" :width="dimension" v-if="iconType == 'rss_icon'" xmlns=" "
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 12 11.968">
<g id="blogpost_icon_active" transform="translate(-77 -178)">
<g id="Group_42" data-name="Group 42" transform="translate(77 178)">
<ellipse :class="className" id="Ellipse_25" data-name="Ellipse 25" class="cls-1" cx="1.641" cy="1.641" rx="1.641" ry="1.641" transform="translate(0 8.649)"/>
<path :class="className" id="Path_135" data-name="Path 135" class="cls-1" d="M1308,266.988v2.279a5.583,5.583,0,0,1,3.957,1.6,5.48,5.48,0,0,1,1.641,3.957h2.334a7.726,7.726,0,0,0-7.932-7.841Z" transform="translate(-1308 -262.897)"/>
<path :class="className" id="Path_136" data-name="Path 136" class="cls-1" d="M1308,246.873v-2.3a11.951,11.951,0,0,1,8.37,3.374,12.4,12.4,0,0,1,3.629,8.589h-2.316a10.124,10.124,0,0,0-2.845-6.82A9.654,9.654,0,0,0,1308,246.873Z" transform="translate(-1308 -244.57)"/>
</g>
</g>
</svg>
</div>
</template>
<script>
export default {
props: ['iconType', 'className', 'dimension'],
methods: {
},
computed: {
},
created () {
console.debug(this.iconType)
}
}
</script>
I add this component in other vue-component to render SVG inline like this:-
<div class="article_box_grid only_article_box_grid" :key="'grid_' + post._source.id "
v-for="(post, index) in getPosts">
......Other code......
<svg-icons iconType="rss_icon" dimension="14" className="orangeColor"></svg-icons>
</div>
I have more than 4 icons for single loop item.
When page load page then I get this warning in the console more than 200+ times and page take more time to load completely:-
WARNING: Too many active WebGL contexts. Oldest context will be lost.
Am I doing anything wrong or is there any other safe way to load SVG icon inside v-for loop in Vue?

Is it possible to use custom icon with reactjs?

I want to use my own designed custom icons in react which I have in both formats SVG and TTF.
How can I do that? I want to put those icons in my navbar like a custom home icon for home button.
I'm not sure how is you webpack configured to resolve svg and include them in your build, But I can give you two different approaches here:
You can make separate SVG files generated from some tool in xml
myIcon.svg
<?xml version="1.0" encoding="UTF-8"?>
<svg width="26px" height="26px" viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>bus-start</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Booking-a-trip" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Verify" transform="translate(-113.000000, -312.000000)">
<g id="Group-3" transform="translate(63.000000, 144.000000)">
<g id="bus-start" transform="translate(51.000000, 169.000000)">
<circle id="Oval" stroke="#606C74" fill="#FFFFFF" cx="12" cy="12" r="12"></circle>
<path d="M6,15.0585702 C6,15.6952627 6.2925,16.2668389 6.75,16.6647717 L6.75,17.952627 C6.75,18.3505599 7.0875,18.6761413 7.5,18.6761413 L8.25,18.6761413 C8.6625,18.6761413 9,18.3505599 9,17.952627 L9,17.2291128 L15,17.2291128 L15,17.952627 C15,18.3505599 15.3375,18.6761413 15.75,18.6761413 L16.5,18.6761413 C16.9125,18.6761413 17.25,18.3505599 17.25,17.952627 L17.25,16.6647717 C17.7075,16.2668389 18,15.6952627 18,15.0585702 L18,7.82342808 C18,5.29112834 15.315,4.92937123 12,4.92937123 C8.685,4.92937123 6,5.29112834 6,7.82342808 L6,15.0585702 Z M8.625,15.7820844 C8.0025,15.7820844 7.5,15.2973299 7.5,14.6968131 C7.5,14.0962963 8.0025,13.6115418 8.625,13.6115418 C9.2475,13.6115418 9.75,14.0962963 9.75,14.6968131 C9.75,15.2973299 9.2475,15.7820844 8.625,15.7820844 Z M15.375,15.7820844 C14.7525,15.7820844 14.25,15.2973299 14.25,14.6968131 C14.25,14.0962963 14.7525,13.6115418 15.375,13.6115418 C15.9975,13.6115418 16.5,14.0962963 16.5,14.6968131 C16.5,15.2973299 15.9975,15.7820844 15.375,15.7820844 Z M16.5,11.4409991 L7.5,11.4409991 L7.5,7.82342808 L16.5,7.82342808 L16.5,11.4409991 Z" id="Shape" fill="#606C74" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</svg>
Later in your component you can import it like :
import myIcon from 'assets/myIcon.svg' // depending on your folder structure
in render method:
render(){
return (
<img src={myIcon} />
)
}
Second approach you can make your svg in react using <svg>:
here is the working codesandbox: Svg Icon + React

Add a prefix to mutliple elements from the parent attribute

I'm trying to figure out how to add a unique prefix to ID's and other reference links.
I have multiple identical SVGs on a page. These SVGs serve as a wrapper (they're devices - laptop, phone, etc.) which have image link that is inserted into the SVG after load. The problem is, the ID's for these svgs are identical so they all conflict with each other. What I'm trying to do (but am open to better solutions) is to insert a unique ID to each id,xlink:href, url(#, etc. but pass over the <image> href attribute and fill and stroke attributes.
EDIT: I added/tweaked the code provided by #Temani, which got me closer to my desired result, however, I'm now getting all the ID's added to each SVG element. Formatted the code to be executable.
Desired output:
<div class="device" data-screen="[[IMAGE TO USE]]" data-name"[[UNIQUE ID]]">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="635" height="420" viewBox="0 0 635 420">
<defs>
<path id="[[UNIQUE ID]]-path-1"/>
<rect id="[[UNIQUE ID]]-path-3" />
<pattern id="[[UNIQUE ID]]-pattern-4">
<use transform="scale(13.1875)" xlink:href="#[[UNIQUE ID]]-image-5"/>
</pattern>
<image id="[[UNIQUE ID]]-image-5" href="[[IMAGE LINK THAT IS INSERTED AFTER LOAD]]"/>
</defs>
<g fill="none" fill-rule="evenodd">
<rect fill="#fff" stroke="#2D8EFF" />
<g >
<mask id="[[UNIQUE ID]]-mask-2" fill="#fff">
<use xlink:href="#[[UNIQUE ID]]-path-1"/>
</mask>
<g mask="url(#[[UNIQUE ID]]-mask-2)">
<mask id="mask-6" fill="#fff">
<use xlink:href="#[[UNIQUE ID]]-path-3"/>
</mask>
</g>
</g>
</g>
</svg>
</div>
Right now - both ID's (first and second) gets added to each SVG element. I also
$('.device').each(function() {
//we get the needed id using $(this) that refer to actual device
var id = $(this).data('name');
//we check all the element with ID
$(this).find("path, rect, pattern, image, mask").each(function() {
//now (this) refer to the actual element
if($(this).attr("id"))
$(this).attr("id", id+"-"+$(this).attr("id"));
});
//we update the <use>
$(this).find("use").each(function() {
//now (this) refer to the actual element
$(this).attr("xlink:href","#"+id+"-"+$(this).attr("xlink:href").substring(1));
});
// Also, hoping to combine g[mask], u[fill], etc into 1 function.
// Basically any attribute that starts with "url(#"
$(this).find("g[mask^='url']").each(function() {
$(this).attr("mask","url(#"+id+"-"+$(this).attr("mask").substring(5));
});
$(this).find("use[fill^='url']").each(function() {
$(this).attr("fill","url(#"+id+"-"+$(this).attr("fill").substring(5));
});
$(this).find("use[filter^='url']").each(function() {
$(this).attr("filter","url(#"+id+"-"+$(this).attr("filter").substring(5));
});
// grab data-screen value
var data = $(this).data('screen');
// replace this with the link inside svg
if (data != '') {
$(this).find("svg defs image").attr("href", data).attr("xlink:href", data);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="device" data-name="first" data-screen="image-1.png">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<defs>
<rect id="w-circle-stroke-a" width="24" height="24"/>
<path id="w-circle-stroke-b" d="M12,2 C17.52,2 22,6.48 22,12 C22,17.52 17.52,22 12,22 C6.48,22 2,17.52 2,12 C2,6.48 6.48,2 12,2 Z M12,3.81818182 C7.48415409,3.81818182 3.81818182,7.48415409 3.81818182,12 C3.81818182,16.5158459 7.48415409,20.1818182 12,20.1818182 C16.5158459,20.1818182 20.1818182,16.5158459 20.1818182,12 C20.1818182,7.48415409 16.5158459,3.81818182 12,3.81818182 Z M10.5553177,13.4773237 L15.155405,8.80967806 C15.5597962,8.4027095 16.222261,8.39598875 16.6350615,8.79466684 C16.6382917,8.79778661 16.6600317,8.81952282 16.7002813,8.85987545 C17.0999062,9.26113743 17.0999062,9.90402237 16.7002813,10.3052843 L10.5553177,16.5 L7.29971874,13.2228714 C6.90252847,12.8240541 6.8997633,12.1859262 7.29348277,11.7837778 L7.33224151,11.7441893 C7.73340831,11.3344341 8.39555055,11.3228774 8.8111776,11.7183766 C8.81566955,11.722651 9.39704957,12.3089667 10.5553177,13.4773237 Z"/>
<image id="image-5" href="image-to-be-inserted.jpg"/>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="w-circle-stroke-c" fill="#fff">
<use xlink:href="#w-circle-stroke-b"/>
</mask>
<g fill="#2D8EFF" mask="url(#w-circle-stroke-c)">
<rect width="24" height="24"/>
</g>
<use fill="url(#pattern-4)" xlink:href="#path-3"/>
<use fill="#000" filter="url(#filter-10)" xlink:href="#path-9"/>
</g>
</svg>
</div>
<div class="device" data-name="second" data-screen="image-1.png">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<defs>
<rect id="w-circle-stroke-a" width="24" height="24"/>
<path id="w-circle-stroke-b" d="M12,2 C17.52,2 22,6.48 22,12 C22,17.52 17.52,22 12,22 C6.48,22 2,17.52 2,12 C2,6.48 6.48,2 12,2 Z M12,3.81818182 C7.48415409,3.81818182 3.81818182,7.48415409 3.81818182,12 C3.81818182,16.5158459 7.48415409,20.1818182 12,20.1818182 C16.5158459,20.1818182 20.1818182,16.5158459 20.1818182,12 C20.1818182,7.48415409 16.5158459,3.81818182 12,3.81818182 Z M10.5553177,13.4773237 L15.155405,8.80967806 C15.5597962,8.4027095 16.222261,8.39598875 16.6350615,8.79466684 C16.6382917,8.79778661 16.6600317,8.81952282 16.7002813,8.85987545 C17.0999062,9.26113743 17.0999062,9.90402237 16.7002813,10.3052843 L10.5553177,16.5 L7.29971874,13.2228714 C6.90252847,12.8240541 6.8997633,12.1859262 7.29348277,11.7837778 L7.33224151,11.7441893 C7.73340831,11.3344341 8.39555055,11.3228774 8.8111776,11.7183766 C8.81566955,11.722651 9.39704957,12.3089667 10.5553177,13.4773237 Z"/>
<image id="image-5" href="image-to-be-inserted.jpg"/>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="w-circle-stroke-c" fill="#fff">
<use xlink:href="#w-circle-stroke-b"/>
</mask>
<g fill="#2D8EFF" mask="url(#w-circle-stroke-c)">
<rect width="24" height="24"/>
</g>
<use fill="url(#pattern-4)" xlink:href="#path-3"/>
<use fill="#000" filter="url(#filter-10)" xlink:href="#path-9"/>
</g>
</svg>
</div>
The issue is that you don't have to use $('.device') when inside and you need to refer to $(this) and since you have 2 each() nested you need to pay attention to the scope of this.
$('.device').each(function() {
//we get the needed id using $(this) that refer to actual device
var id = $(this).data('name');
//we check all the element with ID
$(this).find("path, rect, pattern, image, mask").each(function() {
//now (this) refer to the actual element
if($(this).attr("id"))
$(this).attr("id", id+"-"+$(this).attr("id"));
});
//we update the <use>
$(this).find("use").each(function() {
//now (this) refer to the actual element
$(this).attr("xlink:href","#"+id+"-"+$(this).attr("xlink:href").substring(1));
});
// grab data-screen value
var data = $(this).data('screen');
// replace this with the link inside svg
if (data != '') {
$(this).find("svg defs image").attr("href", data).attr("xlink:href", data);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="device" data-screen="[[IMAGE TO USE]]" data-name="[[UNIQUE ID]]">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="635" height="420" viewBox="0 0 635 420">
<defs>
<path id="path-1"/>
<rect id="path-3" />
<pattern id="pattern-4">
<use transform="scale(13.1875)" xlink:href="#image-5"/>
</pattern>
<image id="image-5" href="[[IMAGE LINK THAT IS INSERTED AFTER LOAD]]"/>
</defs>
<g fill="none" fill-rule="evenodd">
<rect fill="#fff" stroke="#2D8EFF" />
<g >
<mask id="mask-2" fill="#fff">
<use xlink:href="#path-1"/>
</mask>
<g mask="url(#mask-2)">
<mask id="mask-6" fill="#fff">
<use xlink:href="#path-3"/>
</mask>
</g>
</g>
</g>
</svg>
</div>

Categories

Resources