Converting seconds in mm:ss in running JavaScript Timer - javascript

I'm just trying to update a friend's timer, which we did for an event a while ago. The timer works perfectly and already does everything it should (see and run Snippet). However, now I would like to display the format mm:ss instead of only seconds (eg. 180 -> 3:00). This must of course be able to count down further. Different approaches I googled have failed. Has anyone an idea how to solve my problem elegantly?
Edit: You can start and stop the timer by pressing 'Space'
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #333;
font-family: sans-serif;
}
.item {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%) scale(3.0);
}
.item h1 {
text-align: center;
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 3em;
}
.item h2 {
text-align: center;
position: absolute;
width: 50%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 1.5em;
line-height: 0.9;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440;
/* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
</style>
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
var running = false;
var time = 180;
var initialOffset = '440';
var runtime = 0;
$(document).keydown(function(e) {
switch (e.which) {
case 32:
setTimeout(function() {
if (running === false) {
running = true;
} else {
running = false;
};
}, 1);
break;
}
});
$(document).ready(function() {
console.log("ready!");
$('#start').click(function() {
running = true;
});
var interval = setInterval(function() {
$('.circle_animation').css('stroke-dashoffset', initialOffset - (runtime * (initialOffset / (time + 10.5))));
$('h1').text(time - runtime);
if (runtime == 420) {
audioElement1.play();
}
if (runtime == time) {
clearInterval(interval);
$('.circle_animation').css('stroke-dashoffset', 880);
$('h1').text('');
$('h2').text('Time is up!');
}
if (running) {
runtime++;
};
}, 1000);
});
</script>
</head>
<body>
<div class="item html">
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" r="65.85699" cy="81" cx="81" stroke-width="15" stroke="#ffffff" fill="none"/>
<circle id="circle" class="circle_animation" r="65.85699" cy="81" cx="81" stroke-width="16" stroke="#333" fill="none"/>
</g>
</svg>
<h1>180</h1>
<h2></h2>
</div>
</body>
</html>

Use modulus math:
function sec2human(seconds) {
sec = seconds % 60;
min = parseInt(seconds / 60);
if(sec.toString().length == 1) { // padding
sec = "0" + sec;
}
return min + ":" + sec;
}
Full working example:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #333;
font-family: sans-serif;
}
.item {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%) scale(3.0);
}
.item h1 {
text-align: center;
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 3em;
}
.item h2 {
text-align: center;
position: absolute;
width: 50%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 1.5em;
line-height: 0.9;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440;
/* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
</style>
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
var running = false;
var time = 180;
var initialOffset = '440';
var runtime = 0;
$(document).keydown(function(e) {
switch (e.which) {
case 32:
setTimeout(function() {
if (running === false) {
running = true;
} else {
running = false;
};
}, 1);
break;
}
});
$(document).ready(function() {
console.log("ready!");
$('#start').click(function() {
running = true;
});
$('h1').text(sec2human(time)); // added for initial display
var interval = setInterval(function() {
$('.circle_animation').css('stroke-dashoffset', initialOffset - (runtime * (initialOffset / (time + 10.5))));
$('h1').text(sec2human(time - runtime)); // added function call
if (runtime == 420) {
audioElement1.play();
}
if (runtime == time) {
clearInterval(interval);
$('.circle_animation').css('stroke-dashoffset', 880);
$('h1').text('');
$('h2').text('Time is up!');
}
if (running) {
runtime++;
};
}, 1000);
});
function sec2human(seconds) {
sec = seconds % 60;
min = parseInt(seconds / 60);
if(sec.toString().length == 1) { // padding
sec = "0" + sec;
}
return min + ":" + sec;
}
</script>
</head>
<body>
<div class="item html">
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" r="65.85699" cy="81" cx="81" stroke-width="15" stroke="#ffffff" fill="none"/>
<circle id="circle" class="circle_animation" r="65.85699" cy="81" cx="81" stroke-width="16" stroke="#333" fill="none"/>
</g>
</svg>
<h1>180</h1>
<h2></h2>
</div>
</body>
</html>

Here is the important part:
var seconds = time - runtime,
mins = ("0" + Math.floor(seconds / 60)).substr(-2),
secs = ("0" + (seconds % 60)).substr(-2);
$('h1').text(mins + ":" + secs);
Basically split up each part by minutes and seconds and concatenate them. The substring is to enforce double digit padding (ie: 02:03 instead of 2:3)
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #333;
font-family: sans-serif;
}
.item {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%) scale(3.0);
}
.item h1 {
text-align: center;
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 3em;
}
.item h2 {
text-align: center;
position: absolute;
width: 50%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-110%);
color: #ffffff;
font-size: 1.5em;
line-height: 0.9;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440;
/* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
</style>
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
var running = false;
var time = 180;
var initialOffset = '440';
var runtime = 0;
$(document).keydown(function(e) {
switch (e.which) {
case 32:
setTimeout(function() {
if (running === false) {
running = true;
} else {
running = false;
};
}, 1);
break;
}
});
$(document).ready(function() {
console.log("ready!");
$('#start').click(function() {
running = true;
});
var interval = setInterval(function() {
$('.circle_animation').css('stroke-dashoffset', initialOffset - (runtime * (initialOffset / (time + 10.5))));
var seconds = time - runtime,
mins = ("0" + Math.floor(seconds / 60)).substr(-2),
secs = ("0" + (seconds % 60)).substr(-2);
$('h1').text(mins + ":" + secs);
if (runtime == 420) {
audioElement1.play();
}
if (runtime == time) {
clearInterval(interval);
$('.circle_animation').css('stroke-dashoffset', 880);
$('h1').text('');
$('h2').text('Time is up!');
}
if (running) {
runtime++;
};
}, 1000);
});
</script>
</head>
<body>
<div class="item html">
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" r="65.85699" cy="81" cx="81" stroke-width="15" stroke="#ffffff" fill="none"/>
<circle id="circle" class="circle_animation" r="65.85699" cy="81" cx="81" stroke-width="16" stroke="#333" fill="none"/>
</g>
</svg>
<h1>180</h1>
<h2></h2>
</div>
</body>
</html>
Cool animation btw.

Related

why does event Listener need two elements?

In the code below, you'll notice i have two event listeners
window.addEventListener("click", jump);
window.addEventListener("click", jump());
The problem is removing either one of these makes the event listener invalid i.e. it doesnt work, they have to both be present and I'm having a hard time figuring out why.
note: click to jump and view snippet in full page since i havent done the responsive part yet
const ball = document.querySelector(".ball");
const obs = document.querySelector(".obstacle");
const score = document.querySelector("#s");
let temp = 0; // a temporary variable to stop event listener from running as soon as game starts
function jump() {
let bottom = parseInt(window.getComputedStyle(ball).getPropertyValue('bottom'));
if (temp > 0 && bottom === 150) {
ball.style.bottom = "400px";
setTimeout(() => {
ball.style.bottom = "150px";
}, 300);
}
temp++;
}
window.addEventListener("click", jump);
window.addEventListener("click", jump());
let z = 0; // intitial score to be incremented by each succesful second
setInterval(() => {
let ballX = parseInt(window.getComputedStyle(ball).getPropertyValue('bottom'));
let obsY = parseInt(window.getComputedStyle(obs).getPropertyValue('right'));
if (ballX >= 150 && ballX <= 240 && obsY >= 785 && obsY <= 970) {
ball.style.animationPlayState = "paused";
obs.style.animationPlayState = "paused";
ball.style.bottom = `${ballX}px`
window.removeEventListener("keydown", jump);
clearInterval();
} else {
s.innerHTML = z;
z += 1;
}
}, 10);
window.onload = () => {
if (screen.availHeight > screen.availWidth) {
alert("This game is best played in landscape, so rotate your phone if you can :)");
}
}
#import url('https://fonts.googleapis.com/css2?family=Comic+Neue&display=swap');
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
.screen {
margin: 20px;
width: 1000px;
height: 500px;
background: skyblue;
outline: solid 3px;
position: absolute;
overflow: hidden;
}
.score {
position: absolute;
top: 5px;
right: 5px;
width: 200px;
height: 50px;
display: flex;
align-items: flex-end;
font-size: 150%;
font-family: "Comic Neue";
font-weight: bold;
}
.s {
display: flex;
justify-content: center;
align-items: center;
line-height: 50px;
text-shadow: 3px 3px 0px white;
}
#s-title {
width: 40%;
}
#s {
width: 60%;
}
.ball {
position: absolute;
left: 30px;
bottom: 150px;
width: 80px;
height: 80px;
border-radius: 50%;
background: red;
transition: bottom 0.3s ease-in-out;
animation: spin 1s linear infinite;
}
#keyframes spin {
to {
transform: rotate(720deg);
}
}
.obstacle {
width: 100px;
height: 100px;
position: absolute;
right: -150px;
bottom: 150px;
background: red;
animation: attack 1.5s linear infinite;
animation-play-state: running;
}
#keyframes attack {
to {
right: 1150px;
}
}
.grass {
position: absolute;
bottom: 125px;
width: 100%;
height: 25px;
background: rgb(55, 141, 52);
}
.ground {
position: absolute;
bottom: 0;
width: 100%;
height: 125px;
background: rgb(82, 80, 69);
}
<!doctype html>
<html lang='en'>
<head>
<!-- Required meta tags -->
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>Rollin</title>
<link rel='stylesheet' href='rollin.css'>
<link rel='icon' href='assets/logo.ico'>
</head>
<body>
<div class="screen">
<div class="score">
<div id="s-title" class="s">Score:</div>
<div id="s" class="s">000000</div>
</div>
<div class="ball">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 1024 1024" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<defs>
<style type="text/css">
.str0 {stroke:black;stroke-width:0.667;stroke-miterlimit:2.61313}
.fil1 {fill:black}
.fil2 {fill:#1A1A1A}
.fil0 {fill:#AE0000}
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<g>
<path class="fil0" d="M517.231 11.182c277.954,0 503.28,225.327 503.28,503.281 0,277.954 -225.326,503.281 -503.28,503.281 -277.954,0 -503.281,-225.327 -503.281,-503.281 0,-277.954 225.327,-503.281 503.281,-503.281z"/>
<path id="1" class="fil1" d="M517.231 11.182c277.954,0 503.28,225.327 503.28,503.281 0,277.954 -225.326,503.281 -503.28,503.281 -277.954,0 -503.281,-225.327 -503.281,-503.281 0,-277.954 225.327,-503.281 503.281,-503.281zm338.197 165.084c-86.55,-86.551 -206.121,-140.084 -338.197,-140.084 -132.076,0 -251.648,53.533 -338.198,140.084 -86.55,86.55 -140.083,206.121 -140.083,338.197 0,132.076 53.533,251.647 140.083,338.197 86.551,86.551 206.122,140.084 338.198,140.084 132.076,0 251.647,-53.533 338.197,-140.084 86.551,-86.55 140.083,-206.121 140.083,-338.197 0,-132.076 -53.532,-251.647 -140.083,-338.197z"/>
</g>
<g>
<path class="fil2" d="M517.231 246.225c149.688,0 271.035,121.346 271.035,271.035 0,149.688 -121.347,271.035 -271.035,271.035 -149.689,0 -271.035,-121.347 -271.035,-271.035 0,-149.689 121.346,-271.035 271.035,-271.035zm184.58 86.454c-47.237,-47.237 -112.497,-76.454 -184.58,-76.454 -72.084,0 -137.343,29.217 -184.581,76.454 -47.237,47.238 -76.455,112.497 -76.455,184.581 0,72.083 29.218,137.343 76.455,184.58 47.238,47.237 112.497,76.455 184.581,76.455 72.083,0 137.343,-29.218 184.58,-76.455 47.237,-47.237 76.455,-112.497 76.455,-184.58 0,-72.084 -29.218,-137.343 -76.455,-184.581z"/>
</g>
<circle class="fil1 str0" cx="517.231" cy="517.26" r="100.656"/>
<path class="fil1 str0" d="M213.398 645.876c-54.056,-27.029 -41.008,-69.901 -48.444,-92.065 -3.228,-9.623 -41.293,134.779 56.413,170.477 18.411,6.727 36.767,13.855 70.319,8.264 25.978,-4.33 61.512,-22.368 72.238,-53.613 12.934,-37.676 6.05,-56.363 -16.318,-82.46 -8.188,-9.553 -35.416,-37.28 -89.472,-20.504 -33.759,19.875 -36.584,43.161 -44.736,69.901z"/>
<path class="fil1 str0" d="M561.667 188.198c52.09,-14.249 81.039,-0.564 103.952,4.079 9.948,2.016 -96.076,-103.15 -175.843,-36.384 -15.032,12.581 -30.384,24.914 -42.317,56.766 -9.24,24.663 -11.386,64.455 10.311,89.367 26.161,30.039 45.787,33.421 79.571,27.098 12.367,-2.315 49.994,-12.031 62.493,-67.234 -0.333,-39.173 -19.087,-53.263 -38.167,-73.692z"/>
<path class="fil1 str0" d="M786.104 714.481c3.621,60.329 -40.031,70.465 -55.509,87.986 -6.72,7.607 137.369,-31.629 119.431,-134.093 -3.38,-19.308 -6.384,-38.769 -28.003,-65.031 -16.738,-20.332 -50.127,-42.086 -82.549,-35.753 -39.095,7.637 -51.837,22.942 -63.253,55.361 -4.179,11.868 -14.578,49.312 26.979,87.737 34.092,19.299 55.671,10.103 82.904,3.793z"/>
</g>
</svg>
</div>
<div class="obstacle">
<img src="assets/kakashi.png" alt="">
</div>
<div class="grass"></div>
<div class="ground"></div>
</div>
<script src='rollin.js' defer></script>
</body>
</html>
How does this not work? You can try this better here: JSFidlle
const ball = document.querySelector(".ball");
const obs = document.querySelector(".obstacle");
const score = document.querySelector("#s");
let temp = 0; // a temporary variable to stop event listener from running as soon as game starts
function jump() {
let bottom = parseInt(window.getComputedStyle(ball).getPropertyValue('bottom'));
if (temp > 0 && bottom === 150) {
ball.style.bottom = "400px";
setTimeout(() => {
ball.style.bottom = "150px";
}, 300);
}
temp++;
}
window.addEventListener("click", jump);
let z = 0; // intitial score to be incremented by each succesful second
setInterval(() => {
let ballX = parseInt(window.getComputedStyle(ball).getPropertyValue('bottom'));
let obsY = parseInt(window.getComputedStyle(obs).getPropertyValue('right'));
if (ballX >= 150 && ballX <= 240 && obsY >= 785 && obsY <= 970) {
ball.style.animationPlayState = "paused";
obs.style.animationPlayState = "paused";
ball.style.bottom = `${ballX}px`
window.removeEventListener("keydown", jump);
clearInterval();
} else {
s.innerHTML = z;
z += 1;
}
}, 10);
window.onload = () => {
if (screen.availHeight > screen.availWidth) {
alert("This game is best played in landscape, so rotate your phone if you can :)");
}
}
#import url('https://fonts.googleapis.com/css2?family=Comic+Neue&display=swap');
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
.screen {
margin: 20px;
width: 1000px;
height: 500px;
background: skyblue;
outline: solid 3px;
position: absolute;
overflow: hidden;
}
.score {
position: absolute;
top: 5px;
right: 5px;
width: 200px;
height: 50px;
display: flex;
align-items: flex-end;
font-size: 150%;
font-family: "Comic Neue";
font-weight: bold;
}
.s {
display: flex;
justify-content: center;
align-items: center;
line-height: 50px;
text-shadow: 3px 3px 0px white;
}
#s-title {
width: 40%;
}
#s {
width: 60%;
}
.ball {
position: absolute;
left: 30px;
bottom: 150px;
width: 80px;
height: 80px;
border-radius: 50%;
background: red;
transition: bottom 0.3s ease-in-out;
animation: spin 1s linear infinite;
}
#keyframes spin {
to {
transform: rotate(720deg);
}
}
.obstacle {
width: 100px;
height: 100px;
position: absolute;
right: -150px;
bottom: 150px;
background: red;
animation: attack 1.5s linear infinite;
animation-play-state: running;
}
#keyframes attack {
to {
right: 1150px;
}
}
.grass {
position: absolute;
bottom: 125px;
width: 100%;
height: 25px;
background: rgb(55, 141, 52);
}
.ground {
position: absolute;
bottom: 0;
width: 100%;
height: 125px;
background: rgb(82, 80, 69);
}
<!doctype html>
<html lang='en'>
<head>
<!-- Required meta tags -->
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>Rollin</title>
<link rel='stylesheet' href='rollin.css'>
<link rel='icon' href='assets/logo.ico'>
</head>
<body>
<div class="screen">
<div class="score">
<div id="s-title" class="s">Score:</div>
<div id="s" class="s">000000</div>
</div>
<div class="ball">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 1024 1024" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<defs>
<style type="text/css">
.str0 {stroke:black;stroke-width:0.667;stroke-miterlimit:2.61313}
.fil1 {fill:black}
.fil2 {fill:#1A1A1A}
.fil0 {fill:#AE0000}
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<g>
<path class="fil0" d="M517.231 11.182c277.954,0 503.28,225.327 503.28,503.281 0,277.954 -225.326,503.281 -503.28,503.281 -277.954,0 -503.281,-225.327 -503.281,-503.281 0,-277.954 225.327,-503.281 503.281,-503.281z"/>
<path id="1" class="fil1" d="M517.231 11.182c277.954,0 503.28,225.327 503.28,503.281 0,277.954 -225.326,503.281 -503.28,503.281 -277.954,0 -503.281,-225.327 -503.281,-503.281 0,-277.954 225.327,-503.281 503.281,-503.281zm338.197 165.084c-86.55,-86.551 -206.121,-140.084 -338.197,-140.084 -132.076,0 -251.648,53.533 -338.198,140.084 -86.55,86.55 -140.083,206.121 -140.083,338.197 0,132.076 53.533,251.647 140.083,338.197 86.551,86.551 206.122,140.084 338.198,140.084 132.076,0 251.647,-53.533 338.197,-140.084 86.551,-86.55 140.083,-206.121 140.083,-338.197 0,-132.076 -53.532,-251.647 -140.083,-338.197z"/>
</g>
<g>
<path class="fil2" d="M517.231 246.225c149.688,0 271.035,121.346 271.035,271.035 0,149.688 -121.347,271.035 -271.035,271.035 -149.689,0 -271.035,-121.347 -271.035,-271.035 0,-149.689 121.346,-271.035 271.035,-271.035zm184.58 86.454c-47.237,-47.237 -112.497,-76.454 -184.58,-76.454 -72.084,0 -137.343,29.217 -184.581,76.454 -47.237,47.238 -76.455,112.497 -76.455,184.581 0,72.083 29.218,137.343 76.455,184.58 47.238,47.237 112.497,76.455 184.581,76.455 72.083,0 137.343,-29.218 184.58,-76.455 47.237,-47.237 76.455,-112.497 76.455,-184.58 0,-72.084 -29.218,-137.343 -76.455,-184.581z"/>
</g>
<circle class="fil1 str0" cx="517.231" cy="517.26" r="100.656"/>
<path class="fil1 str0" d="M213.398 645.876c-54.056,-27.029 -41.008,-69.901 -48.444,-92.065 -3.228,-9.623 -41.293,134.779 56.413,170.477 18.411,6.727 36.767,13.855 70.319,8.264 25.978,-4.33 61.512,-22.368 72.238,-53.613 12.934,-37.676 6.05,-56.363 -16.318,-82.46 -8.188,-9.553 -35.416,-37.28 -89.472,-20.504 -33.759,19.875 -36.584,43.161 -44.736,69.901z"/>
<path class="fil1 str0" d="M561.667 188.198c52.09,-14.249 81.039,-0.564 103.952,4.079 9.948,2.016 -96.076,-103.15 -175.843,-36.384 -15.032,12.581 -30.384,24.914 -42.317,56.766 -9.24,24.663 -11.386,64.455 10.311,89.367 26.161,30.039 45.787,33.421 79.571,27.098 12.367,-2.315 49.994,-12.031 62.493,-67.234 -0.333,-39.173 -19.087,-53.263 -38.167,-73.692z"/>
<path class="fil1 str0" d="M786.104 714.481c3.621,60.329 -40.031,70.465 -55.509,87.986 -6.72,7.607 137.369,-31.629 119.431,-134.093 -3.38,-19.308 -6.384,-38.769 -28.003,-65.031 -16.738,-20.332 -50.127,-42.086 -82.549,-35.753 -39.095,7.637 -51.837,22.942 -63.253,55.361 -4.179,11.868 -14.578,49.312 26.979,87.737 34.092,19.299 55.671,10.103 82.904,3.793z"/>
</g>
</svg>
</div>
<div class="obstacle">
<img src="assets/kakashi.png" alt="">
</div>
<div class="grass"></div>
<div class="ground"></div>
</div>
<script src='rollin.js' defer></script>
</body>
</html>
You can try to put the -listener- above the -jump- function and remove:
-- window.addEventListener("click", jump()); --

How would I target an element that is visible but beneath another element?

I created a circular graphic that is mainly based on pure HTML and CSS. A little JavaScript and JQuery is added for curving text and interaction that is planned for later on.
The problem I have is, that when I click on the upper right element, it is covered in party by the upper left element. So when I check which element is clicked through an alert, I see that for 50% of the upper right element's area, the number of the upper left element is returned.
How would I target precisely the elements that I click on? This is needed for linking to different pages of our web project later on.
I created a JSFiddle to show the problem: https://jsfiddle.net/niklasbuschner/gj67md4u/4/
The code looks like this:
$(document).ready(function() {
function textRotation() {
new CircleType(document.getElementById('demo1')).radius(185);
new CircleType(document.getElementById('demo2')).radius(185);
new CircleType(document.getElementById('demo3')).radius(185);
}
textRotation();
$('#demo1').children('div').addClass('pie__segment__path-text__rotation1');
$('#demo3').children('div').addClass('pie__segment__path-text__rotation3');
$('.pie__segment').on('click', function() {
var link_target = $(this).data('href');
alert('KLICK' + link_target);
});
})
html {
font-family: Arial;
font-size: 14px;
}
.pie {
border-radius: 100%;
height: calc(var(--size, 400) * 1px);
overflow: hidden;
position: absolute;
top: 0;
left: 0;
width: calc(var(--size, 400) * 1px);
}
.pie__segment {
--a: calc(var(--over50, 0) * -100%);
--b: calc((1 + var(--over50, 0)) * 100%);
--degrees: calc((var(--offset, 0) / 100) * 360);
-webkit-clip-path: polygon(var(--a) var(--a), var(--b) var(--a), var(--b) var(--b), var(--a) var(--b));
clip-path: polygon(var(--a) var(--a), var(--b) var(--a), var(--b) var(--b), var(--a) var(--b));
height: 100%;
position: absolute;
-webkit-transform: translate(0, -50%) rotate(90deg) rotate(calc(var(--degrees) * 1deg));
transform: translate(0, -50%) rotate(90deg) rotate(calc(var(--degrees) * 1deg));
-webkit-transform-origin: 50% 100%;
transform-origin: 50% 100%;
width: 100%;
z-index: calc(1 + var(--over50));
cursor: pointer;
}
.pie__segment:after,
.pie__segment:before {
background: var(--bg, #e74c3c);
content: '';
height: 100%;
position: absolute;
width: 100%;
}
.pie__segment:before {
--degrees: calc((var(--value, 45) / 100) * 360);
-webkit-transform: translate(0, 100%) rotate(calc(var(--degrees) * 1deg));
transform: translate(0, 100%) rotate(calc(var(--degrees) * 1deg));
-webkit-transform-origin: 50% 0%;
transform-origin: 50% 0%;
}
.pie__segment:after {
opacity: var(--over50, 0);
}
.pie__segment .path-text {
position: absolute;
left: -82px;
bottom: 122px;
color: #fff;
font-weight: 700;
z-index: 2;
width: 100%;
text-align: center;
}
.pie__segment .path-text span div {
height: 2.5em !important;
}
.pie__segment .path-text span div span:last-child {
color: rgba(255, 255, 255, 0.75);
}
.pie__segment .path-text.demo1 {
transform: rotate(-90deg);
}
.pie__segment__path-text__rotation1 {
transform: rotate(60deg);
}
.pie__segment .path-text.demo2 {
transform: rotate(-30deg);
}
.pie__segment .path-text.demo3 {
transform: rotate(30deg);
}
.pie__segment__path-text__rotation3 {
transform: rotate(-60deg);
}
.pie-body {
border-radius: 100%;
height: 300px;
width: 300px;
position: absolute;
top: 50px;
left: 50px;
background-color: #73c6be;
text-align: center;
overflow: hidden;
}
.pie-body p {
line-height: 260px;
font-size: 1.75em;
font-weight: 700;
color: #0896A5;
}
<div class="pie-container" style="position: relative; top: 100px; left: 100px;">
<div class="pie">
<div class="pie__segment" data-href="1" style="--offset: 0; --value: 33.33333; --bg: #089baa">
<div class="path-text demo1">
<span id="demo1">BEISPIEL EINTRAG +</span>
</div>
</div>
<div class="pie__segment" data-href="2" style="--offset: 33.33333; --value: 33.33333; --bg: #066f7a;">
<div class="path-text demo2">
<span id="demo2">NÄCHSTER EINTRAG +</span>
</div>
</div>
<div class="pie__segment" data-href="3" style="--offset: 66.66666; --value: 33.33333; --bg: #044249;">
<div class="path-text demo3">
<span id="demo3">WEITERER EINTRAG +</span>
</div>
</div>
</div>
<div class="pie-body">
<p>Kernaussage</p>
</div>
</div>
Here is an example of how you can use svg
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
function describeArc(x, y, radius, startAngle, endAngle) {
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
var sweepFlag = endAngle > startAngle ? 0 : 1; //sic
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y
].join(" ");
return d;
}
window.onload = function() {
let arc1 = document.getElementById("arc1")
let arc2 = document.getElementById("arc2")
let arc3 = document.getElementById("arc3")
arc1.setAttribute("d", describeArc(200, 200, 100, 120, 0));
arc2.setAttribute("d", describeArc(200, 200, 100, 240, 120));
arc3.setAttribute("d", describeArc(200, 200, 100, 360, 240));
let text1 = document.getElementById("text1")
let text2 = document.getElementById("text2")
let text3 = document.getElementById("text3")
let textPath1 = document.getElementById("textPath1")
textPath1.setAttribute("d", describeArc(200, 200, 95, 120, 0));
let textPath2 = document.getElementById("textPath2")
textPath2.setAttribute("d", describeArc(200, 200, 95, 240, 120));
let textPath3 = document.getElementById("textPath3")
textPath3.setAttribute("d", describeArc(200, 200, 95, 360, 240));
[arc1, arc2, arc3, text1, text2, text3].forEach(el => {
el.addEventListener("click", e => {
console.log(e.target.getAttribute("link"))
})
})
};
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
background-color: rgb(36, 41, 46);
display: flex;
align-items: center;
justify-content: center;
}
svg {
/*outline: 2px solid lightgreen;*/
height: 400px;
width: 400px;
transform: scale(1);
}
path,
text {
cursor: pointer;
}
text {
font-family: arial;
font-size: 14px;
fill: #fff;
}
<svg viewBox="0 0 400 400">
<circle shape-rendering="geometricPrecision" cx="200" cy="200" r="100" fill="#73c6be" stroke="none" />
<path shape-rendering="geometricPrecision" id="arc1" fill="none" stroke="#089baa" stroke-width="30" link="Link1.html" />
<path shape-rendering="geometricPrecision" id="arc2" fill="none" stroke="#066f7a" stroke-width="30" link="Link2.html" />
<path shape-rendering="geometricPrecision" id="arc3" fill="none" stroke="#044249" stroke-width="30" link="Link3.html" />
<path id="textPath1" fill="none" stroke="none" />
<path id="textPath2" fill="none" stroke="none" />
<path id="textPath3" fill="none" stroke="none" />
<text id="text1">
<textPath
href="#textPath1"
link="Link1.html"
startOffset="15%"
>BEISPIEL EINTRAG+</textPath>
</text>
<text id="text2">
<textPath
href="#textPath2"
link="Link2.html"
startOffset="10%"
>NACHSTER EINTRAG+</textPath>
</text>
<text id="text3">
<textPath
href="#textPath3"
link="Link3.html"
startOffset="10%"
>WEITERER EINTRAG+</textPath>
</text>
</svg>

