Moving a button in the middle of an SVG? - html

What would be the best way to move a playbutton in the middle of an SVG?
Is there anyone who can help me do this?
All the code is provided below. It's telling me to add more details, but that's about it. I put all the code below.
https://jsfiddle.net/cy8v6657/1/
<svg width="238" height="238" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
<button id="playButton2" style="width:50px; height:50px; border:none; cursor: pointer; background-color:transparent; background-image: url('https://i.imgur.com/A445IfJ.png')" onclick="
var player = document.getElementById('player');
player.volume=1.0;
var button = document.getElementById('playButton2');
if (player.paused) {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/qg4rg7Z.png\')';
player.play();
} else {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/A445IfJ.png\')';
player.pause();
}">
</button>
<audio id="player" preload="none" style="display:none;">
<source src='' type='audio/mpeg'/>
</audio>

Place both - your svg and your button, inside a wrapper div.
Give position relative to this wrapper div.
Center the button using absolute positioning inside the wrapper div.
#svg-wrapper{
position: relative;
width: 238px;
height: 238px;
}
#svg-wrapper #playButton2{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div id="svg-wrapper">
<svg width="238" height="238" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
<button id="playButton2" style="width:50px; height:50px; border:none; cursor: pointer; background-color:transparent; background-image: url('https://i.imgur.com/A445IfJ.png')" onclick="
var player = document.getElementById('player');
player.volume=1.0;
var button = document.getElementById('playButton2');
if (player.paused) {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/qg4rg7Z.png\')';
player.play();
} else {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/A445IfJ.png\')';
player.pause();
}">
</button>
</div><!--#svg-wrapper-->
<audio id="player" preload="none" style="display:none;">
<source src='' type='audio/mpeg'/>
</audio>
Update
If you cannot use external stylesheet for some reason as you mentioned in comments, you can use the same styles inline.
Change following lines:
<div id="svg-wrapper" style="position: relative;width: 238px;height: 238px;">
<button id="playButton2" style="position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width:50px; height:50px; border:none; cursor: pointer; background-color:transparent; background-image: url('https://i.imgur.com/A445IfJ.png')" onclick="
var player = document.getElementById('player');
player.volume=1.0;
var button = document.getElementById('playButton2');
if (player.paused) {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/qg4rg7Z.png\')';
player.play();
} else {
playButton2.style.backgroundImage = 'url(\'https://i.imgur.com/A445IfJ.png\')';
player.pause();
}">
</button>

Related

Rotate svg in a div container

I created an svg. Since I need to rotate it by 45degree, I wrapped it in a div that I transform with a rotation.
It works but the svg overflows the window.
Here the code:
.container {
background-color: tomato;
transform: rotate(45deg);
width: max-content;
}
<div class="container">
<svg width="200" height="200" x="0" y="0">
<rect x="0" y="0" width="100" height="100" fill="pink" stroke="black" />
<rect x="100" y="0" width="100" height="100" fill="white" stroke="black" />
<rect x="0" y="100" width="100" height="100" fill="white" stroke="black" />
<rect x="100" y="100" width="100" height="100" fill="white" stroke="black" />
</svg>
</div>
This is what I would like to obtain:
I would rotate just svg, because you don't need to rotate whole container. You still need add some padding because, when you rotate square it is longer left to right than before.
.container {
width: max-content;
padding: 50px;
}
svg {
transform: rotate(45deg);
}
<div class="container">
<svg width="200" height="200" x="0" y="0">
<rect x="0" y="0" width="100" height="100" fill="pink" stroke="black" />
<rect x="100" y="0" width="100" height="100" fill="white" stroke="black" />
<rect x="0" y="100" width="100" height="100" fill="white" stroke="black" />
<rect x="100" y="100" width="100" height="100" fill="white" stroke="black" />
</svg>
</div>

Why is my SVG icon so blurry on larger screens?

