Related
let btn = document.querySelector('.btn');
let modal = document.querySelector('.modal');
let wrap = document.querySelector('.wrap');
let photo = document.querySelector('.photo');
let svg = document.querySelector('svg');
let data = [{
title: "dog",
age: 10,
rank: [{
rankStatus: 'behind'
},
{
rankStatus: 'generally',
rankNum: '20'
},
{
rankStatus: 'excellent'
}
]
}]
let rankStatusArr = data[0].rank.map(item => item.rankStatus);
let rankNum = data[0].rank.find(item => item.rankNum).rankNum;
btn.addEventListener('click', function(e) {
svg.style.display = "block"
axios.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
// 设置处理程序以在加载图像后显示图像
photo.addEventListener('load', () => {
svg.style.display = "none"
modal.style.display = "flex";
});
// 添加“加载”处理程序后设置图像源
photo.src = response.data.message;
})
.catch((error) => console.log(error));
// 排名狀態在 popup 打開後再載入動畫
let progress = rankNum;
let dot = document.getElementById("dot");
var dotPosition = (progress / 30) * 100;
dot.style.left = dotPosition + "%";
let txt = document.querySelectorAll('.txt');
for (let i = 0; i < txt.length; i++) {
txt[i].innerHTML = rankStatusArr[i];
}
})
wrap.addEventListener('click', function(e) {
e.stopPropagation();
})
modal.addEventListener('click', function() {
modal.style.display = "none"
})
.modal {
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
justify-content: center;
align-items: center;
}
.wrap {
width: 300px;
height: 300px;
padding: 20px;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
flex-direction: column;
}
.wrap .photo {
width: 100%;
height: 200px;
object-fit: cover;
margin-bottom: 20px;
}
.wrap #progress-bar-container {
width: 100%;
height: 5px;
background-color: #fff;
position: relative;
display: flex;
flex-wrap: nowrap;
}
.wrap #progress-bar-container .progress-bar {
width: 33.33%;
height: 5px;
background-color: #ccc;
margin-right: 8px;
border-radius: 20px;
}
.wrap #progress-bar-container .progress-bar .txt {
text-align: center;
color: #ccc;
margin-top: 20px;
}
#progress-bar-1 {
background-color: #ddd;
}
#progress-bar-2 {
background-color: #ddd;
}
#progress-bar-3 {
background-color: #ddd;
margin-right: 0;
}
#dot {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #333;
position: absolute;
top: -3px;
left: 0;
transition: left 0.2s ease-out;
}
svg {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
svg .load {
stroke-dasharray: 0 500;
animation: rot 1s linear infinite;
}
#keyframes rot {
100% {
stroke-dasharray: 500 500;
}
}
.green {
color: yellowgreen;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.2/axios.min.js"></script>
<button class='btn'>open</button>
<div class="modal">
<div class="wrap">
<img class="photo" src="" alt="photo">
<div id="progress-bar-container">
<div class="progress-bar" id="progress-bar-1">
<p class="txt">1</p>
</div>
<div class="progress-bar" id="progress-bar-2">
<p class="txt">2</p>
</div>
<div class="progress-bar" id="progress-bar-3">
<p class="txt">3</p>
</div>
<div id="dot"></div>
</div>
</div>
</div>
<!-- load -->
<svg width="240px" height="240px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="gainsboro" fill="none"></circle>
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="darkturquoise" fill="none" class="load"></circle>
</svg>
I encountered a little difficulty in the following requirements. The first difficulty is that I hope that the popup will not be opened until the picture is fully loaded! But I hope that when the popup is opened, the dot can add animation and run to the specified progress position, but it seems that the animation I want to appear has already run before it is opened, and the user will not see the moving animation effect. The second problem is that I want to add a green color to the rankStatus font on the screen if the rankNum is included in the rankStatus object, but I am a novice in programming and don't know which section to add to achieve this. Hope to get your help, thank you.
To solve the first difficulty, you can add an event listener to the photo element which will be triggered when the image is loaded. Inside this event listener, you can set the display of the modal to 'flex' and the display of the svg element to 'none'.
To solve the second difficulty, you can use an if statement inside your rankStatusArr loop. This statement should check if the rankNum is included in the rankStatus object and if so, add a class to the txt element which adds the green color style.
let txt = document.querySelectorAll('.txt');
for (let i = 0; i < txt.length; i++) {
txt[i].innerHTML = rankStatusArr[i];
if (rankNum === rankStatusArr[i]) {
txt[i].classList.add('green');
}
}
I'm trying to make an infinite logo carousel for a website. However, I haven't much experience with Javascript. At first, I researched lots of sources and understood the basic structure. Then I watched and appied this 2 part video(video Repository here).
Here is the code:
const slide = document.querySelector('.slide');
const root = document.querySelector(':root');
let slideIndex = 1;
let isMoving = false;
function processImages(item) {
return `<img src="${item.url}" alt="${item.alt}">`;
}
function moveSlides() {
slide.style.transform = `translateX(-${slideIndex * 100}%)`;
const slidesArray = [...slide.querySelectorAll('img')];
root.style.setProperty('--slide-progress', `${(100 / (slidesArray.length - 3)) * (slideIndex - 1)}%`);
}
// move when clicked
function moveHandler(direction) {
isMoving = true;
slide.style.transition = `transform 450ms ease-in-out`;
direction !== 'right' ? (slideIndex -= 1) : (slideIndex += 1);
moveSlides();
}
// fetch images
async function fetchImages() {
await fetch('images.json')
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not okay');
}
return response.json();
})
.then((data) => {
// cloned first and last image
data.push(data[0]);
data.unshift(data[data.length - 2]);
// show slider
slide.innerHTML = data.map(processImages).join('');
moveSlides();
})
.catch((error) => {
console.error('There has been a problem with your fetch operation:', error);
});
}
fetchImages()
// keyboard arrow handler
window.addEventListener('keyup', e => {
if (isMoving) {
return;
}
switch (e.key) {
case 'ArrowLeft':
moveHandler()
break;
case 'ArrowRight':
moveHandler('right')
break;
default:
break;
}
})
// click right btn
document.querySelector('.slider__btn--right').addEventListener('click', () => {
if (isMoving) {
return;
}
moveHandler('right');
})
// click left btn
document.querySelector('.slider__btn--left').addEventListener('click', () => {
if (isMoving) {
return;
}
moveHandler();
})
slide.addEventListener('transitionend', () => {
isMoving = false;
const slidesArray = [...slide.querySelectorAll('img')];
root.style.setProperty('--slide-progress--transition', `${slideIndex === slidesArray.length - 1 ? 'none' : 'all 400ms cubic-bezier(0.82, 0.02, 0.39, 1.01)'}`);
if (slideIndex === 0) {
slide.style.transition = 'none';
slideIndex = slidesArray.length - 2;
moveSlides()
}
if (slideIndex === slidesArray.length - 1) {
slide.style.transition = 'none';
slideIndex = 1;
moveSlides()
}
})
*,
*::after,
*::before {
border: 0;
margin: 0;
padding: 0;
}
:root {
--slide-progress: 35%;
--slide-progress--transition: all 200ms cubic-bezier(0.82, 0.02, 0.39, 1.01);
}
.container {
display: flex; /* Changed display grid to flex*/
place-items: center;
align-content: center;
min-height: 100vh;
padding: 2rem 0;
}
.slider {
position: relative;
display: flex; /* Changed display grid to flex*/
place-items: center;
max-width: 800px;
overflow: hidden;
box-shadow:
20px 20px 50px hsla(210, 50%, 40%, .4),
-20px -20px 50px hsla(210, 50%, 80%, .2);
;
}
.slide {
height: 100px;
max-height: 100px;
display: flex;
}
.slide img {
width: 100%;
margin-top: 20px;
height: 60px;
flex: 6 1 25%; /* Changed flex value 1 0 100% -> 6 0 25%*/
object-fit: contain;
}
.slider__progress {
position: absolute;
width: 100%;
height: 6px;
background: linear-gradient(90deg, hsla(210, 50%, 90%, .2), hsla(210, 50%, 70%, .1));
bottom: 0;
z-index: 4;
}
.slider__progress::after {
content: '';
position: absolute;
background: linear-gradient(90deg, hsla(210, 50%, 90%, .7), hsla(210, 50%, 70%, .6));
width: var(--slide-progress);
height: 6px;
left: 0;
transition: var(--slide-progress--transition);
}
.slider__btn-container {
position: absolute;
width: 100%;
}
.slider__btn {
border-radius: 50%;
position: absolute;
z-index: 2;
padding: .2rem;
top: 50%;
display: grid;
place-items: center;
cursor: pointer;
background: hsla(210, 50%, 30%, .15);
color: hsla(210, 50%, 95%, .9);
}
.slider__btn svg {
pointer-events: none;
}
.slider__btn--left {
left: 0;
transform: translate(50%, -50%);
}
.slider__btn--left:is(:hover, :focus) {
animation: 850ms infinite moveLeft cubic-bezier(0.25, -0.50, 0.17, 1.2);
}
#keyframes moveLeft {
10% {
left: -3px;
}
}
.slider__btn--right {
right: 0;
transform: translate(-50%, -50%);
}
.slider__btn--right:is(:hover, :focus) {
animation: 850ms infinite moveRight cubic-bezier(0.25, -0.50, 0.17, 1.2);
}
#keyframes moveRight {
10% {
right: -3px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="slider">
<div class="slider__progress"></div>
<div class="slider__btn-container">
<button class="slider__btn slider__btn--left" aria-label="Move to previous slide">
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-arrow-left">
<line x1="19" y1="12" x2="5" y2="12"></line>
<polyline points="12 19 5 12 12 5"></polyline>
</svg>
</button>
<button class="slider__btn slider__btn--right" aria-label="Move to next slide">
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-arrow-right">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>
</button>
</div>
<div class="slide">
<img src="./images/image-1.jpg" alt="alt">
<img src="./images/image-1.jpg" alt="alt">
<img src="./images/image-1.jpg" alt="alt">
<img src="./images/image-1.jpg" alt="alt">
<img src="./images/image-1.jpg" alt="alt">
</div>
</div>
</div>
when I changed
.slide img {
width: 100%;
margin-top: 20px;
height: 60px;
flex: 6 0 25%; /* Changed flex value 1 0 100% -> 6 0 25%*/
object-fit: contain;
}
this part at CSS code it looks like what I want to see but it's not even close to work properly. What should I do for make this change correctly. ALSO, THANKS FOR ANY HELP <3
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()); --
I have an animated SVG using lazy line painter that I would like to use as a pre-loader. How can I review the page content (with a transition or a simple fade-in) after the line animation is completed?
So the concept is this: on landing LOAD SVG animation when COMPLETE transition into page content.
<!-- Include lazylinepainter -->
<script src="https://cdn.jsdelivr.net/npm/ lazy-line-painter#1.9.4/lib/lazy-line-painter-1.9.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/d3js/5.15.0/d3.min.js"></script>
<script type="text/javascript">
(function(){
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
let el = document.querySelector('#markin2');
let myAnimation = new LazyLinePainter(el, {"ease":"easeLinear","strokeWidth":2.2,"strokeOpacity":1,"strokeColor":"#fff"});
myAnimation.paint();
}
}
})();
</script>
<svg version="1.1" id="markin2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="314.094px" height="314.765px" viewBox="0 0 314.094 314.765" enable-background="new 0 0 314.094 314.765" xml:space="preserve" data-llp-composed="true" class="lazy-line-painter">
<circle fill="none" stroke-miterlimit="10" cx="157.828" cy="157.404" r="150.813" data-llp-id="markin2-0" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
<path id="#markin2" class=".markin2" fill="none" values="#000" stroke-miterlimit="10" d="M18.482,132.273
c1.019-4.147,1.774-8.38,3.099-12.427c7.988-24.405,24.611-39.774,49.798-44.317c26.582-4.795,47.878,5.064,64.031,26.525
c2.094,2.782,2.112,4.714-0.499,7.183c-3.496,3.306-6.592,7.035-10.095,10.837c-2.364-3.506-4.425-7.039-6.94-10.211
C104.843,93.427,81.91,88.297,62.884,97.426c-18.967,9.102-29.097,30.539-24.289,51.399c4.649,20.172,22.977,34.573,43.973,34.571
c13.572-0.002,24.751-5.104,33.906-15.18c22.505-24.771,44.815-49.735,67.885-73.971c17.361-18.239,39.164-24.295,63.441-17.369
c24.221,6.91,39.282,23.516,45.102,48.006c3.184,13.398,1.887,26.967-2.008,39.987c-1.322,4.422-5.715,7.985-8.899,11.78
c-10.94,13.035-24.349,21.988-41.47,24.67c-19.018,2.979-35.86-2.006-50.829-13.86c-1.162-0.92-2.304-1.863-4.361-3.533
c0,2.48-0.004,4.178,0,5.873c0.045,22.324,0.009,44.646,0.213,66.967c0.037,3.956-0.771,7.102-3.877,9.674
c-1.653,1.37-3.243,2.961-4.409,4.748c-2.552,3.912-5.974,4.865-10.668,3.637c0-6.688,0.01-13.473-0.003-20.258
c-0.041-22.488,0.024-44.979-0.227-67.465c-0.056-4.814,1.073-8.443,4.622-11.914c6.039-5.908,11.509-12.398,17.593-19.056
c4.06,8.205,9.36,14.85,16.678,19.736c15.507,10.355,35.698,10.172,51.128-0.49c15.202-10.506,22.338-29.406,18.086-47.903
c-3.979-17.298-19.188-31.573-37.106-33.975c-15.415-2.066-29.11,2.093-39.841,13.781c-21.17,23.057-42.371,46.092-63.192,69.461
c-14.497,16.271-31.743,25.988-53.992,25.404c-30.517-0.799-56.945-24.744-60.94-55.143c-0.123-0.934-0.602-1.821-0.915-2.73
C18.482,140.272,18.482,136.272,18.482,132.273z" data-llp-id="markin2-1" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
</svg>
CSS
body, html {
background: #000;
position: absolute;
width: 100%;
height: 100%;
top:0;
left:0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
}
#markin2 {
width: 40vw;
height: 40vh;
position: relative;
overflow: visible;
}
.markin2 {
animation: stroke_fill 4s linear forwards, changeColor 2s, forwards;
stroke-dasharray: 1538.2169189453125px;
stroke-dashoffset: 0;
}
#keyframes stroke_fill {
0% {
fill: white;
}
50% {
fill: white;
stroke-dashoffset: 0;
}
100% {
fill: black;
stroke-dashoffset: 0;
}
}
#keyframes changeColor {
from{ fill: rgba(0,0,0,0);}
to{ fill: rgba(0,0,0,1)}
}
Here is the SVG animation example:
https://codepen.io/cpawl/pen/zYvEqYq
The Lazy Line Painter library has some custom events built in to which you can listen. Such as the complete event whenever you animation has been completed. Whenever that event is called, hide the SVG.
In the example below I've added this event listener but also wrapped your animation in a Promise. This way you can wait for it to finish and then do something. And also another Promise which listens for the load event on the document. So that this is an actual page loader and the SVG would not disappear before the page would be loaded.
In your HTML first load the SVG and then the JS you see below here. Inside the then callback function either delete your SVG, or set a class to the body which hides the class. Anyway you see fit.
body,
html {
background: #000;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
}
#markin2 {
width: 20vw;
height: 20vh;
position: relative;
overflow: visible;
}
.markin2 {
animation: stroke_fill 4s linear forwards, changeColor 2s, forwards;
stroke-dasharray: 1538.2169189453125px;
stroke-dashoffset: 0;
}
#keyframes stroke_fill {
0% {
fill: white;
}
50% {
fill: white;
stroke-dashoffset: 0;
}
100% {
fill: black;
stroke-dashoffset: 0;
}
}
#keyframes changeColor {
from {
fill: rgba(0, 0, 0, 0);
}
to {
fill: rgba(0, 0, 0, 1);
}
}
.hsvg {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
width: 100%;
height: 100%;
background: #000000;
z-index: 999;
transition: 2000ms ease-in-out;
transition-property: opacity, visibility;
}
body.is-loaded .hsvg {
opacity: 0;
visibility: hidden;
}
.main-content {
color: #fff;
}
<script src="https://cdn.jsdelivr.net/npm/lazy-line-painter#1.9.6/lib/lazy-line-painter-1.9.6.min.js"></script>
<!-- Include lazylinepainter -->
<div class="hsvg">
<svg version="1.1" id="markin2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="314.094px" height="314.765px" viewBox="0 0 314.094 314.765" enable-background="new 0 0 314.094 314.765" xml:space="preserve"
data-llp-composed="true" class="lazy-line-painter">
<circle fill="none" stroke-miterlimit="10" cx="157.828" cy="157.404" r="150.813" data-llp-id="markin2-0" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
<path id="#markin2" class=".markin2" fill="none" values="#000" stroke-miterlimit="10" d="M18.482,132.273
c1.019-4.147,1.774-8.38,3.099-12.427c7.988-24.405,24.611-39.774,49.798-44.317c26.582-4.795,47.878,5.064,64.031,26.525
c2.094,2.782,2.112,4.714-0.499,7.183c-3.496,3.306-6.592,7.035-10.095,10.837c-2.364-3.506-4.425-7.039-6.94-10.211
C104.843,93.427,81.91,88.297,62.884,97.426c-18.967,9.102-29.097,30.539-24.289,51.399c4.649,20.172,22.977,34.573,43.973,34.571
c13.572-0.002,24.751-5.104,33.906-15.18c22.505-24.771,44.815-49.735,67.885-73.971c17.361-18.239,39.164-24.295,63.441-17.369
c24.221,6.91,39.282,23.516,45.102,48.006c3.184,13.398,1.887,26.967-2.008,39.987c-1.322,4.422-5.715,7.985-8.899,11.78
c-10.94,13.035-24.349,21.988-41.47,24.67c-19.018,2.979-35.86-2.006-50.829-13.86c-1.162-0.92-2.304-1.863-4.361-3.533
c0,2.48-0.004,4.178,0,5.873c0.045,22.324,0.009,44.646,0.213,66.967c0.037,3.956-0.771,7.102-3.877,9.674
c-1.653,1.37-3.243,2.961-4.409,4.748c-2.552,3.912-5.974,4.865-10.668,3.637c0-6.688,0.01-13.473-0.003-20.258
c-0.041-22.488,0.024-44.979-0.227-67.465c-0.056-4.814,1.073-8.443,4.622-11.914c6.039-5.908,11.509-12.398,17.593-19.056
c4.06,8.205,9.36,14.85,16.678,19.736c15.507,10.355,35.698,10.172,51.128-0.49c15.202-10.506,22.338-29.406,18.086-47.903
c-3.979-17.298-19.188-31.573-37.106-33.975c-15.415-2.066-29.11,2.093-39.841,13.781c-21.17,23.057-42.371,46.092-63.192,69.461
c-14.497,16.271-31.743,25.988-53.992,25.404c-30.517-0.799-56.945-24.744-60.94-55.143c-0.123-0.934-0.602-1.821-0.915-2.73
C18.482,140.272,18.482,136.272,18.482,132.273z" data-llp-id="markin2-1" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
</svg>
</div>
<script>
const pageLoad = new Promise(resolve => {
window.addEventListener('load', resolve);
});
const animationLoad = new Promise(resolve => {
let el = document.querySelector('#markin2');
let myAnimation = new LazyLinePainter(el, {
"ease": "easeLinear",
"strokeWidth": 2.2,
"strokeOpacity": 1,
"strokeColor": "#fff"
});
myAnimation.paint();
myAnimation.on('complete', resolve);
});
Promise.all([pageLoad, animationLoad]).then(function() {
document.body.classList.add('is-loaded');
console.log('Load event fired and animation done');
});
</script>
<div class="main-content">
<h1>IS THIS THING ON?</h1>
</div>
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>