How do I make my rotating polygon element (svg) to be responsive? - svg

I am trying to make my triangle rotate around the circle for my college assignment, but I have a problem making my triangle responsive.
The blue-purple triangle is supposed to be rotating inside the orange square box and the size should be responsive like the other shapes, but my knowledge is very limited.
Is there any solution for squashing my little triangle into the square?
I appreciated your help in advance...
body {
background-color: white;
}
svg {
position: absolute;
width: 100vw;
height: 100vh;
fill:white;
}
.box {
position: relative;
width: 30vw;
height: 30vw;
fill:white;
stroke:orange;
stroke-width: 1px;
}
.circleAndTriangle {
animation: colorChange 5s linear infinite;
}
.triangle {
transform-origin: 50vw 35vw;
position: absolute;
animation: rotatingTriangle 5s linear reverse infinite;
}
#keyframes colorChange {
0% {fill:blue }
100% {fill:red}
}
#keyframes rotatingTriangle {
0% {transform: rotate(0deg);}
100% {transform: rotate(-360deg);}
}
<!DOCTYPE html>
<html lang="en-UK">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link type="text/css" href="https://cdn.jsdelivr.net/npm/reset-css#3.0.0/reset.min.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<title>Rotating Study</title>
</head>
<body>
<svg>
<rect x="35vw" y="20vw" rx="0px" ry="0px" class="box"/>
<g class="circleAndTriangle">
<circle cx= "50vw" cy="35vw" r="1.5vw" class="circle"/>
<polygon points="250,150,280,150,265,175" class="triangle"/>
</g>
</svg>
</body>
</html>

As #enxaneta suggested. You should give the SVG a viewBox and keep everything within the SVG. Then just use CSS to size and position the SVG on your page.
/*Background*/
body {
background-color: white;
}
/*Grouped Animation*/
svg {
position: absolute;
top: 35vh;
left: 35vw;
width: 30vw;
height: 30vw;
fill:white;
}
/*Square in the middle of the BG with thin green stroke*/
.box {
fill:white;
stroke:orange;
stroke-width: 1px;
}
/*Color Changes in both Circle & Triangle*/
.circleAndTriangle {
animation: colorChange 5s linear infinite;
}
/*Triangle rotating around the circle*/
.triangle {
transform-origin: 50px 50px;
animation: rotatingTriangle 5s linear reverse infinite;
}
#keyframes colorChange {
0% {fill:blue }
100% {fill:red}
}
#keyframes rotatingTriangle {
0% {transform: rotate(0deg);}
100% {transform: rotate(-360deg);}
}
<svg viewBox="0 0 100 100">
<rect x="1" y="1" width="98" height="98" class="box"/>
<g class="circleAndTriangle">
<circle cx= "50" cy="50" r="5" class="circle"/>
<polygon points="45,93, 55,93, 50,98" class="triangle"/>
</g>
</svg>

Related

Safari won't rotate an SVG path but chrome and firefox does?

