I would like your suggestions here for the following points
Make peel effect more realistic if possible.
Reduce the size of the peel (to be able to see the full Ad).
Jsfiddle peel effect
I used a div pagePeelsmallrotate rotated at 24deg initially. Which i then animate its angle as well as dimensions .
Also div pagePeelcontainer dimensions are animated.
There are two functions
var pagePeelopen = function() {} /*opens the ad*/
var pagePeelclose = function() {} /*closes the ad */
I tried skewing only the pagePeelcontainer div and not its children to get small peel as provided here
css used to avoid child elements getting affected
#pagePeelcontainer > * {
transform:skew(-45deg);
}
But couldn't get the peel effect properly on click of open.
Jsfiddle skewed peel
Let me know how i can do it
Changing this section of code
$('#pagePeelcontainer').stop().animate({
width: 1000,
height: 1000
}, {
duration: 500
});
Will reveal the whole advert, as for the peeling it looks pretty good the way it is
Related
So I have two sections of content near the top of my page and I’d like for users who have scrolled down to near the top of the second section to get “scroll snapped” to the top of the second one once they have stopped scrolling.
I think it should be possible using jQuery but I haven’t been able to figure it out. Here are my examples:
Without my attempt: http://codepen.io/jifarris/pen/gaVgBp
With my broken attempt: http://codepen.io/jifarris/pen/gaVgQp
Basically I can’t figure out how to make it try scrolling to the spot only once, after scrolling has stopped. It’s kind of just freaking out.
I love how the recently introduced scroll snap points CSS feature handles scroll snapping and I’d almost prefer to use it – for the browsers that support it, at least – but it seems like it only works for items that take up 100% of the viewport height or width, and it seems like it’s for scrolling within an element, not the page itself.
The top section has a fixed height, so this really can be handled with pixel numbers.
And for reference, here’s the heart of the code from my attempt:
$(function() {
$(document).on('scroll', function() {
var top = $(document).scrollTop();
if (top > 255 && top < 455) {
$('html, body').animate({scrollTop: '356'}, 500);
$('body').addClass('hotzone');
} else {
$('body').removeClass('hotzone');
}
});
});
KQI's answer contains most of the steps required to create a well functioning section-scroll for use in your application/webpage.
However, if you'd just want to experiment yourself, developing your script further, the first thing you'll have to do is add a timeout handler. Otherwise your logic, and therefor scrollAnimation, will trigger every single pixel scrolled and create a buggy bouncing effect.
I have provided a working example based on your script here:
http://codepen.io/anon/pen/QjepRZ?editors=001
$(function() {
var timeout;
$(document).on('scroll', function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
var top = $(document).scrollTop();
if (top > 255 && top < 455) {
$('body').animate({
scrollTop: '356'
}, 500);
$('body').addClass('hotzone');
} else {
$('body').removeClass('hotzone');
}
}, 50);
});
});
Good luck!
All right, there are couple of things you gonna have to deal with to get a good result: which are performance, call stack queue, easing.
Performance wise you should drop jQuery animate and use VelocityJs which gives a smoother transition, better frame per second (fps) to avoid screen glitches especially on mobiles.
Call stack: you should wrap whatever logic you have to animate the scrolltop with 'debounce' function, set the delay for let say 500mm and check the scrolling behavior. Just so you know, the 'scroll' listener your using is firing on each pixel change and your script will go crazy and erratic. (It is just gonna be a moment of so many calc at the same time. Debounce will fix that for you)
Easing: make the transition looks cool not just dry snappy movement.
Remember, 'easing' with Velocity starts with 'mina.' i.e.
'Mina.easingFnName'
Finally, your logic could be right, i am in my phone now cannot debug it but try to simplify it and work with a single problem at once, be like i.e.
If ( top > 380 ) // debounce(...)
I have created a sliding image gallery and when the button is pushed it slides the picture across and updates the image attribute for the relevant sections.
However this works perfectly like 50% of the time. The other times there is a second glitch and the images then go in place as expected.
I have attached the javascript methods for the animate method and the array change method. I have looked elsewhere and cannot see anyone else with a similar issue or where I am going wrong, especially when it doesn't happen often.
imageGallery.leftSelect.onclick = function () {
window.setTimeout(imageGallery.rightClick, 250);
imageGallery.animateImages('.image1', '.imageRight');
imageGallery.animateImages('.imageRight', '.imageNoneRight');
imageGallery.animateImages('.imageLeft', '.image1');
imageGallery.animateImages('.imageNoneLeft', '.imageLeft');
};
animateImages: function (classFrom, classTo) {
var classMoving = $(classFrom);
var classGoingTo = $(classTo);
classMoving.animate({
top: classGoingTo.css('top'),
left: classGoingTo.css('left'),
width: classGoingTo.css('width'),
opacity: classGoingTo.css('opacity'),
}, 258, function () {
console.log('Animated');
classMoving.css({"width":'', "opacity":'', "top":'', "left":'', });
});
},
rightClick: function () {
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src', imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src', imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src', imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src', imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src', imageGallery.imagesDisplay[9]);
},
Can someone assist, I really need this to work?
If there is anything not clear or you need more code let me know.
Thanks,
First things first, the culprit was the setAttribute of all images i.e. whatever you were doing inside the rightClick and leftClick functions were the reasons why you were seeing a glitch. Changing src of an img tag produces the glitch.
But then we cannot simply remove it because your approach relies heavily on this swapping of images.
I had to breakdown and really understand your approach first. The way it worked was that you would animate, for example, image1 (the centered one) to move to the position of imageLeft upon click on the rightCarousel button. On that same click, you had a setTimeout of almost the duration of the animation to call rightClick function. This rightClick function then swaps the images so that image1 can always remain at the center and only images can come and go after animation. This was the problem.
What I had to change was that all image tags i.e. imageNoneLeft, imageLeft, image1, imageRight & imageNoneRight would change each others classes such that their position remains changed after animations.
Also, I had to add another animateImages line inside your leftSelect and rightSelect callbacks to animate the furthest images i.e. imageNoneLeft & imageNoneRight to animate to each other's positions with respect to the click of the buttons.
Take a look at this jsFiddle. It will help you understand a lot better. And let me know if you have any questions.
JavaScript:
var imageGallery={
prefix:'https://dl.dropboxusercontent.com/u/45891870/Experiments/StackOverflow/1.5/',
imagesDisplay:['JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg'],
rightSelect:document.querySelector('.rightCarousel'),
leftSelect:document.querySelector('.leftCarousel'),
imageMain:document.querySelector('.image1'),
imageLeft:document.querySelector('.imageLeft'),
imageRight:document.querySelector('.imageRight'),
imageNoneLeft:document.querySelector('.imageNoneLeft'),
imageNoneRight:document.querySelector('.imageNoneRight'),
init:function(){
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[9]);
},
animateImages:function(classFrom,classTo){
var classMoving=$(classFrom);
var classGoingTo=$(classTo);
classMoving.animate({
top:classGoingTo.css('top'),
left:classGoingTo.css('left'),
width:classGoingTo.css('width'),
opacity:classGoingTo.css('opacity')
},258,function(){
$(this).removeClass(classFrom.substr(1));
$(this).addClass(classTo.substr(1));
$(this).removeAttr('style');
});
}
};
imageGallery.init();
imageGallery.leftSelect.onclick=function(){
imageGallery.animateImages('.imageNoneRight','.imageNoneLeft');
imageGallery.animateImages('.imageRight','.imageNoneRight');
imageGallery.animateImages('.image1','.imageRight');
imageGallery.animateImages('.imageLeft','.image1');
imageGallery.animateImages('.imageNoneLeft','.imageLeft');
};
imageGallery.rightSelect.onclick=function(){
imageGallery.animateImages('.imageNoneLeft','.imageNoneRight');
imageGallery.animateImages('.imageLeft','.imageNoneLeft');
imageGallery.animateImages('.image1','.imageLeft');
imageGallery.animateImages('.imageRight','.image1');
imageGallery.animateImages('.imageNoneRight','.imageRight');
};
I'm creating a short game in Html5. I'm trying to figure out the best way to do the Hero selection.
Basically there are 113 heroes. I created a spritesheet that is 1320x1320 with each hero img being 120x120. The first picture is actually just a box that says 'Click to pick hero' in it.
My first question is, since it loads my spritesheet at the beginning to load the first image, later on when it loads the rest of the heroes it won't have to reload the image right? Because
setting 'heroPics[i].style.backgroundImage = "url(Heroes.jpg)";' each time makes me feel uneasy.
Second and important question to me. Back when I worked on games for mobiles, I found out that if you loaded an image that's 570 it'd use resources for a 1024x1024 and that it'd be better to remake the image to 512 and just scale it up, saving loads of resources. Is it the same here? My image being 1320 would it use resources as a 2048? Or since I'm loading images 120x120 it's only using resources for 128?
Now on to the real question. When the person clicks on 'Click to pick hero', I want all the hero images to appear. When they pick a hero I'd like to garbage all the variables and the div I just created, because they will not be picking a new hero too often, so it's better to garbage it, right? Or since the spritesheet is already loaded it's worth it to just hide the div containing the images instead? It'd still have all those variables loaded tho? Anyway that's one of my major question.
Second one is, how do I create a scrollbar inside a div dynamically? I believe I could do it if I set all the properties manually but I want to create tags and a search for the heroes, so the scrollbar has to adjust to whatever is currently being searched active, any advice on this one is greatly appreciated.
And last of all, is there a way to create the image at half it's size from the beginning? I tried .style.width = "50%" and height auto but it doesn't work since it's a spritesheet =(. So I use the webkit to scale down the div but I'd prefer another option if possible.
Thanks for reading this far and sorry for all the questions, here is what I've done so far:
function selectHero() {
var gg = 1;
var bg = 0;
for (var i = 1; i < 114; i++) {
heroPics[i] = new Image();
heroPics[i].style.backgroundImage = "url(newHeroes.jpg)";
heroPics[i].style.width = "120px";
heroPics[i].style.height = "120px";
heroPics[i].style.backgroundPosition = (-(120 * i)) + "px" + " " + (-((Math.floor(i / 11)) * 120)) + "px";
heroPics[i].style.position = "absolute";
heroPics[i].style.left = -90 + (75 * gg) + "px";
heroPics[i].style.top = -30 + (75 * bg) + "px";
heroPics[i].style.webkitTransform = 'scale(0.6, 0.6)';
heroPics[i].draggable = false;
someDiv.appendChild(heroPics[i]);
//heroPics[i].addEventListener( "click", heroChosen, false );
gg ++;
if(gg > 17) {
gg = 1;
bg ++;
}
}
}
I heard math.floor uses way too much resources, should I find a different solution even if it's uglier since right now it's calling math.floor 113 times? Thanks once again
Edit:
Found a solution to my last question about resizing images:
background-size = 792px 792px;
Just scaled 1320x1320 down by 60% in the css class and then changed the imgae size from 120 to 72 and it worked.
Also thanks for the useful tip of creating a class that holds the majority of the properties and using JS only when needed. Still need help with the scrollbar and a few others!
Basically there are 113 heroes. I created a spritesheet that is
1320x1320 with each hero img being 120x120. The first picture is
actually just a box that says 'Click to pick hero' in it. My first
question is, since it loads my spritesheet at the beginning to load
the first image, later on when it loads the rest of the heroes it
won't have to reload the image right? Because setting
'heroPics[i].style.backgroundImage = "url(Heroes.jpg)";' each time
makes me feel uneasy.
Yes, but you would probably be better off doing this via CSS.
Second and important question to me. Back when I worked on games for
mobiles, I found out that if you loaded an image that's 570 it'd use
resources for a 1024x1024 and that it'd be better to remake the image
to 512 and just scale it up, saving loads of resources. Is it the same
here? My image being 1320 would it use resources as a 2048? Or since
I'm loading images 120x120 it's only using resources for 128?
First I have heard of that, and it is likely to be browser dependent even if true. On second thought, I did hear that iOS had some issues with loading images that were beyond a certain size, but I'm not certain. The largest image I think I currently use is 1440x570 or so. I'd have to check the sprites, but most of them are much smaller.
Now on to the real question. When the person clicks on 'Click to pick
hero', I want all the hero images to appear. When they pick a hero I'd
like to garbage all the variables and the div I just created, because
they will not be picking a new hero too often, so it's better to
garbage it, right? Or since the spritesheet is already loaded it's
worth it to just hide the div containing the images instead? It'd
still have all those variables loaded tho? Anyway that's one of my
major question.
If you are doing filtering etc, you might try something like using classes on the children of your div. So you would have code like:
<div id="heroselection">
<div class="hero1 fighter male"></div>
<div class="hero2 wizard female"></div>
</div>
Then as you select filters, you can easily go through and hide the ones you don't need. First, hide them all. Then show the ones that match your filters, so if they checkbox "female" then your javascript (I'm using jQuery here, but feel free to pick another):
$('#heroselection > div').hide();
$('#hereselection > div.female').show();
Second one is, how do I create a scrollbar inside a div dynamically? I
believe I could do it if I set all the properties manually but I want
to create tags and a search for the heroes, so the scrollbar has to
adjust to whatever is currently being searched active, any advice on
this one is greatly appreciated.
Sounds like you want overflow:auto or perhaps overflow-y: auto on the div.
And last of all, is there a way to create the image at half it's size
from the beginning? I tried .style.width = "50%" and height auto but
it doesn't work since it's a spritesheet =(. So I use the webkit to
scale down the div but I'd prefer another option if possible.
Sounds like you are looking for background-size
you are creating too much properties using javascript better solution is to create one parent class with common properties and apply this class to all divs and modify remaining properties with Javascript.
#parent > div{
background:url('newHeroes.jpg');
width:120px;
height:120px;
}
If you are familiar with SASS style of writing CSS then you can write sass and compile to css for all child div elements
#for $i from 1 through 114 {
div:nth-child(#{$i}) {
/* example --width: 100% / #{$i}*/
}
}
Hello StackOverflow Community,
what I am trying to achieve is a header that can be moved with the mouse.
You klick into the header and drag the mouse and the elements inside the header will move with different speeds.
I achieved the parallaxing part but the performance is not really good. It is partially a bit laggy while dragging the backgrounds.
My question now is: what can be changed in the code to get a performance boost?
That's the part of the code that takes care of parallaxing. On every mousemove a each loop is executed which I think is the reason for the performance beeing so laggy:
var dragging = false;
var clickMouseX;
//Our object for the layers
//each layer has a different scrolling speed
var movingObjects = {
'#header-l1' : {'speed': 1},
'#header-l2' : {'speed': 1.4},
'#header-l3' : {'speed': 1.85},
'#header-l4' : {'speed': 2.2},
};
$('#header-wrapper').mousedown(function(e){
dragging = true;
//Get initial mouse position when clicked
clickMouseX = e.pageX;
$(this).mousemove(function(mme){
//execute only if mousedown
if(dragging){
//iterate through all layers which have to be parallaxed
$.each(movingObjects, function(el, opt){
var element = $(el);
//get difference of initial mouse position and current mouse position
var diff = clickMouseX - mme.pageX;
//scroll-position left speed 1
if(diff < 0) diff = -1;
//scroll position right speed 1
if(diff >= 0) diff = 1;
//get current position of layer
currLeft = parseInt(element.css('left'));
//get current layer width
elWidth = element.width();
//if right border is reached don't scroll further
if(currLeft < -(elWidth - 810)){
element.css('left', -(elWidth - 810));
}
//so do with left border
if(currLeft > 0){
element.css('left', 0);
}
//parallax it! Subtract the scroll position speed multiplied by the speed of the desired
//layer from the current left property
element.css('left', parseInt(element.css('left')) - diff*opt.speed);
});
}
});
/* Cursor */
$(this).css('cursor', 'pointer');
return false;
});
I also put a fiddle up:
http://jsfiddle.net/yWGDz/
Thanks in advance,
Thomas
P.S. maybe someone even finds out why layer two and three have the same scroll speed while having different speeds defined.
I worked at this a bit, and came up with this: http://jsfiddle.net/amqER/2/
This works a lot faster than the original (especially in firefox, where it performs a whole lot better, chrome it's still pretty slow). I also changed up some of the logic in your code, to make it make more sense.
A list of things that I did:
Minify your pngs
2 of your png files were over 2 megs, so I threw them into a png compressor (tinypng) and that reduced the size a lot. This helps with loading time and overall snappiness.
Re-use values as much as possible
In your original code, you wrote to and then subsequently read from the css left property a couple times in your code. Doing this is going to make it a lot slower. Instead, I kept an left property, and would only touch $.css when I absolutely needed to. Likewise for reading each element's width each update.
Also, like I said, I modified your logic to (I think) make more sense, given what you were trying to accomplish. It calculates a new diff each update, and tries to move according to that. Also, it doesn't try to keep moving once one of the images falls off (which yours does if you move all the way to the right, and it looks really weird). You can also look at this: http://jsfiddle.net/amqER/5/, which maybe is more like the control scheme you wanted.
Just some quick performance tips.
Try not to use $(this).mousemove instead save $(this) into a variable and use that.
var th = $(this);
th.mousemove...
Try to avoid using $.each. This is probably the part that's slowing your code down.
You can replace it with a for loop, but I would suggest, in this case, sending in each element one by one.
var parallax = function(img){
};
parallax(img1);
parallax(img2);
instantly-increase-your-jquery-performance
Whilst Xymostech's answer does greatly improve upon the original poster's original code; the performance is hardly improved for me in Chrome.
Whilst inspecting the page FPS, the solution posted here runs at 15FPS for me on a Retina MacBook Pro.
I made a very simple change to the code, altering it to use translate3d properties instead of left. Now, it runs at 55-60 FPS for me. I'd call that a massive performance boost.
If 'show paint rectangles' are turned on in Chrome, you'll see the previously posted solution is continually painting changes to the dom whilst the parallax is in motion. With the translate3d solution, there's simply zero painting done the whole time the parallax is in motion.
http://jsfiddle.net/LG47e/
I'm doing a page here with Twitter widgets on the side. Well I'm really a newbie in using this widget and I don't have a single idea on customizing it this is how far I've gone. First it will appear like this:
Names will appear one by one every 30 seconds from top going down background is transparent. Please disregard the borders (sorry I can't give a decent picture)
Well then What I wanted to do is for it to appear like this one:
Well from top to down it will become bottom to top displaying around 5 or 6 names and font is also adjusted smallest to biggest and positioned left and right alternating position.
Any Ideas? I would also appreciate if you could give me a little lesson here. :)
EDIT: I forgot HTML and I'm using a Javascript on this one.
for _slide looks like this:
_slide: function(el) {
var that = this;
var height = getFirst(el).offsetHeight;
if (this.runOnce) {
new Animate(el, 'height', {
from: 380,
to: height,
time: 500,
callback: function()
{
that._fade.call(that, el);
}
}
).start();
}
return this;
},
Thanks!
Okay as you cant give any indication as to which widget you're using is difficult to help you reverse the order of the <li>'s specific to your widget, but here's how youd do it using jquery:
output = '<ul id="after">';
$($("li").get().reverse()).each(function() {
output += '<li>'+$(this).text()+'</li>';
});
$('body').append(output+'</ul>');
$("#after li:even").css({"float":"left", "clear":"right"});
$("#after li:odd").css({"float":"right", "clear":"left"});
$("#after li:nth-child(2)").css({"width":"320px", "font-size":"90%"});
$("#after li:nth-child(3)").css({"width":"260px", "font-size":"80%"});
$("#after li:nth-child(4)").css({"width":"180px", "font-size":"70%"});
$("#after li:nth-child(5)").css({"width":"100px", "font-size":"60%"});
See the coded example here - http://jsfiddle.net/ajthomascouk/6MQew/1