Refactor preloader script to be modular - javascript

How to refactor below given preloader script to be modular and used in many sections in a page:
JS
$(window).load(function() {
var preloaderDelay = 200,
preloaderFadeOutTime = 800;
function hidePreloader() {
var loadingAnimation = $('#loading-animation'),
preloader = $('#preloader');
loadingAnimation.fadeOut();
preloader.delay(preloaderDelay).fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
CSS
#preloader { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: #ffffff; z-index: 9999; }
#loading-animation { width: 200px; height: 200px; position: absolute; left: 50%; top: 50%; background: url(asset-path('assets/loading-animation.gif')) center center no-repeat; margin: -100px 0 0 -100px; }

I think you can do this way:
JS
$(function () {
$.fn.preloader = function () {
var objPreloader = $(this)
objPreloader.prepend('<div class="preloader"> <div class="loading-animation"></div> </div>');
$(window).load(function () {
var preloaderDelay = 200,
preloaderFadeOutTime = 800;
function hidePreloader() {
var loadingAnimation = objPreloader.find('.loading-animation') ,
preloader = objPreloader.find('.preloader');
loadingAnimation.fadeOut();
preloader.delay(preloaderDelay).fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
};
$('.section-a').preloader();
$('.section-b').preloader();
});
CSS
.preloader { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #f4f3f3; z-index: 9999; }
.loading-animation { width: 200px; height: 200px; position: absolute; left: 50%; top: 50%; background: url(asset-path('loading-animation.gif')) center center no-repeat; margin: -100px 0 0 -100px; }

Related

Struggling to clone animation

I am trying to create a linear animation with pipes just like the flappy bird game. When I have one single pipe, I see a random gap and it works well, but when I clone all the pipes, there is no longer a gap at a random position.
How can I give the gaps in the pipe a random position when I have multiple pipes, and why is it not working as expected?
var block = document.getElementById("block");
//clone the pipe multiples times
var blockClone;
for (var i = 0; i < 4; i++) {
blockClone = block.cloneNode(true);
// the true is for deep cloning
//append all clones to original pipe
block.appendChild(blockClone);
//remove animtion from clones
blockClone.style.animationName = "none";
}
//gap inbetween each pipe
var hole = document.getElementById("hole");
var holeClone;
for (var i = 0; i < 4; i++) {
holeClone = hole.cloneNode(true);
// the true is for deep cloning
//append all clones to original pipe
blockClone.appendChild(hole);
block.appendChild(hole);
//remove animtion from clones
holeClone.style.animationName = "none";
hole.addEventListener('animationiteration', () => {
var random = -((Math.random() * 300) + 150);
hole.style.top = random + "px";
});
}
body {
text-align: center;
position: fixed;
width: 100%;
height: 100%;
}
* {
padding: 0;
margin: 0;
}
#game {
width: 100%;
height: 500px;
border: 1px solid red;
margin: auto;
overflow: hidden;
}
/* pipe version 1 */
#block {
width: 60px;
height: 500px;
background-color: green;
background-image: url("https://l.dropbox.com/s/4jz7uq4e25o8su5/sketch-1664244879.png?dl=0");
background-size: cover;
position: absolute;
left: 100px;
animation: block 5s infinite linear;
}
#hole {
width: 60px;
height: 210px;
background-color: red;
position: absolute;
left: 0px;
top: -10px;
/* animation: block 5s infinite
linear;*/
background-image: url("https://dldropbox.com/s/j7enawgtuepj7au/sketch-166428805830.png?dl=0");
background-size: cover;
}
#character {
width: 40px;
height: 40px;
background-color: none;
position: absolute;
top: 100px;
left: 40px;
border-radius: ;
z-index: 1;
background-color: red;
}
}
#overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: black;
cursor: none;
opacity: 0.3;
text-align: center;
}
/* used to prevent user from tapping even after the game has ended*/
.mainoverlay {
position: fixed;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
cursor: none;
opacity: 0;
}
#blokhold {
animation: block 5s infinite linear;
}
#keyframes block {
0% {
left: 350px
}
100% {
left: -890px
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="game">
<div id="blokhold">
<div id="block">
<div id="hole"></div>
</div>
</div>
<div id="character"></div>
</div>

Onclick handler for dynamic button (added via JS) returning null

I have a button, in my markup called .open-video.
Clicking .open-video opens up a modal which then contains another button .close--modal. The code for the modal (which includes the markup for .modal--close) is added when the .open-video button is clicked.
Now, I'm aware that the EventListener for .modal--close needs to exist after the markup is added to the DOM on the first EventListener for .open-video. But, doing this isn't doing anything at the moment, I instead get the error message Cannot read properties of null (reading 'addEventListener') and I believe this is because the DOMContentLoaded event was already fired at this point.
Currently, when clicking .modal--close, I just want to do a simple console.log("test");.
See my demo below:
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let close_btn = document.querySelector(".modal--close");
let modal = document.querySelector(".modal");
console.log(close_btn);
if (video_btn) {
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#' + triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="' + triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before,
.modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before,
.modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe,
.modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>
How can I get my .modal--close button to print the log? Where am I going wrong?
Because you call closeElement before you create closeElement.
You can call this element after creating.
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// ... codes
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
let close_btn = document.querySelector(".modal--close");
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
You can't document.querySelect an element before it's added to the DOM, you should move the line of
let close_btn = document.querySelector(".modal--close"); // here
to inside the video_btn.addEventListener callback function after you've added the element .modal--close to the DOM.
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let modal = document.querySelector(".modal");
if (video_btn) {
video_btn.addEventListener("click", function(e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#' + triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="' + triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
// modal.insertAdjacentHTML('beforeend', html);
modal.innerHTML = html;
let close_btn = document.querySelector(".modal--close"); // here
close_btn.addEventListener("click", function(e) {
e.preventDefault();
console.log("test");
});
return false;
});
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before,
.modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before,
.modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe,
.modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>

Problems trying to animate my objects in jquery

I am trying to make my character move diagonally. My aim is to make him move towards the door depending on which door I click. There are two doors on the screen; top-left door and top-right door. Right now when I click on the top-left door he moves towards that door, but when I click on the top-right door he moves straight. I don't know where I'm going wrong with this and I could really use some help.
Here is the code that I have so far:
$(document).ready(function() {
//center the character
function centreThing(obj) {
//this is the height and width of heartless
h = $(obj).height();
w = $(obj).width();
$(obj).css({
//this is the height and width of the stage
//height and width of stage by 2 - height and width of heartless by 2
top: $('#stage').height() / 2 - h / 2,
left: $('#stage').width() / 2 - w / 2,
right: $('#stage').width() / 2 - w / 2
})
}
centreThing('#character');
//speech
var progress = 0;
var txt;
//click the door to go to next page
//animate character to the left door
$('#door1').click(function() {
$('#character').animate({
top: 0,
left: 150
}, {
duration: 1000,
complete: function() {
alert("entered");
}
});
});
//click the door to go to next page
//animate character to the right door
$('#door2').click(function() {
$('#character').animate({
top: 0,
right: 150
}, {
duration: 1000,
complete: function() {
alert("entered");
}
});
});
}); // do not delete this line
#character {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
z-index: 99;
}
#door1 {
background-image: url("https://placehold.it/50x50?text=closeddoor");
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 130px;
z-index: 5;
}
#door1:hover {
background-image: url("https://placehold.it/50x50?text=opendoor");
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 130px;
}
#door2 {
background-image: url("https://placehold.it/50x50?text=closeddoor");
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 510px;
}
#door2:hover {
background-image: url("https://placehold.it/50x50?text=opendoor");
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 510px;
z-index: 5;
}
#stage {
position: relative;
width: 720px;
height: 480px;
margin: auto;
margin-top: 100px;
background-color: black;
border-style: solid;
border-width: 5px;
border-color: white;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MAS340</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id="stage">
<img src="https://placehold.it/50x50?text=character" id="character" class="center">
<div id='door1'></div>
<div id='door2'></div>
</div>
</body>
</html>
Try it like this.Reset the left position on clicking the #door2.It happens baecause you have set the left position of the character in centreThing().So on clicking the #door2 the character has left,right and top value.So it is starting at the left value.I have removed the left value on clicking on #door2 and it worked
$(document).ready(function() {
//center the character
function centreThing(obj) {
//this is the height and width of heartless
h = $(obj).height();
w = $(obj).width();
$(obj).css({
//this is the height and width of the stage
//height and width of stage by 2 - height and width of heartless by 2
top: $('#stage').height()/2-h/2,
left: $('#stage').width()/2-w/2,
right: $('#stage').width()/2-w/2
})
}
centreThing('#character');
//speech
var progress = 0;
var txt;
//click the door to go to next page
//animate character to the left door
$('#door1').click(function() {
$('#character').animate({
top: 0,
left: 150
}, {
duration: 1000,
complete: function() {
alert("entered");
}
});
});
//click the door to go to next page
//animate character to the right door
$('#door2').click(function() {
$('#character').css({
'left':''
}).animate({
top: 0,
right: 150
}, {
duration: 1000,
complete: function() {
alert("entered on 2");
}
});
});
}); // do not delete this line
#character {
position: absolute;
/* bottom: 0px;
left: 0px;
right: 0px;*/
z-index: 99;
}
#door1 {
background:#F00;
background-image: url(images/closeddoor.png);
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 130px;
z-index: 5;
}
#door1:hover {
background-image: url(images/opendoor.png);
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 130px;
}
#door2 {
background:#FF0;
background-image: url(images/closeddoor.png);
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 510px;
}
#door2:hover {
background-image: url(images/opendoor.png);
position: absolute;
width: 80px;
height: 60px;
top: -3px;
left: 510px;
z-index: 5;
}
#stage {
position: relative;
width: 720px;
height: 480px;
margin: auto;
margin-top: 100px;
background-color: black;
border-style: solid;
border-width: 5px;
border-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MAS340</title>
<link href="styles.css" rel="stylesheet" />
<script src="jquery-3.1.1.min.js"></script>
<script>
</script>
</head>
<body>
<div id="stage">
<img src="images/character.png" id="character" class="center">
<div id='door1'></div>
<div id='door2'></div>
</div>
</body>
</html>

