Create snowflakes in jquery - javascript

I create the snowflake using jquery. Everything seems ok but i want to do alert option when you click particular flake then it should alert the message. But i implemented the click function that alert option is continuously triggering. I am not sure where i did mistake. I tried the preventDefault still nothing happens.
http://jsfiddle.net/vicky081/4cZdu/12/
function snowFalling(){
// move the snow
$('.snow').each(function(key, value){
// check if the snow has reached the bottom of the screen
if( parseInt($(this).css('top')) > windowHeight - 80 ) {
// remove the snow from the HTML DOM structure
$(this).remove();
}
// set up a random speed
var fallingSpeed = Math.floor(Math.random() * 5 + 1);
// set up a random direction for the snow to move
var movingDirection = Math.floor(Math.random()*2);
// get the snow's current top
var currentTop = parseInt($(this).css('top'));
// get the snow's current top
var currentLeft = parseInt($(this).css('left'));
// set the snow's new top
$(this).css('top', currentTop + fallingSpeed );
// check if the snow should move to left or move to right
if( movingDirection === 0){
// set the snow move to right
$(this).css('left', currentLeft + fallingSpeed );
}else {
// set the snow move to left
$(this).css('left', currentLeft + -(fallingSpeed) );
}
});
jQuery(this).click(function() {
alert('You Clicked');
});
// repeat the rollIt() function for each 200 microseconds
window.setTimeout(snowFalling, 200);
}
// call the function when the document is loaded completely
generateSnow();
snowFalling();
});
Now i want to alert particular click. How to prevent multi alert on click the snow flakes.
Thanks.

If you only want the alert to occur when snow is clicked, move the handler to the point where the snowflake is created, not when it us updated, as you currently have it.
$('<div />')
.addClass('snow')
.css('top', snowTop)
.css('left', snowLeft)
.css('position','absolute')
.html('*')
.click(function() {
alert('You Clicked');
})
);
jsFiddle

You're binding a click handler every 200 ms on each snowflake element.
It looks like generateSnow() would be a good place to bind your click handler instead.
You could also use event delegation and bind on DOM ready:
$(document).on('click', '.snow', function() {
alert('You clicked');
});

Just move the click handler to outside your snowFalling function, after you generate your snowflakes:
JSFiddle
// this function is to alter the top of each snow, using the handy .each() jQuery method
function snowFalling(){
// move the snow
$('.snow').each(function(key, value){
// check if the snow has reached the bottom of the screen
if( parseInt($(this).css('top')) > windowHeight - 80 ) {
// remove the snow from the HTML DOM structure
$(this).remove();
}
// set up a random speed
var fallingSpeed = Math.floor(Math.random() * 5 + 1);
// set up a random direction for the snow to move
var movingDirection = Math.floor(Math.random()*2);
// get the snow's current top
var currentTop = parseInt($(this).css('top'));
// get the snow's current top
var currentLeft = parseInt($(this).css('left'));
// set the snow's new top
$(this).css('top', currentTop + fallingSpeed );
// check if the snow should move to left or move to right
if( movingDirection === 0){
// set the snow move to right
$(this).css('left', currentLeft + fallingSpeed );
}else {
// set the snow move to left
$(this).css('left', currentLeft + -(fallingSpeed) );
}
});
// repeat the rollIt() function for each 200 microseconds
window.setTimeout(snowFalling, 200);
}
// call the function when the document is loaded completely
generateSnow();
snowFalling();
$('.snow').click(function() {
alert('You Clicked');
});

Related

How to make jquery setinterval movement in mobile smoother?

