can anybody help me understand how Honda achieved this effect:
http://testdays.hondamoto.ch/
I mean the ease when you scroll.
var $pages = $(".page"),
tot = $pages.length,
c = 0, pagePos = 0, down = 0, listen = true;
$('html, body').on('DOMMouseScroll mousewheel', function(e) {
e.preventDefault();
if(!listen)return;
listen = false;
down = e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0;
c = Math.min(Math.max(0, down ? ++c : --c), tot-1);
pagePos = $pages.eq(c).offset().top;
$(this).stop().animate({scrollTop: pagePos}, 650, function(){
listen = true;
});
});
*{margin:0;}
.page{min-height:100vh;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page" style="background:#0bf">PAGE 1</div>
<div class="page" style="background:#fb0">PAGE 2</div>
<div class="page" style="background:#0fb">PAGE 3</div>
<div class="page" style="background:#b0f">PAGE 4</div>
P.S:
Use .position().top; if your .pages are inside a scrollable DIV like $("#pagesParent") (instead of $('html, body'))
Notice:
for mobile you might want to adjust the value accounting for the browser's tabs bar height (or best, prevent that behaviour at all). You got the idea
Open up their JS file : http://testdays.hondamoto.ch/js/script_2.js
and search for Utils - Navigation
/***********************************************************************************************/
/************************************ Utils - Navigation *************************************/
/***********************************************************************************************/
/**
* navigation
*/
function navigation(target){
//--Init Quiz
if(!quizRdy){
hideQuiz();
}
//Add class to body
var pageName = target.substr(1).split('-');
$('body').removeClass(lastPage);
$('body').addClass(pageName[0]);
lastPage = pageName[0];
if(resizeBg)retractBg();
resizeBg = false;
busy = true;
$('body').addClass('loading');
//Change Nav Color
$('#nav-wrapper ul.nav li a').each(function(){
$(this).removeClass('selected');
});
var currentNavNumber = currentNav +1;
$('#main_nav_'+currentNavNumber).addClass('selected')
var wHeight = $(window).height();
if(wHeight<1080){
var newMargin = 180 - ( (wHeight - 720)/2 ) ;
if(newMargin<0) newMargin=180;
}else{
var newMargin =0 - (wHeight - 1080)/2;
}
var navTop = $(target).offset().top + newMargin;
navTop += 'px';
trace('navTop : '+navTop);
//$('#nav-wrapper').css('top',navTop);
$('html,body').stop().animate({
scrollTop: $(target).offset().top + newMargin
}, 1000,'easeInOutExpo',function(){
trace('annime done - wHeight : '+wHeight+' target top : '+$(target).offset().top);
if(currentNav==2 && !quizRdy && !quizForm){
showQuiz();
}
if(currentNav==4){
//update social datas
$.getJSON('inc/socials.php', function(data) {
$('#count-fans').empty().append(data['fans-count']);
$('#count-followers').empty().append(data['followers-count']);
});
}
/*
if(currentNav==2){
$('#quiz-nav').livequery(function(){
$(this).show();
});
}else{
$('#quiz-nav').livequery(function(){
$(this).hide();
});
}
*/
$('body').removeClass('loading');
if(currentNav!=0 && currentNav!=4){
$('#nav-wrapper').fadeIn(200);
}else{
$('#nav-wrapper').fadeOut(200);
}
if(currentNav==3){
//--Init Google Map
if(!mapReady){
if(dealerReady){
//init map
initialize();
}else{
askMap = true;
}
}
}
if(wHeight>1080){
extendBg();
}
busy = false;
});
}
/**
* navigation next Page
*/
function nextPage(){
if(currentNav<navArray.length-1 && !busy){
currentNav++;
navigation(navArray[currentNav]);
}
}
/**
* navigation previous Page
*/
function prevPage(){
if(currentNav>0 && !busy){
currentNav--;
navigation(navArray[currentNav]);
}
}
/**
* Center content
*/
function centerContent(){
if(!busy){
//--Retract Background if expended for big screen
if(resizeBg)retractBg();
var wHeight = $(window).height();
var wWidth = $(window).width();
var imgHeight = 0;
//--Test image width / Height and fill the screen
if(wWidth / wHeight > ratioImg ){
//trace('case1 - width : ' + wWidth + ' height : '+wHeight);
if(wHeight > 1080 || wWidth > 1900){
var newImgHeight = wWidth * 1080 / 1920;
$(".bg-image").each(function(){
$(this).css({
'height':newImgHeight+'px',
'width':'100%'
});
});
imgHeight = newImgHeight;
}else{
$(".bg-image").each(function(){
$(this).css({
'height':'1080px',
'width':'1900px'
});
});
imgHeight = 1080;
}
}else{
if(wHeight > 1080 || wWidth > 1900){
$(".bg-image").each(function(){
var newImgWidth = wHeight * 1920 / 1080;
$(this).css({
'height':wHeight+'px',
'width':newImgWidth+'px'
});
});
imgHeight = wHeight;
}else{
$(".bg-image").each(function(){
$(this).css({
'height':'1080px',
'width':'1900px'
});
});
imgHeight = 1080;
}
}
//--Fix height if window > img height
if(wHeight>imgHeight){
$(".bg-image").each(function(){
var newImgWidth = wHeight * 1920 / 1080;
$(this).css({
'height':wHeight+'px',
'width':newImgWidth+'px'
});
});
}
//--Center horizontal bkg image
if(wWidth<1900){
$(".bg-image").each(function(){
var marginCenter = (wWidth - 1900) / 2;
marginCenter = marginCenter * -1;
if($(this).width() > (wWidth + marginCenter)){
$(this).css({'margin-left':-marginCenter+'px'});
}
});
}
//--Scroll to the good position
if(wHeight<1080){
var newMargin = 180 - ( (wHeight - 720)/2 ) ;
if(newMargin<0) newMargin=180;
}else{
var newMargin =0 - (wHeight - 1080)/2;
}
var navTop =$(navArray[currentNav]).offset().top + newMargin;
navTop += 'px';
//$('#nav-wrapper').css('top',navTop);
//trace('Scrool to good position, then expend bg : ' + navArray[currentNav] + ' '+ $(navArray[currentNav]).offset().top);
$('html,body').stop().animate({
scrollTop: $(navArray[currentNav]).offset().top + newMargin
}, 1000,'easeInOutExpo',function(){
if(wHeight>1080){
extendBg();
}
});
}
}
/**
* Extend the background image for big screen ( > 1080 px )
*/
function extendBg(){
var hWin = $(window).height();
if(hWin > 1080){
//--Get & save current page Name
lastBg = navArray[currentNav].split('-');
lastBg = lastBg[0].substr(1);
lastheight = $('#bg-'+lastBg).height();
//--Calculate the position from top to set the scroll position
posToTop = (hWin - $('#bg-'+lastBg).height())/2;
posToTop = $('#bg-'+lastBg).offset().top - posToTop;
lastPosToTop = $('#bg-'+lastBg).offset().top;
//trace('posToTop setting : '+posToTop+' page : ' + lastBg);
//--Set boolean resize to true to call the retract BG
resizeBg = true;
$('#bg-'+lastBg).css({'z-index':2});
//--Test if it's first or last
if(currentNav != 0 && currentNav != (navArray.length-1)){
$('#bg-'+lastBg).animate({
height:hWin+'px',
top:posToTop+'px'
},600);
}else{
if(currentNav==0){
posToTop=0;
$('#bg-'+lastBg).animate({
height:hWin+'px',
top:0
},600);
}else{
posToTop=0;
$('#bg-'+lastBg).animate({
height:hWin+'px',
top:4320+'px'
},600);
}
}
//--Scroll to the bottom for credits page
if(currentNav==(navArray.length-1)){
$('html,body').stop().animate({
scrollTop: $(document).height()
}, 1000,'easeInOutExpo');
}
}
}
/**
* Retrac the background to normal
*/
function retractBg(){
var hWin = $(window).height();
if(resizeBg && lastheight>0 && lastBg!=""){
$('#bg-'+lastBg).css({'z-index':0});
//trace('posToTop callback : '+posToTop + ' lastBg : ' + lastBg + ' lastheight : ' +lastheight);
if(posToTop>0){
//trace('reset pos top : ' + posToTop);
$('#bg-'+lastBg).animate({
height:lastheight+'px',
top:lastPosToTop+'px'
},600)
}else{
$('#bg-'+lastBg).animate({
height:lastheight+'px'
},600)
}
}
}
Related
I've created the following functionality where an image is fixed on the left while scrolling the content and the quote appears for a few pixels.
It's working all right, the only problem is that I'd like to add this many times on the same page and, as it is, it just works with the first image.
The second one is not fixed while scrolling and the quote maintains hidden...
How can I make run this function for every image?
This is a working example
HTML:
<section id="cont_quote" class="maxwidth">
<article class="cont_q hasImage">
<p>Content</p>
<img class="alignleft img_quote" src="/large.jpg" alt="" width="433" height="553" />
<blockquote>
<h3>Why this training plan works</h3>
</blockquote>
<p>Content</p>
</article>
</section>
JS:
// Stick image on scroll
$(window).on('load resize', function () {
if ($(window).width() >= 769) {
var $element = $('#cont_quote');
var $follow = $element.find('.img_quote');
var followHeight = $element.find('.img_quote').outerHeight();
var height = $element.outerHeight() - 300;
var window_height = $(window).height();
$(window).scroll(function () {
var pos = $(window).scrollTop();
var top = $element.offset().top;
// Check if element is above or totally below viewport
if (top + height - followHeight < pos || top > pos + window_height) {
return;
}
var offset = parseInt($(window).scrollTop() - top);
if (offset > 0) {
$follow.css('transform', 'translateY('+ offset +'px)');
}
})
}
});
// Quote show on viewport
function inViewport( element, viewport = { top: 0, bottom: innerHeight } ){
// Get the elements position relative to the viewport
var bb = element.getBoundingClientRect();
// Check if the element is outside the viewport
// Then invert the returned value because you want to know the opposite
return !(bb.top > viewport.bottom || bb.bottom < viewport.top);
}
var myViewport = { top: innerHeight * .5, bottom: innerHeight * .6 };
var myElement = document.querySelector( '#cont_quote blockquote' );
// Listen for the scroll event
document.addEventListener( 'scroll', event => {
// Check the viewport status
if( $(window).width() >= 600 ){
if( inViewport( myElement, myViewport ) && $('.cont_q').hasClass('hasImage') ) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-25%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '-5%';
}
} else if( inViewport( myElement, myViewport )) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-15%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '13%';
}
} else {
myElement.style.opacity = 0;
myElement.style.left = '-40%';
}
} else {
myElement.style.opacity = 1;
myElement.style.left = '5%';
}
});
Trying to initiate FullPage.JS after scrolling through hero. Right now if you scroll past the hero - FullPage gets initialized and continues to scroll through the slides with the momentum of the initial scroll. I have this function inplace for my init.
function initFullPage(){
$(".view-case-study").addClass("projects-load");
$(".pagination").addClass("visible");
$(".logo-menu svg").toggleClass("hovered");
$('#fullpage').fullpage({
lazyLoading:false,
navigation: true,
navigationPosition: 'right',
css3:true,
normalScrollElementTouchThreshold: 5,
touchSensitivity: 10,
anchors: a_anchors,
menu: '#myMenu',
normalScrollElements: '.nav, .open-nav, .project-inner, .work-mode, .menu-shelf, .tab, .view-case-study, #hero, .hero-center-container',
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
projectUrl = loadedSection.data('url');
project_title = loadedSection.data('title');
loadedSection.addClass('projects-load');
loadedSection.find(".full-line").animate({'width':'100%'},500);
loadedSection.animate({'background-position-y':'-20px','background-size':'120%'},1000);
$('#hero').animate({'opacity':'0'},1000);
$('#hero').addClass('destroy');
$('.ui-info').animate({'opacity':'1'},350);
},
onLeave: function(index, nextIndex, direction){
var leavingSection = $(this);
leavingSection.removeClass('projects-load');
leavingSection.find(".full-line").animate({'width':'0%'},250);
leavingSection.animate({'background-position-y':'0px','background-size':'110%'},100);
$('#project-inner-container').animate({scrollTop:0},0);
$('.ui-info').animate({'opacity':'0'},0);
}
});
fullPageInit = true;
}
Below is my Hero scroll script. I've tried to initialize the script and silentmove to the first section but it doesn't want to listen.
var winHeight = $(window).height();
$(window).scroll(function () {
var scrTop = $(document).scrollTop() / winHeight,
scrTopFixed = scrTop.toFixed(2),
scrTransform = scrTopFixed * 80,
bgPos = scrTransform / 10 + 95,
heroOpacity = 1 - scrTransform / 100;
if ((scrTransform >= 80) && (fullPageInit == false)) {
initFullPage();
$.fn.fullpage.silentMoveTo('#sidepocket');
}
$('svg.scroll-end').css({
'clip': "rect(0px," + scrTransform + "px,200px,0px)",
});
}); // Close
// Scroll SVG Hero
$('#scroll-control').on('scroll',function(e){
var totalScroll = $('#scroll-control').scrollTop();
var slowScroll = totalScroll * .2;
console.log(slowScroll);
$('svg.scroll-end').css({
'clip': "rect(0px," + slowScroll + "px,200px,0px)",
});
if(totalScroll > 400){
if((fullPageInit == false) && (workPage == false)){
fullPageInit = true;
$('#hero').animate({'opacity':'0'},300,function(){
// remove scroll listener
$('#scroll-control').off();
// set first project DOM
var wh = window.innerHeight ? window.innerHeight:$(window).height();
$('#fullpage section').height(wh);
var loadedSection = $('#fullpage section:first-child');
projectUrl = loadedSection.data('url');
project_title = loadedSection.data('title');
loadedSection.addClass('projects-load');
loadedSection.find(".full-line").animate({'width':'100%'},500);
history.pushState(null, null, '#'+projectUrl);
loadedSection.animate({'background-position-y':'-20px','background-size':'120%'},1000,function(){
initFullPage();
$('#scroll-control').hide();
});
$('.ui-info').animate({'opacity':'1'},350);
});
$('#hero').addClass('destroy');
}
}
});
var winHeight = $(window).height();
$(window).scroll(function (e) {
console.log(e);
var scrTop = $(document).scrollTop() / winHeight,
scrTopFixed = scrTop.toFixed(2),
scrTransform = scrTopFixed * 80,
bgPos = scrTransform / 10 + 95,
heroOpacity = 1 - scrTransform / 100;
if ((scrTransform >= 80) && (fullPageInit === false)) {
}
}); // Close
The issue was fixed by setting a time out so that FullPage doesn't initialize until the scrolling of the mouse ends, therefore you do not overscroll or have any momentum that forces the user to the next section.
Hope this helps others trying to build custom scripts into FullPage.JS
https://www.alexcoven.com
Currently I have a script which starts a progress bar the moment a user starts scrolling.
Is it possible to change this to when the user gets to 340px from the top of the page?
Here is a demo of my site: http://pixsols.com/test/wordpress/reading-progress/
Here is my current code:
(function ( $ ) {
$.fn.progressScroll = function(options) {
var settings = $.extend({
fontSize : 20,
color : '#009ACF',
height : '5px',
textArea : 'dark',
}, options);
// element state info
var docOffset = $(this).offset().top,
elmHeight = $(this).height(),
winHeight = $(window).height();
// listen for scroll changes
$(window).on('scroll', function() {
var docScroll = $(window).scrollTop(),
windowOffset = docOffset - docScroll,
viewedPortion = winHeight + docScroll - docOffset;
if($(window).scrollTop() > 0) {
if($('.scrollWrapper').hasClass('hidden')) {
$('.scrollWrapper').removeClass('hidden').hide();
$('.scrollWrapper').slideDown('slow');
}
} else {
$('.scrollWrapper').slideUp('slow');
$('.scrollWrapper').addClass('hidden');
}
if(viewedPortion < 0) { viewedPortion = 0; }
if(viewedPortion > elmHeight) { viewedPortion = elmHeight; }
// calculate viewed percentage
var viewedPercentage = viewedPortion / elmHeight;
// set percent in progress element
$('.scroll-bar').css('width', (viewedPercentage*100)+'%' );
});
var self = this;
$(window).on('resize', function() {
docOffset = $(self).offset().top;
elmHeight = $(self).height();
winHeight = $(window).height();
$(window).trigger('scroll');
});
$(window).trigger('scroll');
var $el = $('.scroll-bar').css(settings);
return $el;
};
}( jQuery ));
My guess would be to manipulate this:
windowOffset = docOffset - docScroll,
Probably you should add or subtract 320px from windowOffset. So for example"
windowOffset = docOffset - docScroll + 320,
I did jquery slider using this tutorial
http://css-plus.com/2010/09/create-your-own-jquery-image-slider/
, where the pictures are sliding automatically, but just once. How can I make them circle in an infinite loop?
on-line example :
www.vytvarkajablonec.jecool.net/ati
I'd really appreciate your help!
Replace the JS code from tutorial for this:
$(document).ready(function () {
// Gallery
if (jQuery("#gallery").length) {
// Declare variables
var totalImages = jQuery("#gallery > li").length,
imageWidth = jQuery("#gallery > li:first").outerWidth(true),
totalWidth = imageWidth * totalImages,
visibleImages = Math.round(jQuery("#gallery-wrap").width() / imageWidth),
visibleWidth = visibleImages * imageWidth,
stopPosition = (visibleWidth - totalWidth);
jQuery("#gallery").width(totalWidth);
jQuery("#gallery-prev").click(function () {
if (jQuery("#gallery").position().left < 0 && !jQuery("#gallery").is(":animated")) {
jQuery("#gallery").animate({
left: "+=" + imageWidth + "px"
});
}
if (jQuery("#gallery").position().left === 0) {
jQuery("#gallery > li:last").prependTo($("#gallery"));
}
return false;
});
jQuery("#gallery-next").click(function () {
if (jQuery("#gallery").position().left > stopPosition && !jQuery("#gallery").is(":animated")) {
jQuery("#gallery").animate({
left: "-=" + imageWidth + "px"
});
}
if (jQuery("#gallery").position().left === stopPosition) {
jQuery("#gallery > li:first").appendTo($("#gallery"));
}
return false;
});
}
});
Just animate the gallary back to it's initial position if it is at the end of the gallary.
var oGallary = $('#gallery');
var gallarWidth = oGallary.width();
if(oGalary.position().left > stopPosition && oGallary.is(":animated") == false)
{
oGallary.animate({left : "-=" + imageWidth + "px"});
}
else if ( oGalary.position().left <= stopPosition && oGallary.is(":animated") == false )
{
oGallary.animate({left : "+=" + gallaryWidht + "px"}) // Get full length of the entire gallary
}
I have images that will be quite big in dimension and I want to shrink them down with jQuery while keeping the proportions constrained, i.e. the same aspect ratio.
Can someone point me to some code, or explain the logic?
(function($){
$.fn.swipeGallery = function(options) {
var settings = {
'classname' : 'appGallery',
'autoHeight' : false,
'height' : '100',
'width' : '100',
'background' : '#000000',
'tolerance' : 0.25,
'delay' : 300
}
var ratio = 0;
var mousedown = false;
var mouseX = 0;
var imagesLength = 0;
var imagesCurrent = 0;
var xdiff = 0;
var containerHeight = 0;
var containerWidth = 0;
function doResizeImage(listElement){
$(listElement).css('height', containerHeight);
$(listElement).css('width', containerWidth);
var img = $(listElement).find('img');
if (img.width() / containerWidth > img.height() / containerHeight){
img.width(containerWidth);
var top = (containerHeight - img.height())/2;
img.css('marginTop', top + 'ratio');
}else{
img.height(containerHeight);
var left = parseInt((containerWidth - img.width())/2);
img.css('marginLeft', left + 'ratio');
}
}
function init(obj, parent, imageHandler){
if(settings.autoHeight){
containerHeight = $(window).height();
containerWidth = $(window).width();
}else{
containerHeight = parseInt(settings.height);
containerWidth = parseInt(settings.width);
}
obj.find('li').each(function(){
doResizeImage(this);
imagesLength++;
})
parent.css('height', containerHeight);
parent.css('width', containerWidth);
imageHandler.css('width', containerWidth);
imageHandler.css('height', containerHeight);
imageHandler.css('left', parent.position().left);
imageHandler.css('top', parent.position().top);
obj.css('width', imagesLength * containerWidth);
}
return this.each(function(){
var _this = $(this);
if(options) {
$.extend(settings, options);
}
if(settings.autoHeight){
containerHeight = $(window).height();
containerWidth = $(window).width();
}else{
containerHeight = parseInt(settings.height);
containerWidth = parseInt(settings.width);
}
_this.wrap('<div class="' + settings.classname + '"/>');
var parent = _this.parent();
parent.css('backgroundColor', settings.background);
parent.prepend('<div class="imageHandler"/>');
var imageHandler = _this.parent().find('.imageHandler');
init(_this, parent, imageHandler);
$(window).resize(function(){
init(_this, parent, imageHandler);
})
imageHandler.mousedown(function(event){
if(!this.mousedown){
this.mousedown = true;
this.mouseX = event.pageX;
}
return false;
});
imageHandler.mousemove(function(event){
if(this.mousedown){
xdiff = event.pageX - this.mouseX;
_this.css('left', -imagesCurrent * containerWidth + xdiff);
}
return false;
});
imageHandler.mouseup(function(event){
this.mousedown = false;
if(!xdiff) return false;
var fullWidth = parseInt(settings.width);
var halfWidth = fullWidth/2;
if(-xdiff > halfWidth - fullWidth * settings.tolerance){
imagesCurrent++;
imagesCurrent = imagesCurrent >= imagesLength ? imagesLength-1 : imagesCurrent;
_this.animate({left: -imagesCurrent * containerWidth}, settings.delay);
}else if(xdiff > halfWidth - fullWidth * settings.tolerance){
imagesCurrent--;
imagesCurrent = imagesCurrent < 0 ? 0 : imagesCurrent;
_this.animate({left: -imagesCurrent * containerWidth}, settings.delay);
}else{
_this.animate({left: -imagesCurrent * containerWidth}, settings.delay);
}
xdiff = 0;
return false;
});
imageHandler.mouseleave(function(event){
imageHandler.mouseup();
})
});
};
})(jQuery);
Try this simple function i mentioned here: https://stackoverflow.com/a/14731922/382536
/**
* Conserve aspect ratio of the orignal region. Useful when shrinking/enlarging
* images to fit into a certain area.
*
* #param {Number} srcWidth Source area width
* #param {Number} srcHeight Source area height
* #param {Number} maxWidth Fittable area maximum available width
* #param {Number} maxHeight Fittable area maximum available height
* #return {Object} { width, heigth }
*/
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth*ratio, height: srcHeight*ratio };
}