Use material ui svg icons as background image - html
Can I use #material-ui/icons svg images as background of other elements.? Tried the below code but didn't work.
import CarIcon from '#material-ui/icons/DriveEtaRounded';
const carIcon = <CarIcon />
function Cover(){
return (
<div
className={classes.cover}
style={{ backgroundImage: 'url('+ carIcon+')' }}
/>
)
}
#material-ui/icons are React components and if you open their source, they contain only SVG data that are encapsulated in <svg> tag using a utility function. However you can simulate background-image behaviour by using them directly and a bit of styling:
import CarIcon from '#material-ui/icons/DriveEtaRounded';
function Cover(){
return (
<div style={{position: 'relative', width: '200px', height: '100px'}}>
<CarIcon style={{position: 'absolute', left: 0, top: 0, width: '100%', height: '100%'}} />
</div>
)
}
This is an example but it will work as long as the parent element has its dimensions set by other content. You can also simulate background-size: cover behaviour by adding preserveAspectRatio='xMidYMid slice' to the icon component (default value corresponds to contain).
An added benefit of this approach is that the icons are still SVGs and can be further styled or animated.
Based on an example from the MUI docs relating to custom switches, you can set the backgroundImage property to an Mui icon using the following format:
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20">
<path fill="${encodeURIComponent('#fff',)}"
d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/>
</svg>')`,
It's messy because you can't just use CarIcon, you need the actual svg path (the d attribute in above example). To get the d value of the svg I wanted to use, I just found the icon's file in node modules (e.g node_modules > #mui > icons-material > DriveEtaRounded.js):
DriveEtaRound.js:
"use strict";
var _interopRequireDefault = require("#babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _createSvgIcon = _interopRequireDefault(require("./utils/createSvgIcon"));
var _jsxRuntime = require("react/jsx-runtime");
var _default = (0, _createSvgIcon.default)( /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
//
// ---- d value here \/
//
d: "M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01l-1.97 5.67c-.07.21-.11.43-.11.66v7.16c0 .83.67 1.5 1.5 1.5S6 19.33 6 18.5V18h12v.5c0 .82.67 1.5 1.5 1.5.82 0 1.5-.67 1.5-1.5v-7.16c0-.22-.04-.45-.11-.66l-1.97-5.67zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.27-3.82c.14-.4.52-.68.95-.68h9.56c.43 0 .81.28.95.68L19 10H5z"
//
// ---- d value here /\
//
}), 'DriveEtaRounded');
exports.default = _default;
So your end result should be:
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20">
<path fill="${encodeURIComponent('#fff',)}"
d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01l-1.97 5.67c-.07.21-.11.43-.11.66v7.16c0 .83.67 1.5 1.5 1.5S6 19.33 6 18.5V18h12v.5c0 .82.67 1.5 1.5 1.5.82 0 1.5-.67 1.5-1.5v-7.16c0-.22-.04-.45-.11-.66l-1.97-5.67zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.27-3.82c.14-.4.52-.68.95-.68h9.56c.43 0 .81.28.95.68L19 10H5z"/>
</svg>')`,
make sure you use d="... and not d:"...
Related
How to find a UI element in a web page built on slds (Salesforce)?
Haven't done web programming in a while - nor do I think ever interacted with a site built on Salesforce. The site is a California state site that's part of my work but not publicly available. As part of web automation want to start by clicking on the button under a pencil icon which will transition the page to edit mode. I've experimented with some javascript expressions to find the button that I want. The first couple didn't work. This one does - sort of: let test1 = document.getElementsByClassName("slds-button") the problem is that it returns an array of 58 items. The object I want to find in its raw form is as follows: <button class="slds-button slds-button_icon slds-button_icon-bare" title="Edit" type="button" value="Status"><lightning-primitive-icon><svg class="slds-button__icon" focusable="false" data-key="edit" aria-hidden="true" viewBox="0 0 52 52"><g><g><path d="M9.5 33.4l8.9 8.9c.4.4 1 .4 1.4 0L42 20c.4-.4.4-1 0-1.4l-8.8-8.8c-.4-.4-1-.4-1.4 0L9.5 32.1c-.4.4-.4 1 0 1.3zM36.1 5.7c-.4.4-.4 1 0 1.4l8.8 8.8c.4.4 1 .4 1.4 0l2.5-2.5c1.6-1.5 1.6-3.9 0-5.5l-4.7-4.7c-1.6-1.6-4.1-1.6-5.7 0l-2.3 2.5zM2.1 48.2c-.2 1 .7 1.9 1.7 1.7l10.9-2.6c.4-.1.7-.3.9-.5l.2-.2c.2-.2.3-.9-.1-1.3l-9-9c-.4-.4-1.1-.3-1.3-.1l-.2.2c-.3.3-.4.6-.5.9L2.1 48.2z"></path></g></g></svg></lightning-primitive-icon><span class="slds-assistive-text">Edit</span></button>
As you stated you are selecting the className from webpage, so you will always get list of elements which uses same css class. So in your case I am assuming you want to use className and get the result, so here is the snippet which will give you result which you want to achieve: var btn = document.getElementsByClassName("slds-button"); var searchText = "Status"; // your button element value attribute text var found; for (var i = 0; i < btn.length; i++) { if (btn[i].value == searchText) { found = btn[i]; break; } } //console.log("Button Element: ", found); Here is sample code example which has 3 buttons with same CSS class but different text in value attribute: var btn = document.getElementsByClassName("slds-button"); var searchText = "Status"; // your button element value attribute text var found; for (var i = 0; i < btn.length; i++) { if (btn[i].value == searchText) { found = btn[i]; break; } } console.log("Button Element: ", found); <button class="slds-button slds-button_icon slds-button_icon-bare" title="Edit" type="button" value="Status"><lightning-primitive-icon><svg class="slds-button__icon" focusable="false" data-key="edit" aria-hidden="true" viewBox="0 0 52 52"><g><g><path d="M9.5 33.4l8.9 8.9c.4.4 1 .4 1.4 0L42 20c.4-.4.4-1 0-1.4l-8.8-8.8c-.4-.4-1-.4-1.4 0L9.5 32.1c-.4.4-.4 1 0 1.3zM36.1 5.7c-.4.4-.4 1 0 1.4l8.8 8.8c.4.4 1 .4 1.4 0l2.5-2.5c1.6-1.5 1.6-3.9 0-5.5l-4.7-4.7c-1.6-1.6-4.1-1.6-5.7 0l-2.3 2.5zM2.1 48.2c-.2 1 .7 1.9 1.7 1.7l10.9-2.6c.4-.1.7-.3.9-.5l.2-.2c.2-.2.3-.9-.1-1.3l-9-9c-.4-.4-1.1-.3-1.3-.1l-.2.2c-.3.3-.4.6-.5.9L2.1 48.2z"></path></g></g></svg></lightning-primitive-icon><span class="slds-assistive-text">Edit</span></button> <button class="slds-button slds-button_icon slds-button_icon-bare" title="Edit" type="button" value="Status_other"><lightning-primitive-icon><svg class="slds-button__icon" focusable="false" data-key="edit" aria-hidden="true" viewBox="0 0 52 52"><g><g><path d="M9.5 33.4l8.9 8.9c.4.4 1 .4 1.4 0L42 20c.4-.4.4-1 0-1.4l-8.8-8.8c-.4-.4-1-.4-1.4 0L9.5 32.1c-.4.4-.4 1 0 1.3zM36.1 5.7c-.4.4-.4 1 0 1.4l8.8 8.8c.4.4 1 .4 1.4 0l2.5-2.5c1.6-1.5 1.6-3.9 0-5.5l-4.7-4.7c-1.6-1.6-4.1-1.6-5.7 0l-2.3 2.5zM2.1 48.2c-.2 1 .7 1.9 1.7 1.7l10.9-2.6c.4-.1.7-.3.9-.5l.2-.2c.2-.2.3-.9-.1-1.3l-9-9c-.4-.4-1.1-.3-1.3-.1l-.2.2c-.3.3-.4.6-.5.9L2.1 48.2z"></path></g></g></svg></lightning-primitive-icon><span class="slds-assistive-text">Edit</span></button> <button class="slds-button slds-button_icon slds-button_icon-bare" title="Edit" type="button" value="Status_other_button"><lightning-primitive-icon><svg class="slds-button__icon" focusable="false" data-key="edit" aria-hidden="true" viewBox="0 0 52 52"><g><g><path d="M9.5 33.4l8.9 8.9c.4.4 1 .4 1.4 0L42 20c.4-.4.4-1 0-1.4l-8.8-8.8c-.4-.4-1-.4-1.4 0L9.5 32.1c-.4.4-.4 1 0 1.3zM36.1 5.7c-.4.4-.4 1 0 1.4l8.8 8.8c.4.4 1 .4 1.4 0l2.5-2.5c1.6-1.5 1.6-3.9 0-5.5l-4.7-4.7c-1.6-1.6-4.1-1.6-5.7 0l-2.3 2.5zM2.1 48.2c-.2 1 .7 1.9 1.7 1.7l10.9-2.6c.4-.1.7-.3.9-.5l.2-.2c.2-.2.3-.9-.1-1.3l-9-9c-.4-.4-1.1-.3-1.3-.1l-.2.2c-.3.3-.4.6-.5.9L2.1 48.2z"></path></g></g></svg></lightning-primitive-icon><span class="slds-assistive-text">Edit</span></button>
Using onMessage data to draw svg path
In an HTML frame I want to draw a simple line graph using an svg path, to make sure it is correctly recieving the message I display the data in the span section, and to make sure I have written the code for the svg path correctly i have manually entered example data (figure 1) this works fine but when I try and use the message data in the svg path (figure 2) nothing appears, the message is correctly formatted and in this example it is "M 0 50 l 20 5 l 20 10 l 20 -20 l 20 10 l 20 -5" - exactly the same as what I manually entered for the path in figure 1. I'm not sure what im doing wrong, I'm fairly new to coding and so I don't quite know all the basics and may have jumped in at the deep end so could therefore be overlooking something obvious, any help is greatly appreciated :). Figure 1: <html> <body> <span id="svgPath" class="label">HTML Label</span> <script type="text/javascript"> window.onmessage = (event) => { if (event.data) { document.getElementById("svgPath").innerHTML = event.data; } }; </script> <svg id="myGraph" viewBox="0 0 100 100"> <path d="M 0 50 l 20 5 l 20 10 l 20 -20 l 20 10 l 20 -5" stroke= "black" fill= "transparent" /> </svg> </body> </html> Figure 2 <html> <body> <span id="svgPath" class="label">HTML Label </span> <script type="text/javascript"> window.onmessage = (event) => { if (event.data) { document.getElementById("svgPath").innerHTML = event.data; } }; </script> <svg id="myGraph" viewBox="0 0 100 100"> <path d="svgPath" stroke= "black" fill= "transparent" /> </svg> </body> </html>
How to set margin in CSS for SVGIcon based on sibling text position?
I want to set margin-left or margin-right for a Icon component inside toggle button component (svg+text inside button) in ReactJS using CSS. Here I want to add space between the icon and button placeholder. Using :first-child and :last-child seems to apply in both scenarios (when icon is on left I want to apply marginRight, when icon is on right I want to apply marginLeft). How to achieve it in CSS?
You can add an ID attribute to the SVG tag. And only then you will be able to target the SVG in the CSS. Side note: Since you are using react I will suggest that you create a component for the button itself so it could be re-usable and keep your code clean. References that might help you out: MDN Docs: SVG and CSS MDN Docs: SVG style #btn-icon{ /* Indicators to prove it works */ margin: 0 1rem; fill: red; /* Indicators to prove it works */ /* Apply your styles here */ /* Apply your styles here */ } <button> Placeholder <svg id="btn-icon" focusable="false" aria-hidden="true" viewBox="0 0 24 24"> <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></svg> </button>
If your first code example was correct, you don't have any siblings you could select in css. Since your buttons text content is not a selectable element in css. Therfore, the svg icon will is both :last-child and :first-child. You might try to add a js to assign classes to your buttons: let buttons = document.querySelectorAll('button'); buttons.forEach(function(button, i){ let icon = button.querySelector('svg'); let siblingLeft = icon.previousSibling.textContent; // strip whitespace siblingLeft = siblingLeft.replace(/\s/g, "") let btnClass = siblingLeft ? 'icon-right' : 'icon-left'; button.classList.add(btnClass); }); body{ font-size:3em; } button{ font-size:inherit; background:#fff; border: 1px solid #ccc; padding:0.3em; } .icon{ display:inline-block; height:1em; margin-left:0.3em; margin-right:0.3em; position:relative; bottom:-0.1em; fill: green; } .icon-right svg{ margin-right:0 } .icon-left svg{ margin-left:0; fill:red; } <button> <svg class="icon icon-inline" focusable="false" aria-hidden="true" viewBox="0 0 24 24"> <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg>Placeholder left </button> <button> Placeholder right<svg class="icon icon-inline" focusable="false" aria-hidden="true" viewBox="0 0 24 24"> <path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg> </button> But I'm pretty sure your predefined UI css will have some class attributes for different icon types or positionings. (So you should add an accurate code example of your button markup to your question).
How to display a specific path element from an SVG file in HTML?
I've got an SVG map and I want to show a specific city using ID in HTML with specified width and height. How can I accomplish this? Here is the SVG Image: <?xml version="1.0" encoding="utf-8"?> <!-- (c) ammap.com | SVG map of Afghanistan - High --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:amcharts="http://amcharts.com/ammap" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" > <defs> <style type="text/css"> .land { fill: #CCCCCC; fill-opacity: 1; stroke:white; stroke-opacity: 1; stroke-width:0.5; } </style> <amcharts:ammap projection="mercator" leftLongitude="60.517000" topLatitude="38.490877" rightLongitude="74.889862" bottomLatitude="29.377200"></amcharts:ammap> </defs> <g> <path id="AF-PIA" title="Paktya" class="land" d="M457.09,266.51L454.16,264.78L453.82,264.65L453.52,264.58L453.25,264.56L452.99,264.64L452.7,264.83L451.01,266.9L448.31,268.59L447.77,268.79L447.19,268.77L447.02,268.56L447.01,268.17L447.07,267.74L447.1,267.38L447.03,267.09L446.86,266.89L446.48,266.67L446.04,266.5L444.39,266.1L442.23,265.94L441.63,266L440.81,265.99L440.34,266.07L439.88,266.22L438.81,266.89L438.5,267.21L438.11,268.39L437.39,269.89L436.89,270.59L436.07,271.52L435.53,272L434.94,272.34L433.05,274L432.78,274.28L430.19,277.03L429.84,277.74L429.57,278.1L428.03,279.16L423.18,281.44L418.47,284.98L417.81,285.49L417.21,286.12L416.45,287.68L415.91,289.28L414.98,290.96L414.34,291.52L414.02,291.74L413.46,292.02L412.81,292.24L412.05,292.36L411.47,292.36L410.47,291.94L409.71,291.8L402.52,291.74L402.35,293.86L402.44,295.92L402.56,297L402.75,297.7L403.33,298.79L403.76,299.84L403.87,300.41L403.81,300.91L402.63,303.52L402.35,304.52L405.89,303.21L407.14,303L408.05,303.51L408.56,303.61L408.92,303.52L409.29,303.36L409.56,303.33L409.81,303.37L410.89,303.86L411.16,304.07L411.35,304.28L411.87,305.3L412.64,306.36L412.8,306.68L412.87,307.07L412.88,307.67L412.68,310.41L412.72,311.59L413.14,315L413.12,315.31L413.07,315.59L413.06,316.08L413.25,316.72L413.5,318.04L413.73,318.42L413.87,318.45L414.03,318.44L414.34,318.39L415.06,318.09L415.74,317.66L417.05,316.41L419.02,315.24L421.41,314.16L423.07,313.11L423.47,312.7L423.49,312.54L423.47,312.38L423.43,312.2L423.39,311.96L423.38,311.6L423.49,311.45L423.64,311.38L423.93,311.4L424.25,311.48L424.44,311.57L424.64,311.72L424.78,311.86L425.17,312.18L426.63,313.34L427.64,313.54L428.52,313.41L430.74,312.62L431.52,312.54L431.86,312.71L432.05,312.83L433.02,313.15L433.26,311.96L433.42,311.68L434.08,310.94L434.93,309.91L435.13,309.19L435.26,308.56L435.51,308.17L438.13,305.82L439.25,305.15L439.56,304.77L440.02,304.04L440.29,303.35L441.43,299.65L440.61,298.76L440.56,298.05L440.83,297.36L441.61,295.85L441.87,295.14L443.36,293.89L444.1,293.43L444.83,293.07L447.82,292.16L451.16,291.83L451.29,291.85L451.36,291.89L452.16,292.51L453.62,290.29L453.88,290.06L454.33,289.76L454.71,289.71L455.86,289.3L456.66,288.79L457.78,288.3L459.18,287.45L460.38,287.06L460.71,286.84L461.52,285.94L461.75,285.48L461.88,285.07L461.89,284.22L460.73,284.06L460,283.6L459.5,282.48L459.16,281.34L458.73,280.46L457.58,278.76L457.15,277.83L456.5,275.62L456.07,274.85L454.65,273.42L454.35,272.56L454.99,271.71L455.85,270.82L455.94,269.95L455.78,269.07L455.88,268.15L456.69,267.33L457.47,267.06L457.09,266.51z"/> <path id="AF-WAR" title="Wardak" class="land" d="M384.44,232.47L383.52,232.32L383.24,232.24L383.03,231.97L382.86,231.71L382.55,229.98L382.47,229.09L382.33,228.63L382.09,228.07L379.59,225.53L379.38,225.05L379.18,224.38L379.08,223.22L378.77,222.11L373.18,225.02L371.81,226.05L371.11,227.21L370.1,228.31L369.57,228.75L369.18,228.91L368.64,228.6L368.28,228.5L367.86,228.51L367.3,228.64L366.95,228.86L366.62,229.22L366.3,229.71L365.35,230.8L365.15,231.1L364.9,231.84L363.81,234.16L360.83,233.82L351.91,231.29L350.78,231.09L348.95,231.34L347.56,231.3L346.76,231.18L345.83,230.9L344.34,230.76L343.94,230.64L343.71,230.41L343.47,230.11L343.08,229.79L342.15,229.38L341.6,229.21L341.15,229.14L340.86,229.18L340.57,229.28L339.2,230.12L338.89,230.25L334.64,231.11L331.94,231.48L331.54,231.62L331.06,231.86L330.89,232.09L330.64,232.73L331.12,234.37L331.63,235.1L333.08,236.32L333.36,236.74L333.47,237.19L333.41,238.21L333.32,238.56L333.15,238.81L332.31,239.48L332.07,239.6L331.8,239.67L330.5,239.81L330.19,239.93L329.89,240.12L329.64,240.37L329.4,240.7L329.15,241.14L328.91,241.72L328.6,242.66L328.61,243.38L328.73,243.88L329,244.23L329.31,244.48L329.65,244.66L329.98,244.79L333.36,245.1L335.49,244.99L335.98,245.03L336.43,245.17L336.92,245.55L337.16,245.94L337.29,246.35L337.34,246.72L337.33,247.1L337.27,247.41L337.15,247.64L337,247.82L336.79,247.95L336.61,248.04L336.22,248.15L335.14,248.76L335.03,248.99L335,249.3L335.18,249.45L335.46,249.55L337.02,249.74L337.62,249.91L342.4,252.09L342.97,252.54L343.14,252.88L342.66,253.39L341.96,254.34L341.81,254.66L341.6,255.23L341.47,255.42L341.27,255.58L337.37,257.09L337.03,257.42L336.71,257.92L336.41,259.11L336.41,259.73L336.61,260.23L337.48,261.04L339.77,261.35L340.58,261.34L342.09,260.82L342.33,260.64L342.43,260.45L342.72,259.11L342.91,258.82L343.23,258.5L343.85,258.01L344.28,257.78L344.67,257.65L347.96,256.95L349.18,256.89L350.67,257.23L352.47,257.92L353.97,258.96L355.19,260.12L355.72,260.39L356.38,260.55L358.62,260.72L359.26,260.68L360,260.53L363.09,259.45L364.48,258.71L365.18,258.13L365.44,258.04L365.78,257.85L365.94,257.71L366.63,257.26L367.69,257.51L368.41,258L369.87,259.38L370.26,259.98L370.51,260.53L370.99,263.15L371.02,263.6L370.94,264.45L370.96,264.94L371.02,265.45L371.18,266.09L371.23,266.52L371.21,266.95L371.14,267.33L371.17,267.84L371.29,268.43L371.72,269.89L371.75,270.71L372.1,271.71L372.59,272.03L373.2,272.2L376.23,273.43L376.48,273.63L376.98,274.49L379.31,275.94L380.02,276.71L380.2,277L384.34,281.37L384.66,281.65L384.95,281.8L385.19,281.81L385.67,281.77L386.1,281.67L387.18,281.63L387.63,282.91L387.62,283.24L387.57,283.7L387.17,284.87L386.94,285.83L386.93,286.34L387,286.71L387.09,286.84L387.22,286.99L387.65,287.29L388.27,287.57L390.21,288.05L390.72,288.05L391.52,287.96L391.94,287.79L396.04,285.38L396.37,285.11L398.42,282.56L399.58,281.42L401.21,279.57L401.41,279.23L401.79,278.36L402.11,276.27L402.03,275.83L401.86,275.29L401.36,274.66L401.28,274.5L401.26,274.41L401.38,274.25L402.02,273.01L402.57,272.26L403.76,271.24L404.42,270.88L405.11,270.6L407.44,270.12L407.87,269.97L408.07,269.8L408.13,269.57L408.13,269.46L408.04,269.13L407.34,267.38L407.13,267.14L406.62,266.7L406.01,266.3L404.89,265.29L404.42,264.6L404.18,263.94L404.35,261.84L404.81,259.85L405.84,257.61L406.7,256.46L407.73,255.5L408.4,255.04L409.83,251.64L410.79,250.14L412.06,248.68L411.8,247.79L410.95,244.93L409.29,243.69L408.95,243.52L407.4,243.12L407.13,243L406.92,242.77L406.75,242.39L406.5,241.62L406.28,241.11L406.07,240.74L405.89,240.24L405.8,239.53L405.88,237.92L406.38,235.96L406.3,234.66L406.9,232.62L406.28,232.8L405.52,232.66L404.03,231.99L402.35,231.51L401.64,231.15L401.26,231.1L399.79,231.19L399.15,231.12L398.45,230.85L397.58,230.18L397.34,230.04L397.13,229.95L396.28,229.72L395.6,229.41L392.02,228.53L391.54,228.54L390.85,228.83L387.99,230.71L386.5,231.46L385.7,231.71L385.44,231.87L385.03,232.3L384.78,232.43L384.44,232.47z"/> </g> </svg> I want to display a city by ID from the above map. The result should look like the following image for ID="AF-PIA": I've tried the following but failed to get a city: <object data="/assets/img/illustrations/afghanistan.svg#AF-PIA" type="image/svg+xml" width="100%" height="100%"> NOTE: I have limited the number of cities to two in the above SVG code.
Define a <svg> element inside your HTML page, giving it the desired size, and reference the path from the external SVG: <style> #city-wrapper { width: 500px; height: 500px; fill: #CCCCCC; } </style> <svg id="city-wrapper" viewBox="402.35 264.55 59.54 53.89"> <use href="/assets/img/illustrations/afghanistan.svg#AF-PIA" /> </svg> Note that you will need the viewBox in advance of writing that code. Paul LeBeau's answer told you how to to that. The viewBox makes sure the path is blown up to fill the wrapper element, otherwise it would remain so small that the rest of the map would also fit. If you are willing to write a bit of Javascript, you can also leave out the viewBox attribute initially and add it after the reference has been loaded. The needed bounding box can then be queried by script: window.addEventListener('load', function() { const svg = document.querySelector('#city-wrapper'); const {x, y, width, height} = svg.querySelector('use').getBBox(); svg.setAttribute('viewBox', [x, y, width, height].join(' ')); });
The 17.3 Linking into SVG content: IRI fragments and SVG views section of the SVG specification may contain what you need. For instance, you can get the bounds of the SVG element(s) you want to focus on and use a link such as: data="/assets/img/illustrations/afghanistan.svg#viewBox(402.35,264.55,59.54,53.89) You can get the bounds by highlighting the element in the web inspector. Then type $0.getBBox() into the console. That's what I did to get the values I've used above. These bounds values are for #AF-PIA.
Taking all comments and answers: use :not selector to hide unwanted cities use getBBox() to get city dimensions set the viewBox with BBox values wrap it all in a native JavaScript Web Component (supported in all modern browsers), so all you need is: <display-city code="DAY"> using shadowDOM in the component so you can add any <style> you want (in the SVG), and it doesn't bleed to other components. added a trimmed down version of your SVG in a <template> for brevity You can paste you own SVG there !! You will notice stroke-width differences, because the viewBox dimensions differ !! <style> display-city { display: block; background: pink } cities{ /*abusing an "UknownElement, just because we can" */ display:grid; grid-template-columns:repeat(3,1fr); gap:5px; } </style> <cities> <display-city code="PAR"></display-city> <display-city code="DAY"></display-city> <display-city code="KAB"></display-city> </cities> <script> customElements.define("display-city", class extends HTMLElement { connectedCallback() { setTimeout(() => { // make sure all DOM is parsed let country = document.querySelector(`#AF`).content.cloneNode(true); let code = this.getAttribute("code"); this.attachShadow({mode:"open"}) .innerHTML = `<style>path:not([id="AF-${code}"]){display:none}</style>`; this.shadowRoot.append(country); let svg = this.shadowRoot.querySelector("svg"); let {x,y,width,height} = svg.querySelector(`#AF-${code}`).getBBox(); svg.setAttribute("viewBox", `${x} ${y} ${width} ${height}`); }) } }); </script> <template id="AF"> <style> path { fill: #CCCCCC; fill-opacity: 1; stroke: white; stroke-opacity: 1; stroke-width: 0.5; } </style> <svg viewBox="0 0 700 535"> <path id="AF-PAR" d="m424 186-1-1-2 1v1l-1 1-3 1-1 2-1 1-2 1h-1v1l-3 2-3-2-1 1h-1l-1 1v1l-1 1-1 1v1l-4 2v1h-3v2h1l-1 1-1 1h-10l-4-1-1 1-1 1-2 1h-1v1l3 2v9l1 1h1v3l1 1 2 2v1l1 1v2h3l1-1h1l3-2h5v1h2v1h4v1h2l2 1h1l1-3-1-2 2-3v-1l2-4 2-3v-1l3 1h1l4 1 2-1h1l1 1 1 1 2 1v2l2 2v1l1 1h1l1 1 1 2 1 3v2l1 1 2-1h1l1-1v-2h3v-3l-1-1-1-1v-10l-2-1-2-1h-3l-1-1-1-2h-1v-1h-2l-1-1h-1v-3l1-3-1-2h-2v-2l1-1v-12h-2z" /> <path id="AF-KAP" d="m434 201-2-1h-4l-1 1 1 2-1 3v3h1l1 1h2v1h1l1 2 1 1h3l2 1 2 1v10l1 1 1 1v3l1 1 3-1h2v-2l2-6h1l2-1 1-1h1v-1l1-1 1-1v-2l-1-1-1-3-1-1v-2l-2-1-1-2-1-2-1-2-1-1h-3l-2-1-3 1h-7z" /> <path id="AF-KAB" d="m416 217-3-1v1l-2 3-2 4v1l-2 3 1 2-1 3-1 2v6l1 1v1l2 1 2 1 1 3v1l7 2h4l4-3h1l1 2 1 1v1l1 1 2 2v1l1 1v1l1 1 1 2 1-1v-3l1-1 3-1 3-3 1-3 1-1v-2h1l6-1v-5h1v-4l-1-1 1-1 1-1v-5h1l2-2v-1h1v-2l-2-4-1 1v1h-1l-1 1-2 1h-1l-2 6v2h-2l-3 1-1-1h-3v2l-1 1h-1l-2 1-1-1v-2l-1-3-1-2-1-1h-1l-1-1v-1l-2-2v-2l-2-1-1-1-1-1h-1l-2 1-4-1h-1z" /> <path id="AF-DAY" d="M284 247h-1v-1h-1l-3-1h-1v1h-1l-1 2h-8v1h-1v1h-5l-7-1h-10l-1 2v3l-1 1v3h1v1l-1 1v2l-1 1v2h1v2h2v4h-1v1l-1 1v1l-1 1h-1l-2 1v3h1l1 1v1h1l1 1v1l1 2v3l1 1h1v1l1 1 1 1h-1l-1 1-1 1-2 2-2 1-1 2h-1l-1 1-1 1v1h1v1l-2 1h-3l-1 1-2 1 1 1 1 1h2v2l1 2 1 1 1 1v6h-1v2h2l1 1h1v-1h2l1 1v-3l-1-1h6l3 2h6v-1l1-1h1l2 2 1 1 6 1 2 1h1v-3l1-3v-1l1-1 1-1h3l5-5h1l1-1h1l1 1h1l3-1h1l1 1v1l1 1v1h1l1 1 3-2 2-1h2l1-1 1-1v1l1 1v1h2l1-1 1-3v-4l1-1v-2l-2-4v-2l1-1 1-1 5-2 2-1h2l4-1 1-1h1l1-1 1-1v-1l4-3 1-1 1-2 1-1 1-1-1-2v-2h-1v-1h-1 1v-1h1v-3l-1-1v1h-1v1h-4l-2 1-1 1v1h-1v-1h-3l-3 2-2-1-1-1-9-2h-3v1h-1l-2 1h-1l-2-2-3-3h-1v-5l2-2v-1l-1-2v-3l1-1h1v-1l-1-1-2-1h-2v-1l1-2h-1l-6 1h-1z" /> </svg> </template>
Custom mute/unmute button built with Vue mysteriously does not work in production but works perfectly in development
As the title suggests I'm having trouble figuring out why this mute/unmute button doesn't work. The code is below, but basically it's built with a v-hide directive that changes with an #click. When I use it on local host it works but when it is deployed on netlify it still mute/unmutes the video but the icon only changes once then is stuck on the unmute icon... I would appreciate any ideas as I've tried a bunch of different solutions with no success. Here is the relevant code: <template> <div class="flex flex-grow relative"> <div #click="toggleMute" class="z-20 bg-white absolute bottom-4 right-4 text-black rounded-full bg-opacity-75"> <div v-if="mute" class="sr-only">Unmute</div> <svg v-if="mute" class="h-12 w-12" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><title>Volume Mute</title><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M416 432L64 80"/><path d="M224 136.92v33.8a4 4 0 001.17 2.82l24 24a4 4 0 006.83-2.82v-74.15a24.53 24.53 0 00-12.67-21.72 23.91 23.91 0 00-25.55 1.83 8.27 8.27 0 00-.66.51l-31.94 26.15a4 4 0 00-.29 5.92l17.05 17.06a4 4 0 005.37.26zM224 375.08l-78.07-63.92a32 32 0 00-20.28-7.16H64v-96h50.72a4 4 0 002.82-6.83l-24-24a4 4 0 00-2.82-1.17H56a24 24 0 00-24 24v112a24 24 0 0024 24h69.76l91.36 74.8a8.27 8.27 0 00.66.51 23.93 23.93 0 0025.85 1.69A24.49 24.49 0 00256 391.45v-50.17a4 4 0 00-1.17-2.82l-24-24a4 4 0 00-6.83 2.82zM125.82 336zM352 256c0-24.56-5.81-47.88-17.75-71.27a16 16 0 00-28.5 14.54C315.34 218.06 320 236.62 320 256q0 4-.31 8.13a8 8 0 002.32 6.25l19.66 19.67a4 4 0 006.75-2A146.89 146.89 0 00352 256zM416 256c0-51.19-13.08-83.89-34.18-120.06a16 16 0 00-27.64 16.12C373.07 184.44 384 211.83 384 256c0 23.83-3.29 42.88-9.37 60.65a8 8 0 001.9 8.26l16.77 16.76a4 4 0 006.52-1.27C410.09 315.88 416 289.91 416 256z"/><path d="M480 256c0-74.26-20.19-121.11-50.51-168.61a16 16 0 10-27 17.22C429.82 147.38 448 189.5 448 256c0 47.45-8.9 82.12-23.59 113a4 4 0 00.77 4.55L443 391.39a4 4 0 006.4-1C470.88 348.22 480 307 480 256z"/></svg> <div v-if="!mute" class="sr-only">Mute</div> <svg v-if="!mute" class="h-12 w-12" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><title>Volume On</title><path xmlns="http://www.w3.org/2000/svg" d="M126 192H56a8 8 0 00-8 8v112a8 8 0 008 8h69.65a15.93 15.93 0 0110.14 3.54l91.47 74.89A8 8 0 00240 392V120a8 8 0 00-12.74-6.43l-91.47 74.89A15 15 0 01126 192zM320 320c9.74-19.38 16-40.84 16-64 0-23.48-6-44.42-16-64M368 368c19.48-33.92 32-64.06 32-112s-12-77.74-32-112M416 416c30-46 48-91.43 48-160s-18-113-48-160" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg> </div> <video id="video" ref="video" class="object-cover rounded-lg w-full h-full" src="/Jet_Token_Accelerate_1.mp4" autoplay="" loop="" muted="" playsinline=""></video> </div> </template> <script> export default { data() { return { mute: true } }, methods: { toggleMute() { var vid = this.$refs.video vid.muted = !vid.muted this.mute = !this.mute }, }, } </script> And the resulting mute button that successfully mutes and unmutes but which does not properly switch between the mute and unmute icon after the first click:
You can toggle the data mute first then pass that state to vid.muted so that the video and icon are in synced. toggleMute() { var vid = this.$refs.video this.mute = !this.mute; vid.muted = this.mute; }
Instead of manually setting the <video>'s muted property, you could just use the v-bind directive to bind the property to the component's mute: <template> <video :muted="mute"></video> </template> <script> export default { data() { return { mute: true } }, methods: { toggleMute() { this.mute = !this.mute } } } </script>