I'm quite new to using SVG icons and I can't seem to figure out why my icon is blurry. Could you help? Thanks
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<mask id="mask0_12_275" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="12" height="12">
<rect width="12" height="12" fill="url(#pattern0)"/>
</mask>
<g mask="url(#mask0_12_275)">
<rect x="-5" y="-7" width="23" height="21" fill="#C6C6C6"/>
<rect x="-5" y="-7" width="23" height="21" fill="black" fill-opacity="0.2"/>
<rect x="-5" y="-7" width="23" height="21" fill="black" fill-opacity="0.2"/>
</g>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_12_275" transform="scale(0.01)"/>
</pattern>
<image id="image0_12_275" width="100" height="100" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAD4ElEQVR4nO3dy2tcVRwH8M+Mj9iSNI31gfisVEVLU1QEQS2C26JiN75wIxIEBVFEFy66K4ob3bjxfxB0o7gQXPlCpZhidyrik7aKqRpbGxfniul0xrl35s7MuZPfB36bm5nMOeebOzf3d+8khBBCCCGEEEIIIYQQQgghhBBCCKGqGTyJD7CCtaihaqVYyydwboUcwKX4PINJTGt9VqxxKTMRxljqU132lHaXQJawu8v2UK8b8Vjnxm6BPDT6sYTCw50bWl0e9BtmRz+WIB3o59Zv6BbI2njGEgqnZdDtLStMUASSmQgkMxFIZiKQzEQgmYlAMnN2zd/vBJalPs0yvsO3OIY/iq+v4BR+LZ4zL/1gzOIcbMICLpMacDfgJuwsvj5N4yqlapPsFN7EAzrOOms2hwfxVvGaTR1XZ/VV5Zst445aplXNHhxq4LhGGsghbK1tKtUt4MsGjWvkgdxd4yQGda/mjGvkgWypcwYDmteccZUKZJhub7fnTkLneHMdVy/R7c1ZBJKZCCQzdZ+pT0Iux4xaxB6SmQgkMxFIZqoeQ/7GO3h9yNedwRVS1/SCdbWtqFmpabe5eOxW6S6/ztuT5pw5hzX80rHtd6wW21dxXOruruBIR/2M7/GV1Ake1F14FPfhvLJPKntieByv4RWpbV3GWbgai9iF63BlUZf0eO3c/ISv8Q0O46DUuDwstezLOF+6wfopqc/Vqe86rD+tX8VLuLDEC89jL17Gh1KIVVvRTalV6YbpV7Gvwvrsl/a6gXpZ7+H6Po/djufxEU7WMNGm1ilp79lfYs124N11z+3rBJ7Ve1fahMelvWDSC5FrHcTTel8Ya+EZJd/27uyxfQEv4McMJtyUOoYDuLjiWv+vFh6RDnCTnmBTawXPSb/oDOUqvJ/BhKalPsa1lRJY51b8kMEkpq2OSucoldyDPzMY/LTWX7i/bBi3iE/djiuUvnvK5eLgPc46Kp3L9fRGBoPcaPV2rzD2ZjC4jVr7ugXySQYD26j1haIz8u/1kNtwc7eUwljsxO38F8jS5MYSCkuk3aQlXZDp1W8J43EEF7WlC0gRxuRtw662dAt9yMOetiGaXaF217SlK1ghDzva+py6h7Ha3pYuvoc8bGlL9z6FPGxuSRfap+Gm62lQ9l6vEEII4QwtqR8fMhGfD8lMBJKZCCQzEUhmIpDMRCCZiUAyE4FkJgLJ0KB3252UPq61KC5ykdZgUVqTYT4AO/ATD4x8is31ogkEEv8WqbfdJhBIvE31VuVvLp5Ww3R7m/CnMSZpoHWN37IyE4FkJgLJTASSmQgkMxFIZiKQzPwDFB6i1e0VaQEAAAAASUVORK5CYII="/>
</defs>
</svg>

Any ideas on how to DRY code this navbar in React?