Sorry for bad english.
Here's link to site.
My task is to create site with no scroll. When user clicks to right part of screen car starts to move forward. When it reaches middle of screen - car stops and fixed content-block starts to move in opossite direction. if user moves cursor to left side of screen (while holding mouse button clicked) car should move backward.
Desktop version works as expected. But mobile version is slow. (it's not exactly slow, it's not as smooth as desktop i guess)
What can i do fix this problem?
On touchstart event i get event.pageX value to check what part of screen user touched. (so i would know what direction car should move) and store this value in variable "mousePos". Then i call setInterval with movement function
On touchend event i clear interval to stop car from moving.
On touchmove i will rewrite "mousePos" var with new event.pageX value. For example: user clicked, car starts to move, if user moved cursor to left i will use this var to check direction and turn car back.
In mouseMove function i will check car position and decide what action should be done - either move car or move background and i'll check if it reached start of end points
events:
$(document).on('mousedown touchstart', '.mouse-click', function(event){
clicking = true;
mousePos = event.pageX;
if ( event.target.className == 'helper' ) {
showModal();
} else {
moveStuff = setInterval(mouseMove, 1);
}
});
$(document).on('mouseup touchend', function(){
clicking = false;
carLights.removeClass('blink');
clearInterval(moveStuff);
})
$(document).on('mousemove touchmove', '.mouse-click', function(event){
if(clicking == false) {
return;
} else {
mousePos = event.pageX;
}
});
function:
function mouseMove() {
let offset = parseInt( mainContent.css('left') );
let offsetCar = parseInt( car.css('left') );
if ( mousePos > middleScreen ) {
carLights.removeClass('blink');
if ( offset < - ( contentWidth ) ) {
return;
} else {
rotateWheelsForward();
if ( offsetCar < middleScreen ) {
car.css('left', (offsetCar + mouseSpeed) + 'px');
} else {
mainContent.css('left', (offset - mouseSpeed) + 'px');
}
}
} else if ( mousePos < middleScreen ) {
carLights.addClass('blink');
if ( offset > 0 ) {
carLights.removeClass('blink');
return;
} else {
rotateWheelsBackward();
if ( offsetCar > minCarLeft ) {
car.css('left', (offsetCar - mouseSpeed) + 'px');
} else {
mainContent.css('left', (offset + mouseSpeed) + 'px');
}
}
}
}
So how can i make movement smoother in mobile? (i use iphone 5s safari, but tested in iphone 6, still works bad)
What changes should i implement to this code?
I suggest to use transform rather than position eg: left, top cause thats really affect layer reflow-repaint. Use requestAnimationFrame (wisely) to perform smooth event animation like scroll, mouseup, or any other event.
Then use will-change: transform; to element which will "transformed" on the future. This will creates new layer and prepare for the element changes later.
In my case, relative position impact reflow or green flash on the rendering tool chrome. So I prefer use fixed/absolute position to prevent this.
Here's some great article for you to get Leaner, Meaner, Faster Animations with requestAnimationFrame and how to achieving 60 fps animations with css
Hope this help ;)

Adjust the scrolling speed when scrolling by dragging

