├── LICENSE.txt ├── AnimateScroll.min.js ├── README.md ├── AnimateScroll.js └── demo └── index.html /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Sunmock Yang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /AnimateScroll.min.js: -------------------------------------------------------------------------------- 1 | // AnimateScroll.min.js 2 | // Sunmock Yang Nov. 2015 3 | function animateScroll(t,n,i,e,a,r){e=e?e:0;var o=document.documentElement,s=o.clientHeight,u="scrollMaxY"in window?window.scrollMaxY:o.scrollHeight-s,c=window.pageYOffset,l=c,h=isNaN(t)?t.getBoundingClientRect():0;"center"===a?(l+=isNaN(t)?h.top+h.height/2:t,l-=s/2,l-=e):"bottom"===a?(l+=h.bottom||t,l-=s,l+=e):(l+=h.top||t,l-=e),l=Math.max(Math.min(u,l),0);var d=l-c,f={targetY:l,deltaY:d,duration:n?n:0,easing:i in animateScroll.Easing?animateScroll.Easing[i]:animateScroll.Easing.linear,onFinish:r,startTime:Date.now(),lastY:c,step:animateScroll.step};window.requestAnimationFrame(f.step.bind(f))}animateScroll.Easing={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return t*(2-t)},easeInOutQuad:function(t){return.5>t?2*t*t:-1+(4-2*t)*t},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return--t*t*t+1},easeInOutCubic:function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return 1- --t*t*t*t},easeInOutQuart:function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return 1+--t*t*t*t*t},easeInOutQuint:function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t}},animateScroll.step=function(){if(this.lastY!==window.pageYOffset&&this.onFinish)return void this.onFinish();var t=Math.min((Date.now()-this.startTime)/this.duration,1),n=this.targetY-(1-this.easing(t))*this.deltaY;window.scrollTo(window.scrollX,n),1!==t?(this.lastY=window.pageYOffset,window.requestAnimationFrame(this.step.bind(this))):this.onFinish&&this.onFinish()}; 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AnimateScroll.js 2 | ===================== 3 | Lightweight javascript library to animate vertical scrolling to a specified element without jQuery. 4 | 5 | Click [here](http://sunmockyang.github.io/animate-scroll-js/demo) for a demo 6 | 7 | ## Usage 8 | ```javascript 9 | animateScroll(target, duration, easing, padding, align, onFinish) 10 | ``` 11 | - ```target``` Specifies the DOM element, or a page offset value (px) to scroll to 12 | - ```duration``` How long the scroll animation lasts in milliseconds. Default: 0. 13 | - ```easing``` Easing type for scroll animation. See below for options Default: linear. (string) 14 | - ```padding``` How much space in pixels from the top of the specified element to scroll to. Default: 0 15 | - ```align``` Can be set to `"top"`, `"center"`, `"bottom"` and scroll will animate to the target aligned as specified within the window. Default `"top"` (string) 16 | - ```onFinish``` Callback function to run when the animation is finished or cancelled. 17 | 18 | ## Easing 19 | The types of easing available. Easing functions taken from: https://gist.github.com/gre/1650294 20 | - ```"linear"``` 21 | - ```"easeInQuad"``` 22 | - ```"easeOutQuad"``` 23 | - ```"easeInOutQuad"``` 24 | - ```"easeInCubic"``` 25 | - ```"easeOutCubic"``` 26 | - ```"easeInOutCubic"``` 27 | - ```"easeInQuart"``` 28 | - ```"easeOutQuart"``` 29 | - ```"easeInOutQuart"``` 30 | - ```"easeInQuint"``` 31 | - ```"easeOutQuint"``` 32 | - ```"easeInOutQuint"``` 33 | 34 | ## Notes 35 | - If the user manually scrolls during the scroll animation, the animation will cancel and the onFinish function will run 36 | - Only the element argument is mandatory. Rest are optional with default values. 37 | - This was created after I couldn't find anywhere online a library that can scroll smoothly without jQuery 38 | - Currently if smooth-scrolling is enabled, it will interfere with the scroll animations. Disable smooth-scrolling while the animation is playing 39 | -------------------------------------------------------------------------------- /AnimateScroll.js: -------------------------------------------------------------------------------- 1 | // AnimateScroll.js 2 | // Sunmock Yang Nov. 2015 3 | 4 | function animateScroll(target, duration, easing, padding, align, onFinish) { 5 | padding = padding ? padding : 0; 6 | var docElem = document.documentElement; // to facilitate minification better 7 | var windowHeight = docElem.clientHeight; 8 | var maxScroll = ( 'scrollMaxY' in window ) ? window.scrollMaxY : (docElem.scrollHeight - windowHeight); 9 | var currentY = window.pageYOffset; 10 | 11 | var targetY = currentY; 12 | var elementBounds = isNaN(target) ? target.getBoundingClientRect() : 0; 13 | 14 | if (align === "center") { 15 | targetY += isNaN(target) ? (elementBounds.top + elementBounds.height/2) : target; 16 | targetY -= windowHeight / 2; 17 | targetY -= padding 18 | } 19 | else if (align === "bottom") { 20 | targetY += elementBounds.bottom || target; 21 | targetY -= windowHeight; 22 | targetY += padding 23 | } 24 | else { // top, undefined 25 | targetY += elementBounds.top || target; 26 | targetY -= padding 27 | } 28 | targetY = Math.max(Math.min(maxScroll, targetY), 0); 29 | 30 | var deltaY = targetY - currentY; 31 | 32 | var obj = { 33 | targetY: targetY, 34 | deltaY: deltaY, 35 | duration: (duration) ? duration : 0, 36 | easing: (easing in animateScroll.Easing) ? animateScroll.Easing[easing] : animateScroll.Easing.linear, 37 | onFinish: onFinish, 38 | startTime: Date.now(), 39 | lastY: currentY, 40 | step: animateScroll.step, 41 | }; 42 | 43 | window.requestAnimationFrame(obj.step.bind(obj)); 44 | } 45 | 46 | // Taken from gre/easing.js 47 | // https://gist.github.com/gre/1650294 48 | animateScroll.Easing = { 49 | linear: function (t) { return t }, 50 | easeInQuad: function (t) { return t*t }, 51 | easeOutQuad: function (t) { return t*(2-t) }, 52 | easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t }, 53 | easeInCubic: function (t) { return t*t*t }, 54 | easeOutCubic: function (t) { return (--t)*t*t+1 }, 55 | easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }, 56 | easeInQuart: function (t) { return t*t*t*t }, 57 | easeOutQuart: function (t) { return 1-(--t)*t*t*t }, 58 | easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t }, 59 | easeInQuint: function (t) { return t*t*t*t*t }, 60 | easeOutQuint: function (t) { return 1+(--t)*t*t*t*t }, 61 | easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t } 62 | }; 63 | 64 | animateScroll.step = function () { 65 | if (this.lastY !== window.pageYOffset) { 66 | this.onFinish && this.onFinish(); 67 | return; 68 | } 69 | 70 | // Calculate how much time has passed 71 | var t = Math.min((Date.now() - this.startTime) / this.duration, 1); 72 | 73 | // Scroll window amount determined by easing 74 | var y = this.targetY - ((1 - this.easing(t)) * (this.deltaY)); 75 | window.scrollTo(window.scrollX, y); 76 | 77 | // Continue animation as long as duration hasn't surpassed 78 | if (t !== 1) { 79 | this.lastY = window.pageYOffset; 80 | window.requestAnimationFrame(this.step.bind(this)); 81 | } else { 82 | if (this.onFinish) this.onFinish(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |Sunmock Yang, November 2015
40 | 41 |Click to scroll to any of these elements
78 | 79 | 155 | 156 | 157 | 158 | --------------------------------------------------------------------------------