i'm creating a SPA using React and noticed that in the creation of my navbar there is going to be a lot of repetition. What i want is six components like this:
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
<NavbarItem1 />
<NavbarItem2 />
<NavbarItem3 />
<NavbarItem4 />
<NavbarItem5 />
</div>
</nav>
)
}
Now for the repetition part, every component is going to be basically this:
function NavbarItem1() {
return (
<div className="navbar-item">
<button className="navbar-button">
<svg class="navbar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 80" x="0px" y="0px">
<g>
<path
d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path
d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
<span class="navbar-text">Item 1</span>
</button>
</div>
)
}
So instead of creating six components who are basically the same, is there a less repetitive way of doing this or is this the normal way people create navbars using React?? Thanks in advance for your answer.
Assuming that the parts that differ between each navbar item are the icon and its text content, you can extract the icons into their own components, then just pass the icon component and the text via props:
// Pass className via props so the NavbarItem can set it
function NoteIcon({ className }) {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 80"
x="0px"
y="0px"
>
<g>
<path d="M52,7a5.006,5.006,0,0,0-5-5H7A5.006,5.006,0,0,0,2,7V56H4V7A3,3,0,1,1,8,9.816V7H6V62H48V11.9A5.009,5.009,0,0,0,52,7ZM8,60V12H46V60ZM47,10H10.974a4.9,4.9,0,0,0,0-6H47a3,3,0,0,1,0,6Z" />
<path d="M57,8a5.006,5.006,0,0,0-5,5V52.236l5,10,5-10V13A5.006,5.006,0,0,0,57,8ZM56,48.586,54.845,47.43,54,48.7V22h2Zm-1.846,3.486,1-1.5L57,52.414l1.845-1.844,1,1.5L57,57.764ZM60,48.7l-.845-1.267L58,48.586V22h2ZM60,20H54V18h6Zm-6-4V13a3,3,0,0,1,6,0v3Z" />
<rect x="12" y="20" width="30" height="2" />
<rect x="12" y="28" width="30" height="2" />
<rect x="12" y="35" width="30" height="2" />
<rect x="12" y="43" width="30" height="2" />
<rect x="12" y="50" width="18" height="2" />
<rect x="36" y="50" width="2" height="2" />
<rect x="32" y="50" width="2" height="2" />
<rect x="40" y="50" width="2" height="2" />
</g>
</svg>
);
}
function NavbarItem({ icon: Icon, children }) {
return (
<div className="navbar-item">
<button className="navbar-button">
<Icon className="navbar-icon" />
<span className="navbar-text">{children}</span>
</button>
</div>
);
}
function Navbar() {
return (
<nav className="navbar">
<div className="navbar-items">
<Logo />
{/* Pass the correct icon component, and the text via children */}
<NavbarItem icon={NoteIcon}>Item 1</NavbarItem>
<NavbarItem icon={OtherIcon}>Item 2</NavbarItem>
<NavbarItem icon={AnotherIcon}>Item 3</NavbarItem>
</div>
</nav>
);
}

How to embed svg into svg?

