├── demo ├── CNAME ├── img │ ├── pic1.jpg │ ├── pic2.jpg │ ├── pic3.jpg │ ├── pic4.jpg │ ├── pic1_bigger.jpg │ ├── pic2_bigger.jpg │ └── pic3_bigger.jpg ├── js │ ├── .DS_Store │ ├── demo.js │ ├── demo.min.js │ ├── jquery.parallax-scroll.min.js │ └── jquery.parallax-scroll.js ├── css │ ├── .DS_Store │ ├── normalize.min.css │ └── demo.css └── index.html ├── .gitignore ├── .travis.yml ├── .jshintrc ├── package.json ├── .editorconfig ├── .csslintrc ├── bower.json ├── parallax-scroll.jquery.json ├── LICENSE ├── dist ├── jquery.parallax-scroll.min.js └── jquery.parallax-scroll.js ├── Gruntfile.js ├── README.md └── src └── jquery.parallax-scroll.js /demo/CNAME: -------------------------------------------------------------------------------- 1 | parallax-scroll.aenism.com -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | install: 5 | - npm install -------------------------------------------------------------------------------- /demo/img/pic1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic1.jpg -------------------------------------------------------------------------------- /demo/img/pic2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic2.jpg -------------------------------------------------------------------------------- /demo/img/pic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic3.jpg -------------------------------------------------------------------------------- /demo/img/pic4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic4.jpg -------------------------------------------------------------------------------- /demo/js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/js/.DS_Store -------------------------------------------------------------------------------- /demo/css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/css/.DS_Store -------------------------------------------------------------------------------- /demo/img/pic1_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic1_bigger.jpg -------------------------------------------------------------------------------- /demo/img/pic2_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic2_bigger.jpg -------------------------------------------------------------------------------- /demo/img/pic3_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aentan/Parallax-Scroll/HEAD/demo/img/pic3_bigger.jpg -------------------------------------------------------------------------------- /demo/js/demo.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | $(".bg-holder").parallaxScroll({ 4 | friction: 0.5, 5 | direction: "vertical" 6 | }); 7 | 8 | }); -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "eqnull": true, 6 | "expr": true, 7 | "immed": true, 8 | "noarg": true, 9 | "onevar": true, 10 | "quotmark": "double", 11 | "unused": true, 12 | "node": true 13 | } 14 | -------------------------------------------------------------------------------- /demo/js/demo.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Parallax-Scroll - v0.2.0 3 | * jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify. 4 | * http://parallax-scroll.aenism.com 5 | * 6 | * Made by Aen Tan 7 | * Under MIT License 8 | */ 9 | $(function(){$(".bg-holder").parallaxScroll({friction:.5,direction:"vertical"})}); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "grunt": "~0.4.5", 5 | "grunt-cli": "~0.1.13", 6 | "grunt-contrib-coffee": "~0.10.1", 7 | "grunt-contrib-concat": "~0.4.0", 8 | "grunt-contrib-jshint": "~0.10.0", 9 | "grunt-contrib-csslint": "~0.3.1", 10 | "grunt-contrib-uglify": "~0.4.0", 11 | "grunt-contrib-watch": "^0.6.1" 12 | }, 13 | "scripts": { 14 | "test": "grunt travis --verbose" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = tab 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [package.json] 14 | ; The indent size used in the `package.json` file cannot be changed 15 | ; https://github.com/npm/npm/pull/3180#issuecomment-16336516 16 | indent_size = 2 17 | indent_style = space 18 | -------------------------------------------------------------------------------- /.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false, 3 | "box-sizing": false, 4 | "box-model": false, 5 | "compatible-vendor-prefixes": false, 6 | "floats": false, 7 | "font-sizes": false, 8 | "gradients": false, 9 | "important": false, 10 | "known-properties": false, 11 | "outline-none": false, 12 | "qualified-headings": false, 13 | "regex-selectors": false, 14 | "shorthand": false, 15 | "text-indent": false, 16 | "unique-headings": false, 17 | "universal-selector": false, 18 | "unqualified-attributes": false 19 | } 20 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parallax-scroll", 3 | "version": "0.2.0", 4 | "homepage": "https://github.com/aentan/Parallax-Scroll", 5 | "authors": [ 6 | "Aen Tan " 7 | ], 8 | "description": "jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify.", 9 | "main": "jquery.parallax-scroll.js", 10 | "keywords": [ 11 | "background", 12 | "parallax", 13 | "scroll" 14 | ], 15 | "license": "MIT", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ], 23 | "dependencies": { 24 | "jquery": "latest" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /parallax-scroll.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.parallax-scroll", 3 | "title": "Parallax-Scroll", 4 | "description": "jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify.", 5 | "keywords": [ 6 | "background", 7 | "parallax", 8 | "scroll" 9 | ], 10 | "version": "0.2.0", 11 | "author": { 12 | "name": "Aen Tan", 13 | "email": "hello@aentan.com", 14 | "url": "https://aenism.com/" 15 | }, 16 | "licenses": [ 17 | { 18 | "type": "MIT", 19 | "url": "http://aen.mit-license.org/" 20 | } 21 | ], 22 | "bugs": "https://github.com/aentan/Parallax-Scroll/issues", 23 | "homepage": "http://parallax-scroll.aenism.com", 24 | "docs": "https://github.com/aentan/Parallax-Scroll#readme", 25 | "download": "https://github.com/aentan/Parallax-Scroll/archive/master.zip", 26 | "dependencies": { 27 | "jquery": ">=1.8" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Aen Tan 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/js/jquery.parallax-scroll.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Parallax-Scroll - v0.2.0 3 | * jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify. 4 | * http://parallax-scroll.aenism.com 5 | * 6 | * Made by Aen Tan 7 | * Under MIT License 8 | */ 9 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b(a.jQuery)}(this,function(a){"use strict";var b,c={friction:.5,direction:"vertical"},d=a(window),e=0;return window.requestAnimationFrame=function(a){var b=(new Date).getTime(),c=Math.max(0,5-(b-e)),d=window.setTimeout(function(){a(b+c)},c);return e=b+c,d},b=function(b,e){return{init:function(){this.$background=a(b),this.settings=a.extend({},c,e),this._initStyles(),this._bindEvents()},_initStyles:function(){this.$background.css({"background-attachment":"scroll"})},_visibleInViewport:function(){var a=d.height(),b=this.$background.get(0).getBoundingClientRect();return b.top0||b.bottom<=a&&b.top>a},_bindEvents:function(){var a=this;d.on("load scroll resize",function(){a._requestTick()})},_requestTick:function(){var a=this;this.ticking||(this.ticking=!0,requestAnimationFrame(function(){a._updateBgPos()}))},_updateBgPos:function(){if(this._visibleInViewport()){var a=d.width(),b=d.height(),c=this.$background.data("width"),e=this.$background.data("height"),f=c/e,g=this.$background.width(),h=this.$background.height(),i=g/h,j=f>i,k=g/c,l=e*k,m=c*k,n=this.$background.offset().top,o=d.scrollTop(),p=o-n,q=b+l,r=a+m,s=p*(b/q),t=p/b,u=p*(a/r),v=p/a,w=(b-h)/2;w=j?w*t:w;var x=(a-g)/2;x=j?x:x*v;var y,z,A=j?2*this.settings.friction*i:this.settings.friction*i;"horizontal"===this.settings.direction?(y=j?a+"px auto":"auto "+b+"px",z=x-u*A+"px 50%"):(y=j?"auto "+b+"px":a+"px auto",z="50% "+(s*A-w)+"px"),this.$background.css({"background-size":y,"background-position":z})}this.ticking=!1}}},b.defaults=c,a.fn.parallaxScroll=function(a){return this.each(function(){new b(this,a).init()})},b}); -------------------------------------------------------------------------------- /dist/jquery.parallax-scroll.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Parallax-Scroll - v0.2.0 3 | * jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify. 4 | * http://parallax-scroll.aenism.com 5 | * 6 | * Made by Aen Tan 7 | * Under MIT License 8 | */ 9 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b(a.jQuery)}(this,function(a){"use strict";var b,c={friction:.5,direction:"vertical"},d=a(window),e=0;return window.requestAnimationFrame=function(a){var b=(new Date).getTime(),c=Math.max(0,5-(b-e)),d=window.setTimeout(function(){a(b+c)},c);return e=b+c,d},b=function(b,e){return{init:function(){this.$background=a(b),this.settings=a.extend({},c,e),this._initStyles(),this._bindEvents()},_initStyles:function(){this.$background.css({"background-attachment":"scroll"})},_visibleInViewport:function(){var a=d.height(),b=this.$background.get(0).getBoundingClientRect();return b.top0||b.bottom<=a&&b.top>a},_bindEvents:function(){var a=this;d.on("load scroll resize",function(){a._requestTick()})},_requestTick:function(){var a=this;this.ticking||(this.ticking=!0,requestAnimationFrame(function(){a._updateBgPos()}))},_updateBgPos:function(){if(this._visibleInViewport()){var a=d.width(),b=d.height(),c=this.$background.data("width"),e=this.$background.data("height"),f=c/e,g=this.$background.width(),h=this.$background.height(),i=g/h,j=f>i,k=g/c,l=e*k,m=c*k,n=this.$background.offset().top,o=d.scrollTop(),p=o-n,q=b+l,r=a+m,s=p*(b/q),t=p/b,u=p*(a/r),v=p/a,w=(b-h)/2;w=j?w*t:w;var x=(a-g)/2;x=j?x:x*v;var y,z,A=j?2*this.settings.friction*i:this.settings.friction*i;"horizontal"===this.settings.direction?(y=j?a+"px auto":"auto "+b+"px",z=x-u*A+"px 50%"):(y=j?"auto "+b+"px":a+"px auto",z="50% "+(s*A-w)+"px"),this.$background.css({"background-size":y,"background-position":z})}this.ticking=!1}}},b.defaults=c,a.fn.parallaxScroll=function(a){return this.each(function(){new b(this,a).init()})},b}); -------------------------------------------------------------------------------- /demo/css/normalize.min.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0} -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | grunt.initConfig({ 5 | 6 | // Import package manifest 7 | pkg: grunt.file.readJSON("parallax-scroll.jquery.json"), 8 | 9 | // Banner definitions 10 | meta: { 11 | banner: "/*\n" + 12 | " * <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n" + 13 | " * <%= pkg.description %>\n" + 14 | " * <%= pkg.homepage %>\n" + 15 | " *\n" + 16 | " * Made by <%= pkg.author.name %>\n" + 17 | " * Under <%= pkg.licenses[0].type %> License\n" + 18 | " */\n" 19 | }, 20 | 21 | concat: { 22 | dist: { 23 | src: ["src/jquery.parallax-scroll.js"], 24 | dest: "dist/jquery.parallax-scroll.js" 25 | }, 26 | demo: { 27 | src: ["src/jquery.parallax-scroll.js"], 28 | dest: "demo/js/jquery.parallax-scroll.js" 29 | }, 30 | options: { 31 | banner: "<%= meta.banner %>" 32 | } 33 | }, 34 | 35 | jshint: { 36 | options: { 37 | jshintrc: '.jshintrc' 38 | }, 39 | core: { 40 | src: 'src/*.js' 41 | }, 42 | demo: { 43 | src: ['demo/js/*.js', '!demo/js/*.min.js'] 44 | } 45 | }, 46 | 47 | csslint: { 48 | options: { 49 | csslintrc: '.csslintrc' 50 | }, 51 | demo: { 52 | options: { 53 | requireCamelCaseOrUpperCaseIdentifiers: null 54 | }, 55 | src: 'demo/css/demo.css' 56 | } 57 | }, 58 | 59 | uglify: { 60 | core: { 61 | src: ["dist/jquery.parallax-scroll.js"], 62 | dest: "dist/jquery.parallax-scroll.min.js" 63 | }, 64 | demo_core: { 65 | src: ["demo/js/jquery.parallax-scroll.js"], 66 | dest: "demo/js/jquery.parallax-scroll.min.js" 67 | }, 68 | demo: { 69 | src: ["demo/js/demo.js"], 70 | dest: "demo/js/demo.min.js" 71 | }, 72 | options: { 73 | preserveComments: 'some', 74 | banner: "<%= meta.banner %>" 75 | } 76 | }, 77 | 78 | watch: { 79 | files: ['src/*', 'demo/js/*.js', '!demo/js/*.min.js', 'demo/css/*'], 80 | tasks: ['default'] 81 | } 82 | 83 | }); 84 | 85 | grunt.loadNpmTasks("grunt-contrib-concat"); 86 | grunt.loadNpmTasks("grunt-contrib-jshint"); 87 | grunt.loadNpmTasks("grunt-contrib-csslint"); 88 | grunt.loadNpmTasks("grunt-contrib-uglify"); 89 | grunt.loadNpmTasks("grunt-contrib-watch"); 90 | 91 | grunt.registerTask("default", ["jshint", "csslint", "concat", "uglify"]); 92 | grunt.registerTask("travis", ["jshint"]); 93 | 94 | }; 95 | -------------------------------------------------------------------------------- /demo/css/demo.css: -------------------------------------------------------------------------------- 1 | /* Scaffolding */ 2 | 3 | html, 4 | body { 5 | width: 100%; 6 | height: 100%; 7 | } 8 | 9 | body { 10 | font-family: "lato", sans-serif; 11 | font-size: 18px; 12 | font-weight: 400; 13 | line-height: 1.778; 14 | color: #222; 15 | } 16 | 17 | h1, h2, h3, h4, h5, h6 { 18 | font-weight: 700; 19 | } 20 | 21 | a { 22 | color: #228B22; 23 | text-decoration: none; 24 | } 25 | 26 | a:hover { 27 | text-decoration: underline; 28 | } 29 | 30 | 31 | /* Backgrounds */ 32 | 33 | .bg-holder { 34 | width: 100%; 35 | height: 80%; 36 | background-size: cover; 37 | background-position: 50% 50%; 38 | color: #fff; 39 | } 40 | 41 | .bg-holder .content { 42 | color: #fff; 43 | text-align: center; 44 | position: relative; 45 | top: 50%; 46 | -webkit-transform: translateY(-50%); 47 | -moz-transform: translateY(-50%); 48 | -ms-transform: translateY(-50%); 49 | -o-transform: translateY(-50%); 50 | transform: translateY(-50%); 51 | } 52 | 53 | h2 { 54 | font-size: 32px; 55 | line-height: 1.5; 56 | } 57 | 58 | .pic1 { 59 | background-image: url('../img/pic1.jpg'); 60 | } 61 | 62 | .pic2 { 63 | background-image: url('../img/pic2.jpg'); 64 | } 65 | 66 | .pic3 { 67 | background-image: url('../img/pic3.jpg'); 68 | } 69 | 70 | @media (min-width: 768px) { 71 | .pic1 { 72 | background-image: url('../img/pic1_bigger.jpg'); 73 | } 74 | .pic2 { 75 | background-image: url('../img/pic2_bigger.jpg'); 76 | } 77 | .pic3 { 78 | background-image: url('../img/pic3_bigger.jpg'); 79 | } 80 | } 81 | 82 | 83 | /* Content Sections */ 84 | 85 | section { 86 | padding: 48px; 87 | } 88 | 89 | section .content { 90 | margin: 0 auto; 91 | max-width: 640px; 92 | } 93 | 94 | .content h2 { 95 | margin: 0 0 16px; 96 | font-size: 18px; 97 | } 98 | 99 | section p { 100 | margin: 0; 101 | } 102 | 103 | section p + p { 104 | text-indent: 2em; 105 | } 106 | 107 | section + hr { 108 | border: 0; 109 | border-top: 1px solid #ccc; 110 | height: 0; 111 | } 112 | 113 | section .gist { 114 | margin: 24px 0; 115 | } 116 | 117 | section .gist .gist-data { 118 | border-bottom: 0; 119 | } 120 | 121 | section .gist-meta { 122 | display: none; 123 | } 124 | 125 | .content code { 126 | font-family: monospace, serif; 127 | font-size: 16px; 128 | color: gray; 129 | white-space: nowrap; 130 | } 131 | 132 | 133 | /* Intro */ 134 | 135 | .intro h1 { 136 | margin: 0; 137 | font-size: 48px; 138 | line-height: 1.5; 139 | } 140 | 141 | .intro p { 142 | margin: 0; 143 | font-size: 24px; 144 | } 145 | 146 | .cta { 147 | margin-top: 32px; 148 | } 149 | 150 | .btn-cta { 151 | color: #fff; 152 | font-size: 16px; 153 | border: 2px solid #fff; 154 | border-radius: 4px; 155 | padding: 8px 16px; 156 | margin: 0 4px; 157 | text-decoration: none; 158 | } 159 | 160 | .btn-cta:hover { 161 | background-color: white; 162 | color: #228B22; 163 | text-decoration: none; 164 | } 165 | 166 | 167 | /* Footer */ 168 | 169 | .footer { 170 | text-align: center; 171 | } 172 | 173 | .social { 174 | margin: 16px; 175 | list-style: none; 176 | } 177 | 178 | .social li { 179 | display: inline-block; 180 | margin: 8px; 181 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # パララックス Parallax-Scroll 2 | 3 | [See Demo](http://parallax-scroll.aenism.com). 4 | 5 | Parallax-Scroll is a jQuery plugin to create elements with background images that behaves as if their `background-attachment` property is between `scroll` and `fixed`, similar to the parallax scrolling effect you see on Spotify and is loosely based on Peder Andreas Nielsen’s [Parallax ImageScroll](https://github.com/pederan/Parallax-ImageScroll). 6 | 7 | It makes clever use of `background-position` and `background-size` properties instead of CSS3 tranforms. It runs buttery smooth and retains the rubber-band scroll behavior in Safari. Works great on mobile too. 8 | 9 | ## Markup 10 | 11 | The basic markup consists of content sections placed between background holders. The width and height of the original images must be supplied via data attributes. They are required for the calculation of aspect ratios. 12 | 13 | ```html 14 |
15 | 16 |
17 | Content that "slides" over the backgrounds 18 |
19 | 20 |
21 | Optional content to be displayed on top of the backgrounds 22 |
23 | ``` 24 | 25 | Add background images to the `.bg-holder` elements with the following styles. 26 | 27 | ```css 28 | /* All parent elements of .bg-holder must be 100% height for vertical stretch to work */ 29 | html, 30 | body { 31 | width: 100%; 32 | height: 100%; 33 | } 34 | 35 | .bg-holder { 36 | width: 100%; 37 | height: 100%; 38 | } 39 | 40 | .bg-holder#pic1 { 41 | background-image: url('pic1.jpg'); 42 | } 43 | 44 | .bg-holder#pic2 { 45 | background-image: url('pic2.jpg'); 46 | } 47 | ``` 48 | 49 | The nicest thing about using CSS background images is that by adding media queries we can do responsive image sizes. 50 | 51 | ```css 52 | @media (min-width: 768px) { 53 | .bg-holder#pic1 { 54 | background-image: url('pic1_bigger.jpg'); 55 | } 56 | .bg-holder#pic2 { 57 | background-image: url('pic2_bigger.jpg'); 58 | } 59 | } 60 | ``` 61 | 62 | ## Initialization & Options 63 | 64 | To initialize the plugin, call the `parallaxScroll` method on your background elements. 65 | 66 | ```javascript 67 | $('.bg-holder').parallaxScroll({ 68 | friction: 0.5 69 | }); 70 | ``` 71 | 72 | The plugin accepts one option – friction. It should be a float value that is more than 0 and less than 1. 0 causes the background to behave as it has `background-attachment: scroll`. 1 (maximum friction) is the same as `background-attachment: fixed`. A value greater than 1 will cause the background to scroll in reverse! 73 | 74 | Other features available in Pederan’s plugin such as `holderMinHeight` and `coverRatio` can be achieved purely with CSS and should be. The fallback option to turn off parallax in mobile devices is unnecessary because this plugin works smoothly on mobile devices. 75 | 76 | ## Installation 77 | 78 | Install using bower 79 | 80 | ``` 81 | bower install parallax-scroll 82 | ```` 83 | 84 | ## Notes 85 | 86 | Most likely requires a jQuery of lower version than other plugins you use. If in doubt I recommend 1.8.0 or higher. 87 | 88 | The only limitation is that the `background-size` property is not supported by IE<9 so this plugin would not work on that ancient browser. 89 | 90 | This plugin is loosely based on Peder Andreas Nielsen’s [Parallax ImageScroll](https://github.com/pederan/Parallax-ImageScroll). Beautiful tilt-shift photos in the demo by [rolohauck](https://www.flickr.com/photos/rolohauck/). 91 | 92 | === 93 | 94 | Made by [Aen](http://aenism.com/). Code licensed under [MIT](https://github.com/aentan/Parallax-Scroll/blob/master/LICENSE). 95 | -------------------------------------------------------------------------------- /src/jquery.parallax-scroll.js: -------------------------------------------------------------------------------- 1 | ;(function (root, factory) { 2 | if (typeof define === "function" && define.amd) { 3 | // AMD. Register as an anonymous module. 4 | define(["jquery"], factory); 5 | } else { 6 | // Browser globals 7 | factory(root.jQuery); 8 | } 9 | }(this, function ($) { 10 | "use strict"; 11 | 12 | var ParallaxScroll, 13 | defaults = { 14 | friction: 0.5, 15 | direction: "vertical" 16 | }, 17 | $win = $(window), 18 | lastTickTime = 0; 19 | 20 | window.requestAnimationFrame = function (callback) { 21 | var currTime = new Date().getTime(); 22 | var timeToCall = Math.max(0, 5 - (currTime - lastTickTime)); 23 | var id = window.setTimeout(function () { 24 | callback(currTime + timeToCall); 25 | }, timeToCall); 26 | lastTickTime = currTime + timeToCall; 27 | return id; 28 | }; 29 | 30 | ParallaxScroll = function (background, options) { 31 | return { 32 | init: function () { 33 | this.$background = $(background); 34 | this.settings = $.extend({}, defaults, options); 35 | this._initStyles(); 36 | this._bindEvents(); 37 | }, 38 | _initStyles: function () { 39 | this.$background.css({ 40 | "background-attachment": "scroll" 41 | }); 42 | }, 43 | _visibleInViewport: function () { 44 | var vpHeight = $win.height(); 45 | var rec = this.$background.get(0).getBoundingClientRect(); 46 | return (rec.top < vpHeight && rec.bottom > 0) || (rec.bottom <= vpHeight && rec.top > vpHeight); 47 | }, 48 | _bindEvents: function () { 49 | var self = this; 50 | $win.on("load scroll resize", function () { 51 | self._requestTick(); 52 | }); 53 | }, 54 | _requestTick: function () { 55 | var self = this; 56 | if (!this.ticking) { 57 | this.ticking = true; 58 | requestAnimationFrame(function () { 59 | self._updateBgPos(); 60 | }); 61 | } 62 | }, 63 | _updateBgPos: function () { 64 | if (this._visibleInViewport()) { 65 | var winW = $win.width(); 66 | var winH = $win.height(); 67 | var imgW = this.$background.data("width"); 68 | var imgH = this.$background.data("height"); 69 | var imgA = imgW / imgH; 70 | var bgW = this.$background.outerWidth(); 71 | var bgH = this.$background.outerHeight(); 72 | var bgA = bgW / bgH; 73 | var revA = bgA < imgA; 74 | var bgScale = bgW / imgW; 75 | var bgScaledH = imgH * bgScale; 76 | var bgScaledW = imgW * bgScale; 77 | var bgOffsetTop = this.$background.offset().top; 78 | var winScrollTop = $win.scrollTop(); 79 | var bgScrollTop = winScrollTop - bgOffsetTop; 80 | var xDistToMove = winH + bgScaledH; 81 | var yDistToMove = winW + bgScaledW; 82 | var xf1 = bgScrollTop * (winH / xDistToMove); 83 | var xf2 = bgScrollTop / winH; 84 | var yf1 = bgScrollTop * (winW / yDistToMove); 85 | var yf2 = bgScrollTop / winW; 86 | var centerOffsetY = Math.abs(winH - bgScaledH) / 2; 87 | centerOffsetY = revA ? centerOffsetY * xf2 : centerOffsetY; 88 | var centerOffsetX = Math.abs(winW - bgScaledW) / 2; 89 | centerOffsetX = revA ? centerOffsetX : centerOffsetX * yf2; 90 | var bgFriction = revA? this.settings.friction * (bgA * 2) : this.settings.friction * bgA; 91 | var bgSize; 92 | var bgPos; 93 | if (this.settings.direction === "horizontal") { 94 | bgSize = revA ? winW + "px auto" : "auto " + winH + "px"; 95 | bgPos = (centerOffsetX - (yf1 * bgFriction)) + "px 50%"; 96 | } else { 97 | bgSize = revA ? "auto " + winH + "px" : winW + "px auto"; 98 | bgPos = "50% " + ((xf1 * bgFriction) - centerOffsetY) + "px"; 99 | } 100 | this.$background.css({ 101 | "background-size": bgSize, 102 | "background-position": bgPos 103 | }); 104 | } 105 | this.ticking = false; 106 | } 107 | }; 108 | }; 109 | 110 | ParallaxScroll.defaults = defaults; 111 | $.fn.parallaxScroll = function (options) { 112 | return this.each(function () { 113 | new ParallaxScroll(this, options).init(); 114 | }); 115 | }; 116 | 117 | return ParallaxScroll; 118 | })); -------------------------------------------------------------------------------- /demo/js/jquery.parallax-scroll.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Parallax-Scroll - v0.2.0 3 | * jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify. 4 | * http://parallax-scroll.aenism.com 5 | * 6 | * Made by Aen Tan 7 | * Under MIT License 8 | */ 9 | ;(function (root, factory) { 10 | if (typeof define === "function" && define.amd) { 11 | // AMD. Register as an anonymous module. 12 | define(["jquery"], factory); 13 | } else { 14 | // Browser globals 15 | factory(root.jQuery); 16 | } 17 | }(this, function ($) { 18 | "use strict"; 19 | 20 | var ParallaxScroll, 21 | defaults = { 22 | friction: 0.5, 23 | direction: "vertical" 24 | }, 25 | $win = $(window), 26 | lastTickTime = 0; 27 | 28 | window.requestAnimationFrame = function (callback) { 29 | var currTime = new Date().getTime(); 30 | var timeToCall = Math.max(0, 5 - (currTime - lastTickTime)); 31 | var id = window.setTimeout(function () { 32 | callback(currTime + timeToCall); 33 | }, timeToCall); 34 | lastTickTime = currTime + timeToCall; 35 | return id; 36 | }; 37 | 38 | ParallaxScroll = function (background, options) { 39 | return { 40 | init: function () { 41 | this.$background = $(background); 42 | this.settings = $.extend({}, defaults, options); 43 | this._initStyles(); 44 | this._bindEvents(); 45 | }, 46 | _initStyles: function () { 47 | this.$background.css({ 48 | "background-attachment": "scroll" 49 | }); 50 | }, 51 | _visibleInViewport: function () { 52 | var vpHeight = $win.height(); 53 | var rec = this.$background.get(0).getBoundingClientRect(); 54 | return (rec.top < vpHeight && rec.bottom > 0) || (rec.bottom <= vpHeight && rec.top > vpHeight); 55 | }, 56 | _bindEvents: function () { 57 | var self = this; 58 | $win.on("load scroll resize", function () { 59 | self._requestTick(); 60 | }); 61 | }, 62 | _requestTick: function () { 63 | var self = this; 64 | if (!this.ticking) { 65 | this.ticking = true; 66 | requestAnimationFrame(function () { 67 | self._updateBgPos(); 68 | }); 69 | } 70 | }, 71 | _updateBgPos: function () { 72 | if (this._visibleInViewport()) { 73 | var winW = $win.width(); 74 | var winH = $win.height(); 75 | var imgW = this.$background.data("width"); 76 | var imgH = this.$background.data("height"); 77 | var imgA = imgW / imgH; 78 | var bgW = this.$background.outerWidth(); 79 | var bgH = this.$background.outerHeight(); 80 | var bgA = bgW / bgH; 81 | var revA = bgA < imgA; 82 | var bgScale = bgW / imgW; 83 | var bgScaledH = imgH * bgScale; 84 | var bgScaledW = imgW * bgScale; 85 | var bgOffsetTop = this.$background.offset().top; 86 | var winScrollTop = $win.scrollTop(); 87 | var bgScrollTop = winScrollTop - bgOffsetTop; 88 | var xDistToMove = winH + bgScaledH; 89 | var yDistToMove = winW + bgScaledW; 90 | var xf1 = bgScrollTop * (winH / xDistToMove); 91 | var xf2 = bgScrollTop / winH; 92 | var yf1 = bgScrollTop * (winW / yDistToMove); 93 | var yf2 = bgScrollTop / winW; 94 | var centerOffsetY = Math.abs(winH - bgScaledH) / 2; 95 | centerOffsetY = revA ? centerOffsetY * xf2 : centerOffsetY; 96 | var centerOffsetX = Math.abs(winW - bgScaledW) / 2; 97 | centerOffsetX = revA ? centerOffsetX : centerOffsetX * yf2; 98 | var bgFriction = revA? this.settings.friction * (bgA * 2) : this.settings.friction * bgA; 99 | var bgSize; 100 | var bgPos; 101 | if (this.settings.direction === "horizontal") { 102 | bgSize = revA ? winW + "px auto" : "auto " + winH + "px"; 103 | bgPos = (centerOffsetX - (yf1 * bgFriction)) + "px 50%"; 104 | } else { 105 | bgSize = revA ? "auto " + winH + "px" : winW + "px auto"; 106 | bgPos = "50% " + ((xf1 * bgFriction) - centerOffsetY) + "px"; 107 | } 108 | this.$background.css({ 109 | "background-size": bgSize, 110 | "background-position": bgPos 111 | }); 112 | } 113 | this.ticking = false; 114 | } 115 | }; 116 | }; 117 | 118 | ParallaxScroll.defaults = defaults; 119 | $.fn.parallaxScroll = function (options) { 120 | return this.each(function () { 121 | new ParallaxScroll(this, options).init(); 122 | }); 123 | }; 124 | 125 | return ParallaxScroll; 126 | })); -------------------------------------------------------------------------------- /dist/jquery.parallax-scroll.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Parallax-Scroll - v0.2.0 3 | * jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify. 4 | * http://parallax-scroll.aenism.com 5 | * 6 | * Made by Aen Tan 7 | * Under MIT License 8 | */ 9 | ;(function (root, factory) { 10 | if (typeof define === "function" && define.amd) { 11 | // AMD. Register as an anonymous module. 12 | define(["jquery"], factory); 13 | } else { 14 | // Browser globals 15 | factory(root.jQuery); 16 | } 17 | }(this, function ($) { 18 | "use strict"; 19 | 20 | var ParallaxScroll, 21 | defaults = { 22 | friction: 0.5, 23 | direction: "vertical" 24 | }, 25 | $win = $(window), 26 | lastTickTime = 0; 27 | 28 | window.requestAnimationFrame = function (callback) { 29 | var currTime = new Date().getTime(); 30 | var timeToCall = Math.max(0, 5 - (currTime - lastTickTime)); 31 | var id = window.setTimeout(function () { 32 | callback(currTime + timeToCall); 33 | }, timeToCall); 34 | lastTickTime = currTime + timeToCall; 35 | return id; 36 | }; 37 | 38 | ParallaxScroll = function (background, options) { 39 | return { 40 | init: function () { 41 | this.$background = $(background); 42 | this.settings = $.extend({}, defaults, options); 43 | this._initStyles(); 44 | this._bindEvents(); 45 | }, 46 | _initStyles: function () { 47 | this.$background.css({ 48 | "background-attachment": "scroll" 49 | }); 50 | }, 51 | _visibleInViewport: function () { 52 | var vpHeight = $win.height(); 53 | var rec = this.$background.get(0).getBoundingClientRect(); 54 | return (rec.top < vpHeight && rec.bottom > 0) || (rec.bottom <= vpHeight && rec.top > vpHeight); 55 | }, 56 | _bindEvents: function () { 57 | var self = this; 58 | $win.on("load scroll resize", function () { 59 | self._requestTick(); 60 | }); 61 | }, 62 | _requestTick: function () { 63 | var self = this; 64 | if (!this.ticking) { 65 | this.ticking = true; 66 | requestAnimationFrame(function () { 67 | self._updateBgPos(); 68 | }); 69 | } 70 | }, 71 | _updateBgPos: function () { 72 | if (this._visibleInViewport()) { 73 | var winW = $win.width(); 74 | var winH = $win.height(); 75 | var imgW = this.$background.data("width"); 76 | var imgH = this.$background.data("height"); 77 | var imgA = imgW / imgH; 78 | var bgW = this.$background.outerWidth(); 79 | var bgH = this.$background.outerHeight(); 80 | var bgA = bgW / bgH; 81 | var revA = bgA < imgA; 82 | var bgScale = bgW / imgW; 83 | var bgScaledH = imgH * bgScale; 84 | var bgScaledW = imgW * bgScale; 85 | var bgOffsetTop = this.$background.offset().top; 86 | var winScrollTop = $win.scrollTop(); 87 | var bgScrollTop = winScrollTop - bgOffsetTop; 88 | var xDistToMove = winH + bgScaledH; 89 | var yDistToMove = winW + bgScaledW; 90 | var xf1 = bgScrollTop * (winH / xDistToMove); 91 | var xf2 = bgScrollTop / winH; 92 | var yf1 = bgScrollTop * (winW / yDistToMove); 93 | var yf2 = bgScrollTop / winW; 94 | var centerOffsetY = Math.abs(winH - bgScaledH) / 2; 95 | centerOffsetY = revA ? centerOffsetY * xf2 : centerOffsetY; 96 | var centerOffsetX = Math.abs(winW - bgScaledW) / 2; 97 | centerOffsetX = revA ? centerOffsetX : centerOffsetX * yf2; 98 | var bgFriction = revA? this.settings.friction * (bgA * 2) : this.settings.friction * bgA; 99 | var bgSize; 100 | var bgPos; 101 | if (this.settings.direction === "horizontal") { 102 | bgSize = revA ? winW + "px auto" : "auto " + winH + "px"; 103 | bgPos = (centerOffsetX - (yf1 * bgFriction)) + "px 50%"; 104 | } else { 105 | bgSize = revA ? "auto " + winH + "px" : winW + "px auto"; 106 | bgPos = "50% " + ((xf1 * bgFriction) - centerOffsetY) + "px"; 107 | } 108 | this.$background.css({ 109 | "background-size": bgSize, 110 | "background-position": bgPos 111 | }); 112 | } 113 | this.ticking = false; 114 | } 115 | }; 116 | }; 117 | 118 | ParallaxScroll.defaults = defaults; 119 | $.fn.parallaxScroll = function (options) { 120 | return this.each(function () { 121 | new ParallaxScroll(this, options).init(); 122 | }); 123 | }; 124 | 125 | return ParallaxScroll; 126 | })); -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Parallax-Scroll by Aen 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 29 | 30 |
31 |
32 |