I'm running into an extremely odd issue. I'm trying to animate an SVG path rotation based on an image hover. It seems to not add the class with the transform when you hover over the image. When I manually add it in the HTML it does work but I don't get why it won't work with just a hover function. I have added all the prefixes too. I made a codepen with an example SVG and image to hover. Please check this in safari and chrome.
Codepen link
HTML
<div class="wrapper-logo">
<svg class="App-logo" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg">
<path class="LETTER-P" d="M39.3,6.1c9.59-.72,18.89,2.31,26.17,8.58,14.99,12.98,16.72,35.69,3.68,50.69-12.98,15.07-35.76,16.8-50.75,3.82-2.52-2.24-4.76-4.83-6.63-7.64v14.13c0,1.59-1.3,2.88-2.88,2.88s-2.88-1.3-2.88-2.88V41.94c0-8.58,3.1-16.94,8.72-23.43,6.27-7.28,14.99-11.68,24.58-12.4Z" />
</svg>
</div>
<svg class="App-pill" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg"> <defs>
<mask id="mask-p">
<path class="LETTER-P" d="M39.3,6.1c9.59-.72,18.89,2.31,26.17,8.58,14.99,12.98,16.72,35.69,3.68,50.69-12.98,15.07-35.76,16.8-50.75,3.82-2.52-2.24-4.76-4.83-6.63-7.64v14.13c0,1.59-1.3,2.88-2.88,2.88s-2.88-1.3-2.88-2.88V41.94c0-8.58,3.1-16.94,8.72-23.43,6.27-7.28,14.99-11.68,24.58-12.4Z" fill="white"/>
<path class='pill-1' d="M47.3377 18.8021L18.8226 47.1101C13.7279 52.1678 13.7293 60.3942 18.8258 65.3743C23.9223 70.4298 32.2122 70.4281 37.2309 65.3704L65.746 37.0624C68.2554 34.5713 69.5477 31.2502 69.5471 27.9295C69.5465 24.6087 68.253 21.2882 65.7428 18.7982C60.7223 13.7426 52.4325 13.7444 47.3377 18.8021Z" fill="black"/>
</mask>
</defs>
</svg>
<footer>
<img src="https://via.placeholder.com/150
C/O https://placeholder.com/" class="shoes small" alt="browns" onmouseover="rotateBrowns(this)" />
</footer>
CSS
.App-pill {
display: block;
width: 0;
height: 0;
}
.App-logo {
min-width: 50%;
pointer-events: none;
}
/* LETTER */
.LETTER-P {
-webkit-mask: url(#mask-p);
mask: url(#mask-p);
}
.pill-1 {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
-webkit-transform-origin: 42px 41px;
-ms-transform-origin: 42px 41px;
transform-origin: 42px 41px;
}
.horizontal {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
JS
let shoesarray = document.querySelectorAll('.shoes')
let path1 = document.querySelector('.pill-1')
let path2 = document.querySelector('.pill-1')
let path3 = document.querySelector('.pill-1')
let path4 = document.querySelector('.pill-1')
function rotateBrowns() {
console.log('e')
path1.classList.add('horizontal')
path2.classList.add('horizontal')
path3.classList.add('horizontal')
path4.classList.add('horizontal')
}
function revertBrowns() {
console.log('e')
path1.classList.remove('horizontal')
path2.classList.remove('horizontal')
path3.classList.remove('horizontal')
path4.classList.remove('horizontal')
}

Transform svg parent causes blur - firefox

When I make flip-card and insert into (front and back) the same svg code after rotateY svg on back-card display blurry (when zoomed in). An example below. I would like to add that the problem only concerns the firefox browser (Microsoft Edge, Opera - they work properly). Of course i want to have sharp svg on both side card.
Any thoughts?
var front = document.querySelector('.flip-card-front');
var back = document.querySelector('.flip-card-back');
var innner = document.querySelector('.flip-card-inner');
front.addEventListener( 'click', function() {
innner.classList.toggle("flip-card-cl");
});
back.addEventListener( 'click', function() {
innner.classList.toggle("flip-card-cl");
});
body {
font-family: Arial, Helvetica, sans-serif;
}
.flip-card {
background-color: transparent;
width: 300px;
height: 300px;
perspective: 1000px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s;
transform-style: preserve-3d;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}
.flip-card-cl {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.flip-card-front {
background-color: #bbb;
color: black;
}
.flip-card-back {
background-color: #2980b9;
color: white;
transform: rotateY(180deg);
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div>Click card to rotate</div><br>
<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<p>SHARP</p>
<svg height="210" width="500">
<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;"/>
Sorry, your browser does not support inline SVG.
</svg>
</div>
<div class="flip-card-back">
<p>BLUR</p>
<svg height="210" width="500">
<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;"/>
Sorry, your browser does not support inline SVG.
</svg>
</div>
</div>
</div>
</body>
</html>
I can see it after zooming:
front side - sharp
back side - blur

Why is SVG width 0 if container is display flex?

When I run the following code in a browser:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
svg {
border:1px solid green;
width:200px !important;
height:200px;
}
#container {
position:fixed;
top:300px;
left:800px;
width:1px;
height:1px;
overflow:visible;
display:flex;
flex-wrap:wrap;
justify-content:center;
align-content:center;
}
</style>
</head>
<body>
<div id="container">
<svg class="e3" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/>
</svg>
</div>
</body>
</html>
All I get is a 2 pixel vertical line in the browser. It seems the width of my SVG is 0 (not including the green borders). When I delete the css rule display:flex, then my SVG circle appears. I tried to force my SVG to have a width: 200px !important; but this rule doesn't seem to take effect.
Why is my SVG not respecting the 200px rule when I use display:flex on the container?
I believe your SVG node is not displaying as you expect because it has a default position of static. If you change the SVG node to be absolute you'll get the desired behavior.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
svg {
position: absolute;
border: 1px solid green;
width: 200px;
height: 200px;
}
#container {
position: fixed;
/* changed these for ease of viewing */
top: 30px;
left: 150px;
width: 1px;
height: 1px;
overflow: visible;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="container">
<svg class="e3" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/>
</svg>
</div>
</body>
</html>

Issue perfectly masking a div using an SVG frame

I'm trying to mask a div with an SVG 'frame'. Despite positioning the SVG absolutely and setting height/width to 100%, there's still slivers of the parent div visible around the bottom and right edges.
html
<div class="container">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-144 2 502 609" style="enable-background:new -144 2
502 609;" xml:space="preserve" preserveAspectRatio="none">
<style type="text/css"></style>
<path class="st0" d="M-144,2v608h501.2V2H-144z M354.5,608.5l-
496.2-12.2C-147,201.8-62.3,4.5,112.5,4.5S367.8,205.8,354.5,608.5z"
/>
</svg>
</div>
css
html,
body {
height: 100%;
width: 100%;
margin:0;
padding:0;
}
.container {
width: 50%;
height: 50%;
top: 25%;
margin:auto;
background: pink;
position: relative;
}
svg {
position: absolute;
top:0;
left:0;
height: 100%;
width: 100%;
}
.st0{
fill: white;
}
https://jsfiddle.net/samseurynck/b2x58ahc/
I'd like the white SVG shape to completely mask out the pink div behind it, with no slivers of the div showing (on the bottom and right sides) like it is now. The slivers seem to scale up with the browser. I'm curious if this is even possible with SVG if the way I've tried it isn't working.
I've made a few changes to the path. While the viewBox="-144 2 502 609"the path goes to 501.2 instead of 502 (in x) and to 608.5 instead of 609 (in y). I've changed those numbers in your path.
html,
body {
height: 100%;
width: 100%;
margin:0;
padding:0;
}
.container {
width: 50%;
height: 50%;
top: 25%;
margin:auto;
background: pink;
position: relative;
}
svg {
position: absolute;
top:0;
left:0;
height: 100%;
width: 100%;
}
.st0{
fill: white;
}
<div class="container">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-144 2 502 609" style="enable-background:new -144 2 502 609;" xml:space="preserve" preserveAspectRatio="none">
<style type="text/css">
</style>
<path class="st0" d="M-144,2v609h502V2H-144z M354.5,609l-496.2-12.2C-147,201.8-62.3,4.5,112.5,4.5S367.8,205.8,354.5,609z"
/>
</svg>
</div>

Animate SVG Hamburger menu icon on click and keep it in :active state

I have a SVG hamburger menu icon that is animated when clicked. The goal is to transform it in to a "close" button when you activate the side-push menu. I need some help achieving that:
http://jsfiddle.net/a6ysa9zk/
HTML:
<div class="toggle-menu menu-right push-body">
<svg class="inline-svg" width="42px" height="42px" viewBox="0 0 42 42" enable-background="new 0 0 32 22.5" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.0.4 (8054) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g class="svg-menu-toggle" sketch:type="MSLayerGroup">
<circle class="round" fill="#3B3B41" sketch:type="MSShapeGroup" cx="21" cy="21" r="21"></circle>
<rect class="bar" fill="#F2F2F2" sketch:type="MSShapeGroup" x="12" y="26" width="18" height="4"></rect>
<rect class="bar" fill="#F2F2F2" sketch:type="MSShapeGroup" x="12" y="19" width="18" height="4"></rect>
<rect class="bar" fill="#F2F2F2" sketch:type="MSShapeGroup" x="12" y="12" width="18" height="4"></rect>
</g>
</svg>
</div>
CSS:
.svg-menu-toggle {
fill: #fff;
pointer-events: all;
cursor: pointer;
}
.svg-menu-toggle .round {
transition: fill .4s ease-in-out;
}
.svg-menu-toggle .bar {
-webkit-transform: rotate(0) translateY(0) translateX(0);
transform: rotate(0) translateY(0) translateX(0);
opacity: 1;
-webkit-transform-origin: 20px 10px;
transform-origin: 20px 10px;
-webkit-transition: -webkit-transform 0.4s ease-in-out, opacity 0.2s ease-in-out, fill .4s ease-in-out;
transition: transform 0.4s ease-in-out, opacity 0.2s ease-in-out, fill .4s ease-in-out;
}
.svg-menu-toggle .bar:nth-of-type(1) {
-webkit-transform-origin: 20px 10px;
transform-origin: 20px 10px;
}
.svg-menu-toggle .bar:nth-of-type(3) {
-webkit-transform-origin: 20px 20px;
transform-origin: 20px 20px;
}
.svg-menu-toggle:active .bar:nth-of-type(1) {
-webkit-transform: rotate(-45deg) translateY(-10px) translateX(-8px);
transform: rotate(-45deg) translateY(-10px) translateX(-8px);
fill: #3B3B41;
}
.svg-menu-toggle:active .bar:nth-of-type(2) {
opacity: 0;
}
.svg-menu-toggle:active .bar:nth-of-type(3) {
-webkit-transform: rotate(45deg) translateY(6px) translateX(0px);
transform: rotate(45deg) translateY(6px) translateX(0px);
fill: #3B3B41;
}
.svg-menu-toggle:active .round {
fill: #F2F2F2;
}
Javascript for menu toggle:
jQuery(document).ready(function ($) {
$('.toggle-menu').jPushMenu();
});
Instead of using the :active pseudo-element, its easier to add a class to the group (.svg-menu-toggle).
Unfortunately it isn't possible to use toggleClass from jQuery.
// CSS
.svg-menu-toggle:active become .svg-menu-toggle.active
// JS
$('.toggle-menu').on('click', function(e) {
var $toggle = $(this).find('.svg-menu-toggle');
// toggleClass with addClass & removeClass
});

Resources