Parent div to change dimension when inner image rotate

I have a modal containing one or more images and these images can rotate.
My issue is when image rotate it overflow the parent div. I wish to have the container to change dimension to always fit the image (images).
I created a codepen to have a look.
I tried to change many and many css properties without success...
Jade:
.overlay
.fake-modal
.content
img.img(src='http://lorempixel.com/output/abstract-q-c-300-200-2.jpg')
.wrapper
button.left rotate left
button.right rotate right
Less:
.overlay {
background-color: rgba(0, 0, 0, .7);
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
}
.fake-modal {
background-color: #fff;
padding: 10px;
position: fixed;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
width: auto;
height: auto;
z-index: 1;
.content {
position: relative;
.wrapper {
position: absolute;
top: 10px;
right: 10px;
}
}
}
js:
var angle = 0;
var btnLeft = $('.left');
var btnRight = $('.right');
btnLeft.on('click', function (e) {
e.preventDefault();
angle = angle - 90;
rotate(angle);
});
btnRight.on('click', function (e) {
e.preventDefault();
angle = angle + 90;
rotate(angle);
});
function rotate(rotateDegrees) {
var r = 'rotate(' + rotateDegrees + 'deg)';
var img = $('.img');
img.css({
'-moz-transform': r,
'-webkit-transform': r,
'-o-transform': r,
'-ms-transform': r
});
}
Solved using getBoundingClientRect()
Codepen: http://codepen.io/anon/pen/BNENge
you may set fixed width and height to div contaning image.
http://codepen.io/anon/pen/XbQXJP
`.overlay {
background-color: rgba(0, 0, 0, .7);
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
}
.fake-modal {
background-color: #fff;
padding: 10px;
position: fixed;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
width: auto;
height: auto;
z-index: 1;
.content {
position: relative;
.imgContainer {
position: relative;
width: 300px;
height: 200px;
.img {
position: absolute;
margin-left: -150px;
margin-top: -100px;
top: 50%;
left: 50%;
}
}
.wrapper {
position: absolute;
top: 10px;
right: 10px;
}
}
}`