パララックス

33 |

Parallax-Scroll

34 |
35 | Download 36 | View on GitHub 37 |
38 |
39 |
40 | 41 |
42 |
43 |

Parallax-Scroll is a jQuery plugin to create elements with background images that behaves as if their background-attachment property is between scroll and fixed, similar to the parallax scrolling effect you see on Spotify and is loosely based on Peder Andreas Nielsen’s Parallax ImageScroll.

44 |

It makes clever use of background-position and background-size properties instead of CSS3 tranforms. It runs buttery smooth and retains the rubber-band scroll behavior in Safari. Works great on mobile too.

45 |
46 |
47 | 48 |
49 |
50 |

マークアップ

51 |

Markup

52 |
53 |
54 | 55 |
56 |
57 |

The basic markup consists of content sections placed between background holders. The width and height of the original images must be supplied via data attributes. They are required for the calculation of aspect ratios.

58 | 59 |

Add background images to the .bg-holder elements with the following styles.

60 | 61 |

The nicest thing about using CSS background images is that by adding media queries we can do responsive image sizes.

62 | 63 |
64 |
65 | 66 |
67 |
68 |

イニシャライズとオプション

69 |

Initialization & Options

70 |
71 |
72 | 73 |
74 |
75 |

To initialize the plugin, call the parallaxScroll method on your background elements.

76 | 77 |

The plugin accepts one option – friction. It should be a float value that is more than 0 and less than 1. 0 causes the background to behave as it has background-attachment: scroll (which is useless). 1 (maximum friction) is the same as background-attachment: fixed. A value greater than 1 will cause the background to scroll in reverse!

78 |

Other features available in Pederan’s plugin such as holderMinHeight and coverRatio can be achieved purely with CSS and should be. The fallback option to turn off parallax in mobile devices is unnecessary because this plugin works smoothly on mobile devices.

79 |
80 |
81 | 82 |
83 | 84 |
85 |
86 |

Notes

87 |

Most likely requires a jQuery of lower version than other plugins you use. If in doubt I recommend 1.8.0 or higher.

88 |

The only limitation is that the background-size property is not supported by IE<9 so this plugin would not work on that ancient browser.

89 |

This plugin is loosely based on Peder Andreas Nielsen’s Parallax ImageScroll. Beautiful tilt-shift photos by rolohauck.

90 |
91 |
92 | 93 |
94 | 95 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | --------------------------------------------------------------------------------