I am trying to modify a slideshow to continuously animate while the mouse is over the back or next arrow. If the mouse leaves, I would like the animation to stop where it is.
I found this post and this post which are helpful in telling me I need to use setInterval, but because I am a beginner I am not sure how to implement it with the code I have. I tried updating the miliseconds set in the counter variable but that didn't change anything.
Here is the hover code so far. It advances the image on hover but not continuously.
$(document).ready(function(){
var thumbs = $('ul.thumbHolder li');
var bigImgs = $('ul.imgHolder li');
var mask = $('.imgHolder');
var imgW = $('ul.imgHolder li').width();
var speed = 800;
thumbs.removeClass('selected').first().addClass('selected');
thumbs.click(function () {
var target = $(this).index();
mask.animate({
'left': '-' + imgW * target + 'px'
}, speed);
thumbs.removeClass('selected');
$(this).addClass('selected');
});
$('.Bleft').on('mouseover', function () {
var i = $('ul.thumbHolder li.selected').index();
i--;
$('ul.thumbHolder li.selected').removeClass('selected');
thumbs.eq(i).addClass('selected');
if (i === -1) {
mask.animate({
'left': '-' + imgW * $('ul.thumbHolder li').index() + 'px'
}, speed);
} else {
mask.animate({
'left': '-' + imgW * i + 'px'
}, speed);
}
clearInterval(counter);
});
$('.Bright').on('mouseover', function () {
var i = $('ul.thumbHolder li.selected').index();
i = i >= thumbs.length - 1 ? 0 : i + 1;
$('ul.thumbHolder li.selected').removeClass('selected');
thumbs.eq(i).addClass('selected');
mask.animate({
'left': '-' + imgW * i + 'px'
}, speed);
clearInterval(counter);
});
var count = 0;
var counter = window.setInterval(timer, 5000);
function timer() {
count = count + 0;
if (count >= 0) {
count = 0;
return;
}
mask.animate({
'left': '-' + imgW * count + 'px'
}, speed);
thumbs.removeClass('selected');
thumbs.eq(count).addClass('selected');
}
});
This is an example of what I am trying to achieve (I know it is flash but I think it can be done with jQuery too).
This is a fiddle that has all my work so far.
Thank you for any help.
I think I am close to the solution. This is my idea.
Every ul.imgHolder li is divided in many blocks of 20px ( you can change the size of course ), so if a div has a size of 980px you will have 49 blocks for image.
When mouseover event is fired I will slide for a block every speed milliseconds until the mouseout is fired.
I've implemented only the slide right button, I've deleted partially some logic, sorry!
var $ = jQuery.noConflict(true);
$(document).ready(function(){
var thumbs = $('ul.thumbHolder li');
var bigImgs = $('ul.imgHolder li');
var mask = $('.imgHolder');
var imgW = $('ul.imgHolder li').width(); //Assuming imgW % 20 = 0
var blockSize = 20; //20px
var blocksPerThumb = imgW/blockSize;
var numBlocks = (blocksPerThumb)*thumbs.length;
var speed = 400;
var blockPos = 0;
var currentAnim = null;
thumbs.removeClass('selected').first().addClass('selected');
thumbs.click(function () {
var target = $(this).index();
mask.animate({
'left': '-' + imgW * target + 'px'
}, speed,'linear');
thumbs.removeClass('selected');
$(this).addClass('selected');
});
$('.Bleft').on('mouseover', function () {
});
$('.Bright').on('mouseover', function(){
currentAnim = setInterval(goRight,speed);
}).mouseout(function(){
clearInterval(currentAnim);
});
var goRight = function () {
blockPos = (blockPos+1)%numBlocks;
mask.animate({
'left': '-' + blockSize * blockPos + 'px'
}, speed,'linear');
};
});
Good Work!
Related
Every time I load my page for the first time my script does not load, I need to refresh the page at least 3 times for it to run. How can I make my script run without a page refresh? This particular script is in BABEL.
'use strict';
var deg = 0;
var index = 0;
$('#' + index).css('opacity', '1');
$('.navbar').contextmenu(function () {
return false;
});
$('.navbar').on('mousewheel', function (e) {
var move = -60;
var nextIndex = nextIndex = (index + 1) % 6;
if (e.originalEvent.wheelDelta / 120 <= 0) {
// wheel up
move = 60;
nextIndex = index -1 < 0 ? 5 : index - 1;
}
$('.scroll-list').css('transform', 'rotateX(' + (deg + move) + 'deg)');
$('#' + index).css('opacity', '0.01');
$('#' + nextIndex).css('opacity', '1');
index = nextIndex;
deg = deg + move;
event.stopPropagation();
console.timeEnd('cache');
});
And what if you wrapped your code inside a window.onload function?
window.onload = function() {
// your code
}
Your code will only run when the html document is "ready" and fully loaded.
You are running Javascript that depends on page elements and the javascript is executed before the elements are on the page;
Wrapp all your code inside document.ready function
$(document).ready(function () {
var deg = 0;
var index = 0;
$('#' + index).css('opacity', '1');
$('.navbar').contextmenu(function () {
return false;
});
$('.navbar').on('mousewheel', function (e) {
var move = -60;
var nextIndex = nextIndex = (index + 1) % 6;
if (e.originalEvent.wheelDelta / 120 <= 0) {
// wheel up
move = 60;
nextIndex = index - 1 < 0 ? 5 : index - 1;
}
$('.scroll-list').css('transform', 'rotateX(' + (deg + move) + 'deg)');
$('#' + index).css('opacity', '0.01');
$('#' + nextIndex).css('opacity', '1');
index = nextIndex;
deg = deg + move;
event.stopPropagation();
console.timeEnd('cache');
});
});
Wrap your code in ready function, so that your JavaScript executes after DOM is loaded.
I'm doing a little dice game to learn.
What I do is i scrumble the dice X amount of times, keep slowing the random down until it gets to the final value, and that's the "winning number".
But i would like to execute the scrumble 1 by 1 on the dices. Imagine I got 2. And later I do a little zoom effect.
I was thinking I could achieve this by using promises but is not working for me, I don't know what I'm missing.
Here's the JS code:
var counter = 0.8;
var diceNumber = 0;
var rollDice = function(diceId){
var dfd = new $.Deferred();
$('#' + diceId).removeClass('idle');
counter *= 1.2;
diceNumber = Math.round(Math.random()*5) + 1;
$('#' + diceId).removeClass();
$('#' + diceId).addClass('dice_' + diceNumber);
if(counter < 800) {
timeout = setTimeout(rollDice, counter, diceId);
}else{
$('.winner').text(diceNumber);
$('#' + diceId).removeClass();
$('#' + diceId).addClass('animate');
$('#' + diceId).addClass('dice_' + diceNumber)
.animate({ zoom: '1.3' }, 200)
.animate({ zoom: '1' }, 100);
dfd.resolve();
return dfd.promise();
}
}
var startToDice = function() {
rollDice('dice_1').then(rollDice('dice_2'));
}
startToDice();
And what it ends up doing is running both dices simultaneously.
Any advice? Thanks.
You're on the right track. I couldn't test cause I don't have all the elements in place, but try this out:
var counter = 0.8;
var diceNumber = 0;
var rollDice = function(diceId){
var dfd = new $.Deferred();
var roll = function() {
$('#' + diceId).removeClass('idle');
counter *= 1.2;
diceNumber = Math.round(Math.random()*5) + 1;
$('#' + diceId).removeClass();
$('#' + diceId).addClass('dice_' + diceNumber);
if(counter < 800) {
timeout = setTimeout(roll, counter);
}else{
$('.winner').text(diceNumber);
$('#' + diceId).removeClass();
$('#' + diceId).addClass('animate');
$('#' + diceId).addClass('dice_' + diceNumber)
.animate({ zoom: '1.3' }, 200)
.animate({ zoom: '1' }, 100);
dfd.resolve();
}
}
roll();
return dfd.promise();
}
var startToDice = function() {
rollDice('dice_1').then(function(){
rollDice('dice_2');
});
}
startToDice();
Let me know if you get any errors when you run it so I can make adjustments as necessary.
Like comented by bergi:
var startToDice = function() {
rollDice('dice_1').then(function() { rollDice('dice_2'); });
}
I use a scrollTop function to start animations, delays, etc when the div is scrolled to. It works for other things on my page, but for some reason, this function is not working and it loads on page load.
Does anyone see anything wrong in my code? This can be seen live here:
<div class="blue-box-container">
</div>
$(function() {
var oTop = $('.blue-box-container').offset().top - window.innerHeight;
$(window).scroll(function() {
var pTop = $('body').scrollTop();
console.log(pTop + ' - ' + oTop);
if (pTop > oTop) {
blueBoxDelays();
}
});
});
$('.fadeBlock').css('display', 'none');
blueBoxDelays();
function blueBoxDelays() {
var delay = 0;
$('.fadeBlock').each(function(i) {
$(this).delay(400 + delay).fadeIn(1000);
delay = 200 * (i + 1);
});
};
I extracted your code to a fiddle and it works correctly https://jsfiddle.net/26jw7Low/3/, you just need to remove the call to blueBoxDelays() which is outside of the initial function as seen below.
$(function() {
var oTop = $('.blue-box-container').offset().top - window.innerHeight;
$(window).scroll(function() {
var pTop = $('body').scrollTop();
console.log(pTop + ' - ' + oTop);
if (pTop > oTop) {
blueBoxDelays();
}
});
});
$('.fadeBlock').css('display', 'none');
// REMOVE THIS blueBoxDelays();
function blueBoxDelays() {
var delay = 0;
$('.fadeBlock').each(function(i) {
$(this).delay(400 + delay).fadeIn(1000);
delay = 200 * (i + 1);
});
};
Function $('.fadeBlock').css('display', 'none'); maybe not yet execute
You can put it to $(function(){}) end try again:
$(function() {
$('.fadeBlock').css('display', 'none');
var oTop = $('.blue-box-container').offset().top - window.innerHeight;
$(window).scroll(function() {
var pTop = $('body').scrollTop();
console.log(pTop + ' - ' + oTop);
if (pTop > oTop) {
blueBoxDelays();
}
});
});
I am trying to create a simple game on a webpage.
The game should be like this:
The web page should display at random times images placed in random positions on the browser window.
Each image lasts on the browser window for a short period of time and then it disappears.
If the user clicks an image before it disappears, he/she gets a point.
The game ends when the user wins 10 points.
So far I managed to display all elements on a page at random positions, then delete them, and display them again.
Right now I am having problems with the count of each click.
JavaScript
$(document).ready(function () {
timeOut();
});
function timeOut() {
setInterval(function () {
deleteImages();
createImages();
}, 3000);
}
function createImages() {
var myarray = ["img/Angel.gif", "img/Angry.gif", "img/BigSmile.gif",
"img/Confused.gif", "img/Cool.gif", "img/Crying.gif",
"img/Eyebrow.gif", "img/Goofy.gif", "img/Happy.gif"];
var count = 0;
var div;
for (var i = 0; i < 9; i++) {
var randPos = 0 + Math.floor(Math.random() * 500);
this.img = document.createElement("img");
div = document.createElement("div");
$("div").attr("id", "div" + i);
var randNew = 0 + Math.floor(Math.random() * (5));
var rand = 0 + Math.floor(Math.random() * (9 - count));
this.img.src = myarray[rand];
$('#div' + i).css("left", randPosition());
$('#div' + i).css("right", randPosition());
$('#div' + i).css("top", randPosition());
$('#div' + i).css("bottom", randPosition());
$('#div' + i).css("position", "relative");
$('#div' + i).show();
div.appendChild(this.img);
$("body").prepend(div);
myarray.splice(rand, 1);
count++;
}
//setTimeout(function(){ jQuery("div").hide(); }, 3000);
}
function deleteImages() {
$("div").remove();
}
function randPosition() {
return 0 + Math.floor(Math.random() * 500);
}
$(function () {
$("div").click(function (e) {
var offset = $(this).offset();
var relativeX = (e.pageX - offset.left);
var relativeY = (e.pageY - offset.top);
alert("X: " + relativeX + " Y: " + relativeY);
});
});
css
.active-div{
position:relative;
}
.menu-div{
position:absolute;
top:0;
right:0;
display:none;
}
Use a counter and increment when you click an image:
var count = 0;
count++;
Also you need to reapply the click event because you are recreating new elements instead of moving the already created ones:
Call this:
$("div").click(function(e) {
var offset = $(this).offset();
var relativeX = (e.pageX - offset.left);
var relativeY = (e.pageY - offset.top);
});
after createImages function like so:
var count = 0;
var holder;
$(document).ready(function(){
timeOut();
});
function addOnClicks() {
$("div").on('click',function(e) {
var offset = $(this).offset();
var relativeX = (e.pageX - offset.left);
var relativeY = (e.pageY - offset.top);
count++;
if(count >= 10)
{
deleteImages();
clearInterval(holder);
alert("Game Over");
}
});
}
function timeOut(){
holder = setInterval(function(){deleteImages();createImages();addOnClicks(); }, 3000);
}
function createImages(){
var myarray=["img/Angel.gif","img/Angry.gif","img/BigSmile.gif",
"img/Confused.gif","img/Cool.gif","img/Crying.gif",
"img/Eyebrow.gif","img/Goofy.gif","img/Happy.gif"
];
var count=0;
var div;
for (var i = 0; i < 9; i++) {
var randPos = 0 + Math.floor(Math.random() * 500);
this.img = document.createElement("img");
div = document.createElement("div");
$("div").attr("id","div"+i);
var randNew = 0 + Math.floor(Math.random() * (5));
var rand = 0 + Math.floor(Math.random() * (9-count));
this.img.src = myarray[rand];
$('#div'+i).css("left", randPosition());
$('#div'+i).css("right",randPosition());
$('#div'+i).css("top",randPosition());
$('#div'+i).css("bottom",randPosition());
$('#div'+i).css("position","relative");
$('#div'+i).show();
div.appendChild(this.img);
$("body").prepend(div);
myarray.splice(rand,1);
count++;
}
//setTimeout(function(){ jQuery("div").hide(); }, 3000);
}
function deleteImages(){
$("div").remove();
}
function randPosition(){
return 0 + Math.floor(Math.random() * 500);
}
.active-div{
position:relative;
}
.menu-div{
position:absolute;
top:0;
right:0;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Use an incremented variable like so:
$(function() {
var click_count = 0;
$("div").click(function(e) {
click_count++;
});
});
I have an element with animated top margin. I need to detect if it isn't too close from the border, and if it is, scroll parent div to lower position, to prevent animated element from hiding. Here is an example:
http://jsfiddle.net/zYYBR/5/
This green box shouldn't be below the red line after clicking the "down" button.
Do you mean this?
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down').click(function() {
var goStep = step;
var elHeight = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
if((elHeight + step) > limit)
{
goStep = limit - elHeight;
}
new_margin = goStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({marginTop: new_margin}, 1000);
});
http://jsfiddle.net/zYYBR/8/
EDIT: Or maybe something like that (of course you can improve the calculation, because currently it's very buggy with scroll):
var new_margin;
var step = 75;
$('#down').click(function () {
scroll(1000);
});
var scrollTimer = null;
$("#container").bind("scroll", function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function () { scroll(1); }, 10);
});
function scroll(speed) {
var scrollStep, animationStep = step;
var currentBoxBottom = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
var nextCurrentBoxBottom = currentBoxBottom + step;
var limit = $("#max")[0].offsetTop + $("#container")[0].scrollTop;
if (nextCurrentBoxBottom > limit) {
if (limit >= $("#container")[0].scrollTop) {
scrollStep = $("#container")[0].scrollTop + nextCurrentBoxBottom - limit;
}
else {
scrollStep = $("#container")[0].scrollTop - nextCurrentBoxBottom - limit;
animationStep = nextCurrentBoxBottom - limit;
}
$("#container")[0].scrollTop = scrollStep;
}
new_margin = animationStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({ marginTop: new_margin }, speed);
}
http://jsfiddle.net/zYYBR/13/
Do you mean something like this?
I have the same visual result as Alex Dn did, but I added a little extra direction to what I think you're talking about. If it's what you're looking for I'll make updates:
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down2').click(function() {
var anim = $("#animated");
var hrOff = $("#max").offset();
var thOff = anim.offset();
new_margin = Math.min(hrOff.top - thOff.top - anim.height(), 75);
console.log(new_margin, hrOff.top, thOff.top);
var st = 0;
if (new_margin < 75) {
st = 75 - new_margin;
//have container scroll by this much?
}
anim.animate({
marginTop: "+=" + new_margin
}, 1000);
});
http://jsfiddle.net/zYYBR/10/