jQuery - pause animation - javascript

My website has a news section in the format of squares that animate alot like the Metro UI. The square animates once every 5-10 seconds (random) and swaps between the text and picture.
FIDDLE
I now want the animation to immediately switch to the text-stage when the user mouse-overs, and remain there until mouse-out. When the user mouse-outs the animation can either resume with any delay that's left from before the mouse-in, or instantly switch to the picture-stage. I prefer the first, but any solution works.
I tried doing something with .hover but I'm not sure how to best pause/resume animations. Cheers.
HTML
<div class="news-container">
<div>
<div class="news-window">
<div class="date"><span>05</span><div>Sep</div></div>
<div class="news-tile" id="1">
<div class="news-pic" style="background-image:url('https://pbs.twimg.com/profile_images/378800000532546226/dbe5f0727b69487016ffd67a6689e75a.jpeg');"></div>
<div class="news-title"><div>News Title</div></div>
</div>
</div>
<div class="news-window">
<div class="date"><span>28</span><div>Aug</div></div>
<div class="news-tile" id="2">
<div class="news-pic" style="background-image:url('https://www.petfinder.com/wp-content/uploads/2012/11/155293403-cat-adoption-checklist-632x475-e1354290788940.jpg');"></div>
<div class="news-title"><div>News Title</div></div>
</div>
</div>
<div class="news-window">
<div class="date"><span>17</span><div>Aug</div></div>
<div class="news-tile" id="3">
<div class="news-pic" style="background-image:url('https://www.petfinder.com/wp-content/uploads/2012/11/99233806-bringing-home-new-cat-632x475.jpg');"></div>
<div class="news-title"><div>News Title</div></div>
</div>
</div>
</div>
</div>
CSS
.news-container {
text-align: center;
display: inline-block;
vertical-align: top;
}
.news-window {
display: inline-block;
overflow: hidden;
background: #EFEFEF;
width: 230px;
height: 200px;
margin: 0 15px;
cursor: pointer;
}
.news-tile {
width: 230px;
height: 400px;
position: relative;
top: 0px;
}
.news-pic {
width: 100%;
height: 200px;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
}
.news-title {
width: 100%;
height: 200px;
background: #5D697B;
color: orange;
font-size: 18px;
display: table;
}
.news-title div {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.news-window .date {
width: 50px;
height: 56px;
background: orange;
position: absolute;
z-index: 100;
opacity: 0.5;
line-height: 1.25;
font-size: 14px;
}
.news-window .date span {
font-size: 28px;
}
JS
$(document).ready(function(){
move(1);
move(2);
move(3);
});
function random(){
return ((Math.random() * 5000) + 5000);
}
function move(i) {
$("#" + i + ".news-tile").delay(random()).animate({top: "-200px"}, 600, 'easeOutCirc');
$("#" + i + ".news-tile").delay(random()).animate({top: "0"}, 600, 'easeOutCirc');
window.setTimeout(function() {move(i) }, 500);
}
EDIT: Fiddle had a problem. Fixed now.

Instead of .delay() use setTimeout, which is more appropriate in case of cancelling the animation on hover().
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases.
Reference
Also, it would be more convenient to use classes instead of id attributes in your situation.
I'd make it this way (updated):
$('.news-window').each(function(i, el){
el.timer = setTimeout(function(){moveUp.call(el)}, random());
}).hover(function(){moveUp.call(this, true)}, moveDown);
function random(){
return ((Math.random() * 5000) + 5000);
}
function moveUp(x){
var that = this;
$('.slide', that).stop().animate({top:"-200px"}, 600, 'swing');
clearTimeout(that.timer);
that.timer = x || setTimeout(function(){moveDown.call(that)}, random());
}
function moveDown(){
var that = this;
$('.slide', that).stop().animate({top:"0"}, 600, 'swing');
clearTimeout(that.timer);
that.timer = setTimeout(function(){moveUp.call(that)}, random());
}
NOTE, I added slide class to each of the news-tile elements (as you have more sections with news-tile class).
JSFiddle

Related

How do I bring the block up to the header by scrolling when the button is clicked?

I'm trying to make it so that when you click on the button with the class .booking__button, the block scrolls up under the header. Position should not change, only scroll. This is done so that the search results of the booking module, which, would be visible to the user. I found the code that does the scrolling, but it works with the exact number, now 100px, but you understand that this distance will be different for everyone, depending on the height of the screen.
document.querySelector('.booking__button').addEventListener('click', () => {
window.scrollTo(0, 100);
});
body {
margin: 0;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: #002164;
}
.hero {
min-height: calc(100vh - 100px);
background: #fff;
}
.booking__module {
display: flex;
justify-content: center;
align-items: center;
background: #BC0B3C;
}
.booking__search {
height: 600px;
background: #ccc;
}
.booking__button {
height: 20px;
margin: 40px;
}
.others {
height: 200vh;
}
<header class="header"></header>
<main class="hero"></main>
<section class="booking">
<div class="booking__module">
<button class="booking__button">booking</button>
</div>
<div class="booking__search"></div>
</section>
<section class="others"></section>
One approach is below, with explanatory comments in the code. Note that while I changed the background-color of the <header> element, that's simply to visualise the functionality and is not at all required:
// we pass a reference to the Event Object ('evt') to the function:
document.querySelector('.booking__button').addEventListener('click', (evt) => {
// we retrieve the closest ancestor <section> element of the element
// to which the event-handler is bound, and retrieve the 'top' property
// of its bounding-client rect:
let {top} = evt.currentTarget.closest('section').getBoundingClientRect();
// we then scroll to that value:
window.scrollTo(0, top);
});
body {
margin: 0;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
/*background: #002164;*/
background-color: hsl(200deg 70% 70% / 0.4);
}
.hero {
min-height: calc(100vh - 100px);
background: #fff;
}
.booking__module {
display: flex;
justify-content: center;
align-items: center;
background: #BC0B3C;
}
.booking__search {
height: 600px;
background: #ccc;
}
.booking__button {
height: 20px;
margin: 40px;
}
.others {
height: 200vh;
}
<header class="header"></header>
<main class="hero"></main>
<section class="booking">
<div class="booking__module">
<button class="booking__button">booking</button>
</div>
<div class="booking__search"></div>
</section>
<section class="others"></section>
JS Fiddle demo.
References:
Element.closest().
Element.getBoundingClientRect().
Event.
Event.currentTarget.
EventTarget.addEventListener().
Window.scrollTo.

Position an invisible div element over a photo(onclick)(repl.it)

Visual of element placement
I am trying to make a little “pet the dog game” and I would like to put a div over his head and when you click the DIV it will trigger a JS function to change the photo to a .gif then back again here is my code
JS:
function pet_head(){
var image = getElementById("image");
image.src="DogPet.gif";
setTimeout(function(){
image.src="dog.jpeg";
}, 1000//length of gif
);
};
HTML:
<div class="main">
<img id="image" src="dog.jpeg">
<div class="click></div>
</div>
CSS:
img{
height:100%;
width100%;
position:absolute;
}
If you use absolute in the image it will always be on top of everything else.
Take a look below and see if that is what you looking for.
function pet_head(event) {
/*var image = getElementById("image");
image.src = "DogPet.gif";
setTimeout(function() {
image.src = "dog.jpeg";
}, 1000 //length of gif
);*/
alert('changed');
};
document.getElementById('click').addEventListener('click', pet_head);
img {
height: 100%;
width: 100%;
}
div {
/* This will center the image horizontally */
display: flex;
justify-content: center;
position: absolute;
}
div#click {
color: green;
border: 2px solid red;
top: 14%;
height: 45%;
width: 300px;
position: absolute;
}
<div class="main">
<div id="click"></div>
<img id="image" src="https://i.insider.com/5df126b679d7570ad2044f3e?width=1100&format=jpeg&auto=webp" />
</div>
Here is a working version of your code. Also note that (besides removing code typos) I added object-fit: cover to your img, so that it preserves aspect ratio as the viewport size changes.
function pet_head() {
// var image = document.getElementById("image");
alert("petting the dog");
/* image.src = "DogPet.gif";
setTimeout(function() {
image.src = "dog.jpeg";
}, 1000 //length of gif
); */
};
document.querySelector(".click").addEventListener("click", pet_head);
img {
height: 100%;
width: 100%;
position: absolute;
object-fit: cover;
}
.click {
position: absolute;
left: 49%;
top: 22px;
height: 13vh;
width: 17vw;
cursor: pointer;
}
/* Presentational styles */
.click {
background: yellow;
opacity: .1;
}
html, body {
margin: 0;
}
*, *::before, &::after {
box-sizing: border-box;
}
<div class="main">
<img id="image" src="https://i.stack.imgur.com/FthXz.jpg">
<div class="click"></div>
</div>
jsFiddle