I have to perform this task in which i have to embed one svg into another svg.
As I am new to SVG, I have done the polygon and rectangle part but while combining these two I am facing issues. I am attaching my work up to which I have completed.
Don't have a bunch of SVGs. Instead you should just put all your shapes into one big SVG.
Below is a quick example. But remember, you might find it easier to just use one of the many available vector drawing apps to create your SVG.
<!DOCTYPE html>
<html>
<body>
<svg width="550" height="400">
<g>
<rect width="300" height="30" style="fill:rgb(255,0,0);" />
<text x="10" y="20" fill="white">Fatality</text>
</g>
<g transform="translate(0,40)">
<rect width="300" height="30" style="fill:rgb(255,0,0);" />
<text x="10" y="20" fill="white">Lost Time Incidents</text>
</g>
<g transform="translate(0,80)">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="10" y="20" fill="white">Restricted Work Cases</text>
</g>
<g transform="translate(0,120)">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="10" y="20" fill="white">Medical Treatment Cases</text>
</g>
<g transform="translate(0,160)">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="10" y="20" fill="white">First Aid Cases</text>
</g>
<g transform="translate(0,200)">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="10" y="20" fill="white">RTA Incident</text>
</g>
<g transform="translate(0,240)">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="10" y="20" fill="white">Environment Incident</text>
</g>
<g transform="translate(0,280)">
<rect width="300" height="30" style="fill:rgb(102,204,0);" />
<text x="10" y="20" fill="white">Near Miss</text>
</g>
<g transform="translate(0,320)">
<rect width="300" height="30" style="fill:rgb(102,204,0);" />
<text x="10" y="20" fill="white">Unsafe Acts & Conditions</text>
</g>
<g transform="translate(0,360)">
<rect width="300" height="30" style="fill:rgb(102,178,255);" />
<text x="10" y="20" fill="white">Man Hours</text>
</g>
<polygon points="350,0, 550,400, 150,400" style="fill:white;stroke:black;stroke-width:1" />
</svg>
In order to embed one svg into another svg you have to use it the same way you would use a <symbol> element.
const SVG_NS = 'http://www.w3.org/2000/svg';
let colors = [
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(255,128,0)",
"rgb(102,204,0)",
"rgb(102,204,0)",
"rgb(102,178,255)"
];
let angle = Math.atan2(215,430);
let n = 0;
let offset = 10;// distance between the border of the triangle and the start of the rectangle
for(let y = 40; y < 430; y+= 40){
let halfW = Math.tan(angle)*y - offset;
let o = {
x:430/2 - halfW,
y: y,
width: 2*halfW,
height: 30,
fill:colors[n]
}
drawRect(o, polys);
n++;
}
function drawRect(o, parent) {
let rect = document.createElementNS(SVG_NS, 'rect');
for (var name in o) {
if (o.hasOwnProperty(name)) {
rect.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(rect);
return rect;
}
svg{max-width:100vh}
<svg viewBox="0 0 600 600" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="400" height="30" y="40">
<rect width="300" height="30" style="fill:rgb(255,0,0);" />
<text x="0" y="15" fill="white">Fatality</text>
</svg>
<svg width="400" height="30" y="80">
<rect width="300" height="30" style="fill:rgb(255,0,0);" />
<text x="0" y="15" fill="white">Lost Time Incidents</text>
</svg>
<svg width="400" height="30" y="120">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="0" y="15" fill="white">Restricted Work Cases</text>
</svg>
<svg width="400" height="30" y="160">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="0" y="15" fill="white">Medical Treatment Cases</text>
</svg>
<svg width="400" height="30" y="200">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="0" y="15" fill="white">First Aid Cases</text>
</svg>
<svg width="400" height="30" y="240">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="0" y="15" fill="white">RTA Incident</text>
</svg>
<svg width="400" height="30" y="280">
<rect width="300" height="30" style="fill:rgb(255,128,0);" />
<text x="0" y="15" fill="white">Environment Incident</text>
</svg>
<svg width="400" height="30" y="320">
<rect width="300" height="30" style="fill:rgb(102,204,0);" />
<text x="0" y="15" fill="white">Near Miss</text>
</svg>
<svg width="400" height="30" y="360">
<rect width="300" height="30" style="fill:rgb(102,204,0);" />
<text x="0" y="15" fill="white">Unsafe Acts & Conditions</text>
</svg>
<svg width="400" height="30" y="400">
<rect width="300" height="30" style="fill:rgb(102,178,255);" />
<text x="0" y="15" fill="white">Man Hours</text>
</svg>
<svg id="polys" height="430" width="430" viewBox="0 0 430 430" x="160" >
<polygon points="215,0, 0,430 430,430 215,0" style="fill:white;stroke:red;stroke-width:1" />
</svg>
</svg>

How would I create an opaque coloured box with transparent text on top of a video?

I currently have this:
A Screenshot of current "model"
The background is a video, so it is supposed to make the text appear "alive".
I've done this through SVG, how do I change the background from black to white? Fill-opacity doesn't seem to work with other colors than black.
If this isn't possible, is there anyway do this this through CSS or Javascript?
<video autoplay muted loop poster="../billeder/Blue-Horizon.jpg" id="bgvid">
<source src="../video/Blue-Horizon.mp4" type="video/mp4">
<source src="../video/Blue-Horizon.webm" type="video/webm">
</video>
<svg viewbox="0 0 100 60">
<defs>
<mask id="mask" x="0" y="0" width="60" height="50">
<rect x="10" y="10" width="82" height="35" fill="#fff" stroke-opacity="0.8"/>
<text text-anchor="middle" x="51" y="35" dy="1" style="font-size:18px; font-weight: 900" opacity="1">SUMMER</text>
</mask>
</defs>
<rect x="5" y="15" width="95" height="30" mask="url(#mask)" fill-opacity="0.5"/>
</svg>
If you want the rect to be white, set its fill to white.
<svg viewBox="0 0 100 60">
<defs>
<mask id="mask" x="0" y="0" width="60" height="50">
<rect x="10" y="10" width="82" height="35" fill="#fff" stroke-opacity="0.8"/>
<text text-anchor="middle" x="51" y="35" dy="1" style="font-size:18px; font-weight: 900" opacity="1">SUMMER</text>
</mask>
</defs>
<image width="100" height="60" xlink:href="https://image.freepik.com/free-photo/sea-water_1160-2.jpg"/>
<rect x="5" y="15" width="95" height="30" mask="url(#mask)" fill="white" fill-opacity="0.5"/>
</svg>