Container showing when my page is loaded

When I have loaded my page my containers: '.lightbox-prev, .lightbox-next' load however I only want them to be visible when the '.lightbox-trigger' is clicked.
My HTML:
<div class="lightboxbg"></div>
<div class="lightbox-prev"></div>
<div class="lightbox-next"></div>
<div class="lightbox"></div>
My CSS:
div.lightbox{
position: absolute;
top: 25%;
left: 45%;
background: center no-repeat #fff;
width: 400px;
height: 600px;
padding: 10px;
z-index: 1001;
display: none;
}
div.directionslightbox{
position: absolute;
top: 10%;
left:18%;
background:url("../Map_Background_Web.png"); center;
background-repeat: no-repeat;
background-size: cover;
width: 65%;
height: 80%;
padding: 10px;
z-index: 1001;
display: none;
}
div.lightboxbg{
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.5);
z-index: 1000;
display: none;
}
.lightbox-prev, .lightbox-next {
position: absolute;
top: 0;
bottom: 0;
width: 250px;
background: center no-repeat red;
z-index: 1001;
cursor: pointer;
}
.lightbox-prev {
left: 0;
background-image: url("../previous.png");
}
.lightbox-next {
right: 0;
background-image: url("../next.png");
}
My JS:
<script type="text/javascript">
var lightboxcounter;
$(document).ready(function(){
$('.lightbox-trigger').click(function() {
lightboxcounter = $(this).attr('data-counter');
var image = $(this).attr('data-img')
$('.lightbox').css('background-image', 'url(' + image + ')');
$('.lightboxbg, .lightbox, .lightbox-prev, .lightbox-next').fadeIn(800);
});
$('.lightboxbg').click(function() {
$('.lightboxbg, .lightbox, .lightbox-prev, .lightbox-next').fadeOut(800);
});
$('.lightbox-prev').click(function() {
lightboxcounter--;
$('.lightbox-trigger[data-counter="'+lightboxcounter+'"]').click();
});
$('.lightbox-next').click(function() {
lightboxcounter++;
console.log(lightboxcounter);
$('.lightbox-trigger[data-counter="'+lightboxcounter+'"]').click();
});
});
</script>
If anyone could help, I would most appreciate it, it's been bugging me all day!
Cheers
You are already using fadeIn to display the controls so all you need to do is hide them initially.
Add this to your CSS...
.lightbox-prev, .lightbox-next {
display: none;
}

Categories

Resources