How to put scroll bar in vertical position and also how to move images with up and down arrows?

I am having difficulty to put the scroll bar in a vertical position instead of horizontal. Also, I want to slide images with up
and down arrow key of the keyboard. Please help me I have an
assignment due. I'll appreciate your help.
For more information please check my code into jsfiddle https://jsfiddle.net/mgj7hb0k/
The code below is from HTML file
<div class="slider-wrap">
<div class="slider" id="slider">
<div class="holder">
<div class="slide" id="slide-0"><span class="temp">74°</span></div>
<div class="slide" id="slide-1"><span class="temp">64°</span></div>
<div class="slide" id="slide-2"><span class="temp">82°</span></div>
</div>
</div>
<nav class="slider-nav">
Slide 0
Slide 1
Slide 2
</nav>
</div>
CSS file. I have added some styles into separate css file.The "slider" (visual container) and the slides need to have explicity the same size. We'll use pixels here but you could make it work with anything.
#import url(https://fonts.googleapis.com/css?family=Josefin+Slab:100);
.slider-wrap {
width: 300px;
height: 500px;
margin: 20px auto;
}
.slider {
overflow-x: scroll;
}
.holder {
width: 300%;
}
.slide {
float: left;
width: 300px;
height: 500px;
position: relative;
background-position: -100px 0;
}
.temp {
position: absolute;
color: white;
font-size: 100px;
bottom: 15px;
left: 15px;
font-family: 'Josefin Slab', serif;
font-weight: 100;
}
#slide-0 {
background-image: url(http://farm8.staticflickr.com/7347/8731666710_34d07e709e_z.jpg);
}
#slide-1 {
background-image: url(http://farm8.staticflickr.com/7384/8730654121_05bca33388_z.jpg);
}
#slide-2 {
background-image: url(http://farm8.staticflickr.com/7382/8732044638_9337082fc6_z.jpg);
}
.slide:before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40%;
background: linear-gradient(transparent, black);
}
.slider-nav {
text-align: center;
margin: 10px 0 0 0;
}
.slider-nav a {
width: 10px;
height: 10px;
display: inline-block;
background: #ddd;
overflow: hidden;
text-indent: -9999px;
border-radius: 50%;
}
.slider-nav a.active {
background: #999;
}
We're going to use jQuery here because we love life. Our goal is the adjust the background-position of the slides as we scroll. We can set background-position in percentages in CSS, but that alone doesn't do the cool hide/reveal more effect we're looking for. Based the amount scrolled (which we can measure in JavaScript), we'll adjust the background-position. Alone, that would look something like this:
Js file
var slider = {
// Not sure if keeping element collections like this
// together is useful or not.
el: {
slider: $("#slider"),
allSlides: $(".slide"),
sliderNav: $(".slider-nav"),
allNavButtons: $(".slider-nav > a")
},
timing: 800,
slideWidth: 300, // could measure this
// In this simple example, might just move the
// binding here to the init function
init: function() {
this.bindUIEvents();
},
bindUIEvents: function() {
// You can either manually scroll...
this.el.slider.on("scroll", function(event) {
slider.moveSlidePosition(event);
});
// ... or click a thing
this.el.sliderNav.on("click", "a", function(event) {
slider.handleNavClick(event, this);
});
// What would be cool is if it had touch
// events where you could swipe but it
// also kinda snapped into place.
},
moveSlidePosition: function(event) {
// Magic Numbers =(
this.el.allSlides.css({
"background-position": $(event.target).scrollLeft()/6-100+ "px 0"
});
},
handleNavClick: function(event, el) {
event.preventDefault();
var position = $(el).attr("href").split("-").pop();
this.el.slider.animate({
scrollLeft: position * this.slideWidth
}, this.timing);
this.changeActiveNav(el);
},
changeActiveNav: function(el) {
this.el.allNavButtons.removeClass("active");
$(el).addClass("active");
}
};
slider.init();