I have a page on a website i am working on, that includes many images in a div in a grid (map). I made the div show a scroll bar at overflow and used jquery to enable scrolling via dragging and it works as intented with only a hundred or so showing at a time.
My only issue is, that since there are thousands of small images, moving the mouse only a bit will already result in blowing past a lot of objects.
My question now is, how can i modify my code, so that moving the mouse over the screen once will only scroll about one tenth of the div's width. So basically i want to reduce the scrolling speed.
I am super new to javascript etc. so please be patient.
<div id="map" class="center unselectable overflow">
lots of images here in a grid</div>
<script>
var clicked = false, clickY, clickX;
var map = document.getElementById('map');
$(document).on({
'mousemove': function(e) {
clicked && updateScrollPos(e);
},
'mousedown': function(e) {
clicked = true;
clickY = e.pageY;
clickX = e.pageX;
},
'mouseup': function() {
clicked = false;
$('html').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$('html').css('cursor', 'row-resize');
$(map).scrollTop($(map).scrollTop() + (clickY - e.pageY));
$(map).scrollLeft($(map).scrollLeft() + (clickX - e.pageX));
}
</script>
TLDR: how to I reduce the drag to scroll speed in jQuery?
A little more elabouration from my comment: it seems like you are trying to dampen the scrolling speed. Mathematically, this means all you need is to reduce the value you feed to the .scrollTop() and .scrollLeft() functions. This can be done by dividing them by a set, arbitrarily determined factor, so that the transformation is linear. An example will be, if you want to dampen your scrolling speed by a factor of 10×, then you simply divide the values by 10:
var updateScrollPos = function(e) {
var scrollTop = $(map).scrollTop() + (clickY - e.pageY);
var scrollLeft = $(map).scrollLeft() + (clickX - e.pageX);
$('html').css('cursor', 'row-resize');
$(map).scrollTop(scrollTop / 10);
$(map).scrollLeft(scrollLeft / 10);
}
Pro-tip: since you are accessing $(map) several times, you can (micro)optimize your code by caching it:
var updateScrollPos = function(e) {
var $map = $(map);
var scrollTop = $map.scrollTop() + (clickY - e.pageY);
var scrollLeft = $map.scrollLeft() + (clickX - e.pageX);
$('html').css('cursor', 'row-resize');
$map.scrollTop(scrollTop / 10);
$map.scrollLeft(scrollLeft / 10);
}

Javascript .on function runs for all values a string variable has had, instead of only its current value

I'm using Packery JS to create a card lay-out. In this lay-out I move things around using the fit method. When the moving is finished I then scroll to the moved div; I wait for the fit complete event and then use jQuery's scrolltop to scroll to the div in question. This is the code I currently use for the scrolling part:
$container.packery( 'on', 'fitComplete', function () {
$('html,body').animate({
scrollTop: $("#" + moveItem).offset().top - 40
});
console.log("scroll to: " + moveItem + ", position: " +($("#"+moveItem).offset().top - 40))
});
On the first click this works as intended, this is the output of moving div#vision:
scroll to: vision, position: 69
But on the second click (moving div#project-6) it goes wrong:
scroll to: project-6, position: 616
scroll to: vision, position: 69
It first scrolls to project-6, but then immediately goes to the previous value of moveItem, vision. On subsequent clicks the list only gets longer.
So my question: Why is it remembering the previous values of the moveItem variable? And how can I stop it from doing that?
For context, this is the website I'm using it on. The code in question can be found by searching for "//Move function".
Thanks in advance!
This happens when you execute $container.packery( 'on', ...); several times. My guess is that you attach another event handler every time you click the button instead of attaching it once in the setup of the page and then make sure the event is triggered when the button is clicked.
I will be more specific. Change this function to this:
//Move Function
var moveThis = function(moveItem, moveTarget){
if (moveTarget == "stamp" && $("#" + moveItem).hasClass("w2") && 720 < window.innerWidth && window.innerWidth < 992) {
var targetX = 0;
var targetY = $("#stamp").height() + 40;
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
} else if (moveTarget == "stamp") {
var arrayList = $container.packery('getItemElements')
var targetX = $(arrayList[0]).position().left
var targetY = $(arrayList[0]).position().top
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
} else {
var arrayList = $container.packery('getItemElements')
positionList = arrayList.indexOf(document.getElementById(moveTarget))
var targetX = $(arrayList[positionList+1]).position().left
var targetY = $(arrayList[positionList+1]).position().top
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
}
};
this code must be out of function, somewhere globally defined:
$container.packery( 'on', 'fitComplete', function ( moveItem ) {
$('html,body').animate({
scrollTop: $("#" + $(moveItem.element).attr('id')).offset().top - 40
});
console.log("scroll to: " + $(moveItem.element).attr('id') + ", position: " +($("#"+moveItem).offset().top - 40))
});
I'm not sure about $(moveItem.element).attr('id') - for this look at console what it has

Prepending content

What is the best way to repeat the content in this slideshow, so when you click .left and the carousal starts moving, you get a neverending loop? At the moment, if you click .left, the carousal starts moving and leaves behind empty space.
http://jsfiddle.net/tmyie/mZRQx/1/
var loop;
var moveRight = function(){
$('.box').animate({left: '-=10'}, 100);
};
var moveLeft = function(){
$('.box').animate({left: '+=10'}, 100);
};
$('.right').mousedown(function(){
loop = setInterval(moveRight, 200);
}).mouseup(function(){
clearInterval(loop);
});
$('.left').mousedown(function(){
loop = setInterval(moveLeft, 200);
}).mouseup(function(){
clearInterval(loop);
});
Any help would be great.
Here's a demo for your 'left' movement (though I think you got directions confused):
var moveLeft = function(){
$('.box').animate({left: '+=10'}, 100, function(){
var $last = $('.box').last();
if ($last.css('left') == '100px') {
$last.prependTo('.container').before('\n\r');
$('.box').css('left','0px');
}
});
};
It checks whether elements shifted by 100px and if so - moves the last element before first. Note I am also adding CrLf there to keep original formatting and distance between the DIVs (remove it if u don't need it).
"Left" Demo: http://jsfiddle.net/mZRQx/3/

deactivate button on gallery slider

I'm am trying to make my javascript/jquery slider button deactivated when it reaches the the end of the scrolling images( when the images have moved all the way to the right, the MoveRight button must be deactivated and only leave MoveLeft button active, same for the move LeftButton), can anybody help with this ? Im not sure if im using
.attr() and removeAttr() correctly. I have pasted my code below.
<script type="text/javascript">
$(document).ready(function(){
//Check width of Gallery div
var galleryWidth = $("#Gallery").innerWidth();
//Check width of GalleryItem
var NoListed = $("ul.GalleryItem li").length;
var galleryItemWidth = 1881;
$('.MoveRight')
$('.GalleryItem').css('width', galleryItemWidth);
//Check width of Gallery div on resize
$(window).resize(function(){
var galleryWidth = $("#Gallery").innerWidth();
});
$('.MoveLeft').click(function() {
$(".GalleryItem2").animate({"left": "-=350px"}, "slow");
$(".GalleryItem3").animate({"left": "-=280px"}, "slow");
$(".GalleryItem").animate({
left: '-=230',
}, "slow", function() {
position = $(".GalleryItem").position();
galleryItemLeft = position.left;
if(galleryItemLeft <= galleryWidth - galleryItemWidth) {
$('.MoveLeft').removeAttr('disabled');}
else{
$('.MoveLeft').attr('disabled','disabled');
$('.MoveRight').attr('disabled','disabled');
}
});
});
$('.MoveRight').click(function() {
$(".GalleryItem2").animate({"left": "+=350px"}, "slow");
$(".GalleryItem3").animate({"left": "+=280px"}, "slow");
$(".GalleryItem").animate({
left: '+=230',
}, "slow", function() {
position = $(".GalleryItem").position();
galleryItemLeft = position.left;
if(galleryItemLeft >= "0") {
$('.MoveLeft').removeAttr('disabled');}
else{
$('.MoveLeft').attr('disabled','disabled');
$('.MoveRight').attr('disabled','disabled');
}
});
});
});
</script>
first of all, I see you doing the following:
//Check width of Gallery div on resize
$(window).resize(function(){
var galleryWidth = $("#Gallery").innerWidth();
});
I like the fact that you keep your variables local, but the var keyword should be omitted in this case. You've declared galleryWidth already in the function that encloses this resize callback, so by omitting the var keyword here, the value will be assigned to the variable you use in your script, with this va keyword, you create a new galleryWidth variable, only visible in the resize callback, and therefore never used.
now for the enabling and disabling of the buttons:
you could keep a currentitem counter, and update it every time the moveright or moveleft buttons are clikced. When this counter reaches 0, you disable the moveleft button, when it reaches the number of items, you disable the moveright button, and enable them otherwise.

Categories