Make an indicator move around a circle

I was trying to come up with some JS (pure JS) code making the indicator move around the circle while the pin is being moved (as if it was a speedometer), but I failed. I tried to use offsets, count the offsetTop etc., but it doesn't work. Can anyone help me out here, please?
If there is some other way to do this without using some extra libraries (for example, just using the css options), let me know - I'll be really grateful as it's really important for me to understand the concept here!
'use strict';
let firstIndicator = document.querySelector('.indicator');
let pinLevel = document.querySelector('.effect-level__pin');
let effectLevelLine = document.querySelector('.effect-level__line');
let effectLevelDepth = document.querySelector('.effect-level__depth');
let changeOverlay = function (percentage) {
pinLevel.style.left = percentage + '%';
effectLevelDepth.style.width = percentage + '%';
};
pinLevel.addEventListener('mousedown', function (evt) {
evt.preventDefault();
let startX = evt.clientX;
let startLevelDepthWidth = effectLevelDepth.offsetWidth;
let clickedPercentageLevel = startLevelDepthWidth / effectLevelLine.offsetWidth * 100;
changeOverlay(clickedPercentageLevel);
let onMouseMove = function (moveEvt) {
moveEvt.preventDefault();
let shift = moveEvt.clientX - startX;
let levelWidth = startLevelDepthWidth + shift;
let movedPercentageLevel = levelWidth / effectLevelLine.offsetWidth * 100;
movedPercentageLevel = Math.max(0, movedPercentageLevel);
movedPercentageLevel = Math.min(100, movedPercentageLevel);
changeOverlay(movedPercentageLevel);
firstIndicator.style.top = (firstIndicator.offsetHeight * 3) - (movedPercentageLevel / 100) + 'px';
firstIndicator.style.transform = 'rotate('+ (52 + movedPercentageLevel * 2.4) + 'deg' + ')';
};
let onMouseUp = function (upEvt) {
upEvt.preventDefault();
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
.circle {
margin: 0 auto;
margin-top: 50px;
width: 150px;
height: 150px;
border: 1px solid black;
border-radius: 50%
}
.indicator {
position: relative;
}
.indicator svg {
position: absolute;
top: -100px;
transform: rotate(82deg);
left: 108px;
}
.effect-level {
position: absolute;
bottom: -30px;
left: 50%;
width: 495px;
height: 33px;
font-size: 12px;
line-height: 42px;
text-align: center;
color: black;
white-space: nowrap;
background-color: #ffffff;
border: none;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
.effect-level__value {
display: none;
}
.effect-level__line {
position: absolute;
top: 50%;
right: 20px;
left: 20px;
height: 5px;
font-size: 0;
background-color: rgba(0, 0, 0, 0.2);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.effect-level__pin {
position: absolute;
top: 50%;
left: 0%;
z-index: 1;
width: 18px;
height: 18px;
margin: -9px 0 0;
background-color: #fff;
border-radius: 50%;
border: 1px solid #323232;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
cursor: move;
}
.effect-level__depth {
position: absolute;
width: 0%;
height: 100%;
background-color: #323232;
}
<div class="circle"></div>
<div class="indicator">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="337.0744522647706 304.4241607573019 28.925547735229372 104" width="24.93" height="100"><defs><path d="" id="c6VRx4235S"></path><path d="M348.07 305.42L338.07 405.42" id="f84HmfmJk"></path><path d="M340.01 305.42L338.07 403.88" id="azVXtGrDR"></path></defs><g><g><g><use xlink:href="#c6VRx4235S" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#f84HmfmJk" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#azVXtGrDR" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g></g>
</svg>
</div>
<fieldset class="effect-level">
<input class="effect-level__value" type="number" name="effect-level" value="0">
<div class="effect-level__line">
<div class="effect-level__pin" tabindex="0">Кнопка изменения эффекта </div>
<div class="effect-level__depth">Глубина эффекта</div>
</div>
</fieldset>
You can define the size of your .indicator such that, when rotated using transform: rotate(angle), it rotates about the center of your defined circle.
It's always better to define your moving elements & their references as position: absolute and later have container divs to place it where ever you want.
.circle {
position: absolute;
top: 100px;
left: 100px;
width: 150px;
height: 150px;
border: 1px solid black;
border-radius: 50%;
}
.indicator {
position: absolute;
top: 6px;
left: 155px;
height: 340px;
width: 44px;
transform: rotate(0deg);
}
.indicator svg {
transform: rotate(177deg);
}
This makes our lives very easy, we just have to rotate .indicator based on your movedPercentageLevel.
Check out the following code snippet.
'use strict';
let firstIndicator = document.querySelector('.indicator');
let pinLevel = document.querySelector('.effect-level__pin');
let effectLevelLine = document.querySelector('.effect-level__line');
let effectLevelDepth = document.querySelector('.effect-level__depth');
let changeOverlay = function(percentage) {
pinLevel.style.left = percentage + '%';
effectLevelDepth.style.width = percentage + '%';
};
pinLevel.addEventListener('mousedown', function(evt) {
evt.preventDefault();
let startX = evt.clientX;
let startLevelDepthWidth = effectLevelDepth.offsetWidth;
let clickedPercentageLevel = startLevelDepthWidth / effectLevelLine.offsetWidth * 100;
changeOverlay(clickedPercentageLevel);
let onMouseMove = function(moveEvt) {
moveEvt.preventDefault();
let shift = moveEvt.clientX - startX;
let levelWidth = startLevelDepthWidth + shift;
let movedPercentageLevel = levelWidth / effectLevelLine.offsetWidth * 100;
movedPercentageLevel = Math.max(0, movedPercentageLevel);
movedPercentageLevel = Math.min(100, movedPercentageLevel);
changeOverlay(movedPercentageLevel);
firstIndicator.style.transform = 'rotate(' + movedPercentageLevel * 3.6 + 'deg' + ')';
};
let onMouseUp = function(upEvt) {
upEvt.preventDefault();
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
.circle {
position: absolute;
top: 100px;
left: 100px;
width: 150px;
height: 150px;
border: 1px solid black;
border-radius: 50%;
}
.indicator {
position: absolute;
top: 6px;
left: 155px;
height: 340px;
width: 44px;
transform: rotate(0deg);
}
.indicator svg {
transform: rotate(177deg);
}
.effect-level {
position: absolute;
bottom: -30px;
left: 50%;
width: 495px;
height: 33px;
font-size: 12px;
line-height: 42px;
text-align: center;
color: black;
white-space: nowrap;
background-color: #ffffff;
border: none;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
.effect-level__value {
display: none;
}
.effect-level__line {
position: absolute;
top: 50%;
right: 20px;
left: 20px;
height: 5px;
font-size: 0;
background-color: rgba(0, 0, 0, 0.2);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.effect-level__pin {
position: absolute;
top: 50%;
left: 0%;
z-index: 1;
width: 18px;
height: 18px;
margin: -9px 0 0;
background-color: #fff;
border-radius: 50%;
border: 1px solid #323232;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
cursor: move;
}
.effect-level__depth {
position: absolute;
width: 0%;
height: 100%;
background-color: #323232;
}
<div class="circle"></div>
<div class="indicator">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="337.0744522647706 304.4241607573019 28.925547735229372 104" width="24.93" height="100"><defs><path d="" id="c6VRx4235S"></path><path d="M348.07 305.42L338.07 405.42" id="f84HmfmJk"></path><path d="M340.01 305.42L338.07 403.88" id="azVXtGrDR"></path></defs><g><g><g><use xlink:href="#c6VRx4235S" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#f84HmfmJk" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g><g><g><use xlink:href="#azVXtGrDR" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="1"></use></g></g></g>
</svg>
</div>
<fieldset class="effect-level">
<input class="effect-level__value" type="number" name="effect-level" value="0">
<div class="effect-level__line">
<div class="effect-level__pin" tabindex="0">Кнопка изменения эффекта </div>
<div class="effect-level__depth">Глубина эффекта</div>
</div>
</fieldset>
Just for fun, here's an even more javascript-y flavour that doesn't need any elements rotating. Just a circle and a line, redrawn to new coordinates after rotation about a point.
Here it just updates on mouse movement but desired angle just needs to be fed into the function as an offset.
'use strict';
// get the canvas element
const canvas = document.getElementById('canvas');
canvas.width = 170;
canvas.height = 170;
canvas.style.background = 'red';
canvas.style.border = '1px solid black';
// somewhere to store the position and state of the needle
const needle = {
start_angle: 0,
current_angle: 0,
point_x: canvas.width,
point_y: canvas.height/2 // the 3oclock position is just straight to the right! from the centre of our circle,
}
// handy function to rotate a point about a point. first google result
const rotatePoint = (x, y, centerx, centery, degrees)=>{ // https://stackoverflow.com/a/45649110/2244284
let newx = (x - centerx) * Math.cos(degrees * Math.PI / 180) - (y - centery) * Math.sin(degrees * Math.PI / 180) + centerx;
let newy = (x - centerx) * Math.sin(degrees * Math.PI / 180) + (y - centery) * Math.cos(degrees * Math.PI / 180) + centery;
return [newx, newy];
}
// handy function to convert degrees to radians
const d2r = (degree)=>{
return degree * (Math.PI / 180);
}
// handy function to draw a circle
const drawCircle = ()=>{
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height/2, canvas.width/2, 0, d2r(360)); // just use the whole canvas
ctx.stroke();
}
// draw our needle
const drawNeedle = (offset)=>{
let xy = rotatePoint(needle.point_x, needle.point_y, canvas.width/2, canvas.height/2, offset); // point_x/y is the far end of the needle, the other side is just the centre of the circle/canvas
// draw a line from centre to the new point of the needle
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(canvas.width/2, canvas.height/2);
ctx.lineTo(xy[0], xy[1]);
ctx.stroke();
}
// --- init stuff
drawCircle(); // draw first circle
drawNeedle(needle.start_angle); // draw first needle
// add an event for every mouse move detected over the canvas
canvas.addEventListener('mousemove', (e)=>{
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); // clear clear the canvas
drawCircle(); // redraw the circle
let offset = needle.start_angle + needle.current_angle++ % 360; // increase angle by 1 for every mouseover event, reset to 0 if a full circle is reached
drawNeedle(offset) // draw needle
})
<html>
<body>
<canvas id="canvas"></canvas>
</body>
</html>

Time condition not executing byself, need to reload whole page

I got two conditions in my code. If this condition becomes true (based on currentTime) I would like to change opacity on div element from '0' to '1'.
Second condition works same but it does opposite.
My problem:
Lets say that it supposed to work as Day / Night phase.
So when I would like to set opacity for day '0' and night '1' I need to reload whole page. Why is that not reloading by itself even though I have there setInterval?
Whole code is here : https://jsbin.com/huvoluk/1/edit?html,css,js,output
Just edit those time condition so you can see what I am trying to describe.
window.onload = function() {
// TODO:: Do your initialization job
var cs = new Date();
var hour = cs.getHours();
var minu = cs.getMinutes();
var sec = cs.getSeconds();
var tst = hour +":"+ minu +":"+ sec;
function showTime(){
var date = new Date();
var h = date.getHours(); // 0 - 23
var m = date.getMinutes(); // 0 - 59
var s = date.getSeconds(); // 0 - 59
if(h === 0){
h = 24;
}
h = (h < 10) ? "0" + h : h;
m = (m < 10) ? "0" + m : m;
s = (s < 10) ? "0" + s : s;
var time = h + ":" + m + ":" + s;
document.getElementById("MyClockDisplay").innerText = time;
document.getElementById("MyClockDisplay").textContent = time;
setTimeout(showTime, 100);
}
showTime();
function showdate(){
var d = new Date();
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
document.getElementById("date").innerHTML = days[d.getDay()];
}
showdate();
// day1 tonight transition
function day1toNight3(){
if('10:00' <= tst&&tst < '20:35:20')
{
document.getElementById("day1").style.opacity = "1";
document.getElementById("night3").style.opacity = "0";
}
setInterval(day1toNight3, 10000);
}
day1toNight3();
function night3toDay1(){
if('20:35:23' <= tst&&tst < '22:58:00')
{
document.getElementById("day1").style.opacity = "0";
document.getElementById("night3").style.opacity = "1";
}
setInterval(night3toDay1, 10000);
}
night3toDay1();
};
html,
body {
width: 100%;
height: 100%;
margin: 0 auto;
padding: 0;
background-color: #000000;
color: #ffffff;
}
.page {
width: 100%;
height: 100%;
display: table;
}
.contents {
display: table-cell;
vertical-align: middle;
text-align: center;
-webkit-tap-highlight-color: transparent;
}
.clock {
position: absolute;
top: 45%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
color: #FFFFFF;
font-size: 30px;
/* font-family: Orbitron; */
letter-spacing: 7px;
}
img {
position: fixed;
top: 0%;
left: 0%;
height: 360px;
width: 360px;
transition: all 5s ease;
}
#day1 {
position: absolute;
width: 360px;
height: 360px;
background-repeat: no-repeat;
}
#night3 {
position: absolute;
width: 360px;
height: 360px;
background-repeat: no-repeat;
}
#components-main {
position: absolute;
width: 100%;
height: 100%;
}
.showsDate {
position: absolute;
top: 55%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
color: #FFFFFF;
font-size: 22px;
/* font-family: Orbitron; */
letter-spacing: 5px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="test" />
<title>Web Basic Application</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script src="js/main.js"></script>
</head>
<body>
<div id="container">
<img id="day1" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRXHbfK8xm3PQo4fR9O-Q5_EvGnH3Tsixdm1iUay24SH2lYUIhQWw" style="opacity: 0"/>
<img id="night3" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqK7DnhIIS444uMgbgWbPGeOfLmQkZFfvRJU3XkX_z7UBFWzkswQ" style="opacity: 0"/>
<!-- <div id="backgroundNight" style="opacity: 0;"></div>-->
<div id="MyClockDisplay" class="clock" onload="showTime()"></div>
<div id="date" class="showsDate"></div>
<div id="components-main">
<!--<div id="hand-main-hour"></div>-->
<div id="hand-main-minute"></div>
<div id="hand-main-second"></div>
</div>
</div>
<script src="js/main.js"></script>
</body>
</html>
00

Inline SVG Element not working on Div

I have this snippet. My end game is to use a larger hexagon as a container for the generated hexagons. I am using an inline svg element but it does not seem that the mask is applying to the div with the inner class like I hoped. Am I implementing it wrong or missing something?
If I had to guess is it because my coordinates for the hexagon are larger than 1 which would break boundingBox?
$(document).ready(function() {
var wrapper = document.getElementsByClassName('inner')[0];
for(var i = 0; i <= 250; i++) {
var hex = document.createElement('div');
var colors = ['red-hex', 'blue-hex','yellow-hex'];
var hexColor = Math.floor(Math.random() * colors.length);
hex.className = 'hexagon ';
hex.className += colors[hexColor];
hex.innerHTML = '<i class="mdi mdi-hexagon" aria-hidden="true"></i>';
var size = (Math.random()* (200-100)) + 100;
hex.style.fontSize = size + 'px';
var posx = (Math.random() * wrapper.offsetWidth - size).toFixed();
var posy = (Math.random() * wrapper.offsetHeight - size).toFixed();
hex.style.top = posy+'px';
hex.style.left = posx+'px';
wrapper.appendChild(hex);
}
});
.hexagon_wrapper {
position: relative;
width: 1000px;
height: 1000px;
margin: 0 auto;
}
.svg-defs {
position: absolute;
width: 0;
height: 0;
}
.inner {
position: relative;
width: 100%;
height: 100%;
-webkit-clip-path: url("#clipping");
clip-path: url("#clipping");
}
.hexagon {
position: absolute;
/* mix-blend-mode: color-dodge; looks wicked */
mix-blend-mode: saturation;
padding: 10px;
}
.red-hex {
color: #fe412b;
-webkit-animation:fade-in 6s infinite;
}
.blue-hex {
color: #39b1e3;
-webkit-animation:fade-in 5s infinite;
}
.yellow-hex {
color: #fcfe41;
-webkit-animation:fade-in 4s infinite;
}
#-webkit-keyframes fade-in{
0%, 100% {
opacity: 0.9;
}
50% {
opacity: 0.5;
}
}
<link href="https://cdn.materialdesignicons.com/1.8.36/css/materialdesignicons.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hexagon_wrapper">
<div class="inner">
</div>
<svg class="svg-defs">
<defs>
<clipPath id="clipping" clipPathUnits ="objectBoundingBox">
<polygon points="50 1 95 25 95 75 50 99 5 75 5 25" />
</clipPath>
</defs>
</svg>
</div>
I have rewritten your polygon to fit within a viewBox of 1x1, then it works. I haven't figured out what the exact reason is for this behavior.
$(document).ready(function() {
var wrapper = document.getElementsByClassName('inner')[0];
for(var i = 0; i <= 250; i++) {
var hex = document.createElement('div');
var colors = ['red-hex', 'blue-hex','yellow-hex'];
var hexColor = Math.floor(Math.random() * colors.length);
hex.className = 'hexagon ';
hex.className += colors[hexColor];
hex.innerHTML = '<i class="mdi mdi-hexagon" aria-hidden="true"></i>';
var size = (Math.random()* (200-100)) + 100;
hex.style.fontSize = size + 'px';
var posx = (Math.random() * wrapper.offsetWidth - size).toFixed();
var posy = (Math.random() * wrapper.offsetHeight - size).toFixed();
hex.style.top = posy+'px';
hex.style.left = posx+'px';
wrapper.appendChild(hex);
}
});
.hexagon_wrapper {
position: relative;
width: 1000px;
height: 1000px;
margin: 0 auto;
}
.svg-defs {
position: absolute;
width: 0;
height: 0;
}
.inner {
position: relative;
width: 100%;
height: 100%;
-webkit-clip-path: url("#clipping");
clip-path: url("#clipping");
}
.hexagon {
position: absolute;
/* mix-blend-mode: color-dodge; looks wicked */
mix-blend-mode: saturation;
padding: 10px;
}
.red-hex {
color: #fe412b;
-webkit-animation:fade-in 6s infinite;
}
.blue-hex {
color: #39b1e3;
-webkit-animation:fade-in 5s infinite;
}
.yellow-hex {
color: #fcfe41;
-webkit-animation:fade-in 4s infinite;
}
#-webkit-keyframes fade-in{
0%, 100% {
opacity: 0.9;
}
50% {
opacity: 0.5;
}
}
<link href="https://cdn.materialdesignicons.com/1.8.36/css/materialdesignicons.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hexagon_wrapper">
<div class="inner">
</div>
<svg class="svg-defs">
<defs>
<clipPath id="clipping" clipPathUnits ="objectBoundingBox">
<polygon points=".5 .01, 0.95 .25, .95 .75, .50 .99, .05 .75, .05 .25" />
</clipPath>
</defs>
</svg>
</div>

Categories

Resources