How do I create a fixed amount of space between a responsive image and an element below?

I have a responsive slider with elements below. I've tried using margin-top on the element below and margin-bottom on the image. In both cases, when the view-port reduces, the image and the other elements part company...ie the gap widens. I've tried px, vw and vh as the unit for the margin.
Is there a technique to resolve this?
The code is:
<div id="slider">
<div class="container">
<div>
<img class="slider_img" src="images/hands-coffee-cup-apple_1920x965.jpg"/>
</div>
<div>
<img class="slider_img" src="images/macbook-apple-imac-computer-39284_1920x965.jpg"/>
</div>
<div>
<img class="slider_img" src="images/ipad-tablet-technology-touch_1920x965.jpg"/>
</div>
</div>
</div>
<div class="promises_hdr">Our promise to you</div>
<div class="promises">
<div class="promise">
<img class="promise_img" src="images/iconfinder_ecommerce.png"/>
<div class="promise_hdr">Get Noticed, Get Customers</div>
<div class="promise_txt">
<p>The progression from the Get Noticed Online step to the Create Customer step goes through 2 other stages. These are Convert and Close. Inward Marketing: webThemes understands.</p>
</div>
</div>
#slider{
width:100%;
height: 100vh;
position: relative;
}
.container {
max-width: 100%;
height: 100%;
margin: auto;
position: absolute;
}
.container div {
display: inline-block;
width: 100%;
height: 940px;
display: none;
}
.slider_img {
width: 100%;
height: auto;
z-index: -1;
}
.promises_hdr {
font-family: "Century Gothic", Sans-serif;
font-size: 2.3em;
color: #0150E2;
position: relative;
text-align: center;
margin-top: 4vw;
}
$( document ).ready(function() {
var currentIndex = 0,
items = $('.container div'),
itemAmt = items.length;
function cycleItems() {
var item = $('.container div').eq(currentIndex);
items.hide();
item.css('display','inline-block');
}
var autoSlide = setInterval(function() {
currentIndex += 1;
if (currentIndex > itemAmt - 1) {
currentIndex = 0;
}
cycleItems();
}, 4000);
});
Try to use % value for the margin as well. It's the most confident way to resolve many problems in CSS, especially in tweaking site's responsiveness.

Continous animation to show or hide element without fade

I'd like to continuously show and hide two page elements in turn.
This is the code:
$(document).ready(function() {
var continuous = function () {
setTimeout(function() { $("#Mass_alert").css('display','block'); $("#Devotion_alert").css('display','none'); },1500);
setTimeout(function() { $("#Mass_alert").css('display','none'); $("#Devotion_alert").css('display','block'); },1500);
};
setInterval(continuous,500);
});
This is the HTML:
<div id="Mass_alert" class="alert" style="position: relative; top: 3px; margin: 0 auto; text-align: center; width:100%; height: 20px;">Mass alert</div>
<div id="Devotion_alert" class="alert" style="position: relative; top: 3px; margin: 0 auto; text-align: center; width:100%; height: 20px;">devotion alert</div>
I get the right effect once. What should I change in the code above to have the continuous effect. I don't want to use fadeToggle, because, I actually need the display:none setting. If I don't then there is space left for the hidden element that interferes with the placement of the other element.
try:
setInterval(function () {
$('#Mass_alert, #Devotion_alert').toggle();
}, 1500);
​
with:
<div id="Mass_alert" class="alert" style="position: relative; top: 3px; margin: 0 auto; text-align: center; width:100%; height: 20px;">Mass alert</div>
<div id="Devotion_alert" class="alert" style="position: relative; top: 3px; margin: 0 auto; text-align: center; width:100%; height: 20px; display: none;">devotion alert</div>​
demo: http://jsfiddle.net/qxMdA/1/
Try just toggling back and forth.
var a = false;
$(document).ready(toggle);
function toggle() {
if (a) {
$("#Mass_alert").css('display','block'); $("#Devotion_alert").css('display','none');
}
else
{
$("#Mass_alert").css('display','none'); $("#Devotion_alert").css('display','block');
}
a = !a;
setTimeout(toggle, 1500);
}

Categories