├── .gitignore
├── gg-close-read.Rproj
├── custom.scss
├── README.md
├── practice
├── second.css
├── lib
│ ├── shortcuts
│ │ ├── sticky.min.js
│ │ ├── infinite.min.js
│ │ ├── inview.min.js
│ │ ├── sticky.js
│ │ ├── infinite.js
│ │ └── inview.js
│ ├── waypoints.debug.js
│ ├── jquery.waypoints.min.js
│ ├── zepto.waypoints.min.js
│ ├── noframework.waypoints.min.js
│ ├── jquery.waypoints.js
│ ├── zepto.waypoints.js
│ └── noframework.waypoints.js
├── style.css
├── layouts.qmd
├── sticky-side-original.qmd
├── scrollama.qmd
├── sticky-side.qmd
└── waypoints.qmd
├── gg-close-read-dream-syntax-1.qmd
└── gg-close-read.qmd
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | .DS_Store
6 |
7 | *.html
8 | *_files
9 | _publish.yml
--------------------------------------------------------------------------------
/gg-close-read.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
--------------------------------------------------------------------------------
/custom.scss:
--------------------------------------------------------------------------------
1 | /*-- scss:defaults --*/
2 |
3 | // Google fonts
4 | @import url('https://fonts.googleapis.com/css2?family=Nanum+Myeongjo&display=swap');
5 |
6 | // Fonts
7 |
8 | $font-family-sans-serif: 'Nanum Myeongjo', serif;
9 |
10 | /*-- scss:rules --*/
11 |
12 | p {
13 | margin-bottom: 85vh; /* between paragraphs */
14 | }
15 |
16 | h3 {
17 | margin-top: 15vh; /* for new sections */
18 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## GG Close Read
2 |
3 | A test to see how close we can get to creating a scrollytelling html document from a Quarto document. The inspiration for this is the Close Read series from the New York Times, specifically:
4 |
5 | [*A Poem (and a Painting) About the Suffering That Hides in Plain Sight*](https://www.nytimes.com/interactive/2022/03/06/books/auden-musee-des-beaux-arts.html) by Elisa Gabbert.
6 |
7 | The result can be viewed on Quarto pubs:
8 |
9 | [*A Grammar of Graphics: A close read of a scatterplot*](https://andrew.quarto.pub/gg-close-read/)
10 |
11 |
--------------------------------------------------------------------------------
/practice/second.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | height: 100%;
3 | }
4 |
5 | .wrapper {
6 | height: 100%;
7 | font-family: Helvetica, sans-serif;
8 | line-height: 1.5;
9 | word-spacing: 2px;
10 | letter-spacing: 0.5px;
11 | }
12 |
13 | .fixed {
14 | background-attachment: fixed;
15 | background-repeat: no-repeat;
16 | background-size: cover;
17 | background-position: center center;
18 | height: 100%;
19 | width: 100%;
20 | color: #eeeeee;
21 | text-align: center;
22 | display: table;
23 | }
24 |
25 | .fixed h2 {
26 | display: table-cell;
27 | vertical-align: middle;
28 | }
29 |
30 | .scroll {
31 | background-color: #ffe0f6;
32 | padding: 10px 70px;
33 | color: #666666;
34 | }
35 |
36 | .one {
37 | background-image: "pic1.png";
38 | }
39 |
40 | .two {
41 | background-image: pic2.png;
42 | }
43 |
44 | .three {
45 | background-image: pic3.png;
46 | }
--------------------------------------------------------------------------------
/practice/lib/shortcuts/sticky.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Sticky Element Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(s){this.options=e.extend({},i.defaults,t.defaults,s),this.element=this.options.element,this.$element=e(this.element),this.createWrapper(),this.createWaypoint()}var e=window.jQuery,i=window.Waypoint;t.prototype.createWaypoint=function(){var t=this.options.handler;this.waypoint=new i(e.extend({},this.options,{element:this.wrapper,handler:e.proxy(function(e){var i=this.options.direction.indexOf(e)>-1,s=i?this.$element.outerHeight(!0):"";this.$wrapper.height(s),this.$element.toggleClass(this.options.stuckClass,i),t&&t.call(this,e)},this)}))},t.prototype.createWrapper=function(){this.options.wrapper&&this.$element.wrap(this.options.wrapper),this.$wrapper=this.$element.parent(),this.wrapper=this.$wrapper[0]},t.prototype.destroy=function(){this.$element.parent()[0]===this.wrapper&&(this.waypoint.destroy(),this.$element.removeClass(this.options.stuckClass),this.options.wrapper&&this.$element.unwrap())},t.defaults={wrapper:'
',stuckClass:"stuck",direction:"down right"},i.Sticky=t}();
--------------------------------------------------------------------------------
/practice/lib/shortcuts/infinite.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Infinite Scroll Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(n){this.options=i.extend({},t.defaults,n),this.container=this.options.element,"auto"!==this.options.container&&(this.container=this.options.container),this.$container=i(this.container),this.$more=i(this.options.more),this.$more.length&&(this.setupHandler(),this.waypoint=new o(this.options))}var i=window.jQuery,o=window.Waypoint;t.prototype.setupHandler=function(){this.options.handler=i.proxy(function(){this.options.onBeforePageLoad(),this.destroy(),this.$container.addClass(this.options.loadingClass),i.get(i(this.options.more).attr("href"),i.proxy(function(t){var n=i(i.parseHTML(t)),e=n.find(this.options.more),s=n.find(this.options.items);s.length||(s=n.filter(this.options.items)),this.$container.append(s),this.$container.removeClass(this.options.loadingClass),e.length||(e=n.filter(this.options.more)),e.length?(this.$more.replaceWith(e),this.$more=e,this.waypoint=new o(this.options)):this.$more.remove(),this.options.onAfterPageLoad(s)},this))},this)},t.prototype.destroy=function(){this.waypoint&&this.waypoint.destroy()},t.defaults={container:"auto",items:".infinite-item",more:".infinite-more-link",offset:"bottom-in-view",loadingClass:"infinite-loading",onBeforePageLoad:i.noop,onAfterPageLoad:i.noop},o.Infinite=t}();
--------------------------------------------------------------------------------
/practice/lib/waypoints.debug.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Debug - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var displayNoneMessage = [
11 | 'You have a Waypoint element with display none. For more information on ',
12 | 'why this is a bad idea read ',
13 | 'http://imakewebthings.com/waypoints/guides/debugging/#display-none'
14 | ].join('')
15 | var fixedMessage = [
16 | 'You have a Waypoint element with fixed positioning. For more ',
17 | 'information on why this is a bad idea read ',
18 | 'http://imakewebthings.com/waypoints/guides/debugging/#fixed-position'
19 | ].join('')
20 |
21 | function checkWaypointStyles() {
22 | var originalRefresh = window.Waypoint.Context.prototype.refresh
23 |
24 | window.Waypoint.Context.prototype.refresh = function() {
25 | for (var axis in this.waypoints) {
26 | for (var key in this.waypoints[axis]) {
27 | var waypoint = this.waypoints[axis][key]
28 | var style = window.getComputedStyle(waypoint.element)
29 | if (!waypoint.enabled) {
30 | continue
31 | }
32 | if (style && style.display === 'none') {
33 | console.error(displayNoneMessage)
34 | }
35 | if (style && style.position === 'fixed') {
36 | console.error(fixedMessage)
37 | }
38 | }
39 | }
40 | return originalRefresh.call(this)
41 | }
42 | }
43 |
44 | checkWaypointStyles()
45 | }())
46 | ;
--------------------------------------------------------------------------------
/practice/lib/shortcuts/inview.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Inview Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(){}function e(t){this.options=i.Adapter.extend({},e.defaults,t),this.axis=this.options.horizontal?"horizontal":"vertical",this.waypoints=[],this.element=this.options.element,this.createWaypoints()}var i=window.Waypoint;e.prototype.createWaypoints=function(){for(var t={vertical:[{down:"enter",up:"exited",offset:"100%"},{down:"entered",up:"exit",offset:"bottom-in-view"},{down:"exit",up:"entered",offset:0},{down:"exited",up:"enter",offset:function(){return-this.adapter.outerHeight()}}],horizontal:[{right:"enter",left:"exited",offset:"100%"},{right:"entered",left:"exit",offset:"right-in-view"},{right:"exit",left:"entered",offset:0},{right:"exited",left:"enter",offset:function(){return-this.adapter.outerWidth()}}]},e=0,i=t[this.axis].length;i>e;e++){var n=t[this.axis][e];this.createWaypoint(n)}},e.prototype.createWaypoint=function(t){var e=this;this.waypoints.push(new i({context:this.options.context,element:this.options.element,enabled:this.options.enabled,handler:function(t){return function(i){e.options[t[i]].call(e,i)}}(t),offset:t.offset,horizontal:this.options.horizontal}))},e.prototype.destroy=function(){for(var t=0,e=this.waypoints.length;e>t;t++)this.waypoints[t].destroy();this.waypoints=[]},e.prototype.disable=function(){for(var t=0,e=this.waypoints.length;e>t;t++)this.waypoints[t].disable()},e.prototype.enable=function(){for(var t=0,e=this.waypoints.length;e>t;t++)this.waypoints[t].enable()},e.defaults={context:window,enabled:!0,enter:t,entered:t,exit:t,exited:t},i.Inview=e}();
--------------------------------------------------------------------------------
/practice/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html,
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | }
10 |
11 | body {
12 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
13 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
14 | min-height: 1280px;
15 | color: #3b3b3b;
16 | font-size: 24px;
17 | }
18 |
19 | p,
20 | h1,
21 | h2,
22 | h3,
23 | h4,
24 | a {
25 | margin: 0;
26 | font-weight: 400;
27 | }
28 |
29 | a,
30 | a:visited,
31 | a:hover {
32 | color: teal;
33 | text-decoration: none;
34 | border-bottom: 2px solid currentColor;
35 | }
36 |
37 | nav {
38 | display: -webkit-box;
39 | display: -ms-flexbox;
40 | display: flex;
41 | -webkit-box-align: baseline;
42 | -ms-flex-align: baseline;
43 | align-items: baseline;
44 | -webkit-box-pack: justify;
45 | -ms-flex-pack: justify;
46 | justify-content: space-between;
47 | background: #f3f3f3;
48 | padding: 1rem;
49 | padding-right: 5rem;
50 | -ms-flex-wrap: wrap;
51 | flex-wrap: wrap;
52 | }
53 |
54 | .nav__examples {
55 | display: -webkit-box;
56 | display: -ms-flexbox;
57 | display: flex;
58 | -webkit-box-align: baseline;
59 | -ms-flex-align: baseline;
60 | align-items: baseline;
61 | -ms-flex-wrap: wrap;
62 | flex-wrap: wrap;
63 | margin-top: 1rem;
64 | }
65 |
66 | .nav__examples > * {
67 | margin-right: 0.5rem;
68 | }
69 |
70 | #intro {
71 | max-width: 40rem;
72 | margin: 1rem auto;
73 | text-align: center;
74 | }
75 |
76 | .intro__hed {
77 | font-size: 2em;
78 | margin: 2rem auto 0.5rem auto;
79 | }
80 |
81 | .intro__dek {
82 | color: #8a8a8a;
83 | }
84 |
85 | #intro {
86 | margin-bottom: 320px;
87 | }
88 |
89 | #outro {
90 | height: 640px;
91 | }
92 |
93 | @media (min-width: 840px) {
94 | .nav__examples {
95 | margin-top: 0;
96 | margin-left: 2rem;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/practice/lib/shortcuts/sticky.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Sticky Element Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var $ = window.jQuery
11 | var Waypoint = window.Waypoint
12 |
13 | /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */
14 | function Sticky(options) {
15 | this.options = $.extend({}, Waypoint.defaults, Sticky.defaults, options)
16 | this.element = this.options.element
17 | this.$element = $(this.element)
18 | this.createWrapper()
19 | this.createWaypoint()
20 | }
21 |
22 | /* Private */
23 | Sticky.prototype.createWaypoint = function() {
24 | var originalHandler = this.options.handler
25 |
26 | this.waypoint = new Waypoint($.extend({}, this.options, {
27 | element: this.wrapper,
28 | handler: $.proxy(function(direction) {
29 | var shouldBeStuck = this.options.direction.indexOf(direction) > -1
30 | var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : ''
31 |
32 | this.$wrapper.height(wrapperHeight)
33 | this.$element.toggleClass(this.options.stuckClass, shouldBeStuck)
34 |
35 | if (originalHandler) {
36 | originalHandler.call(this, direction)
37 | }
38 | }, this)
39 | }))
40 | }
41 |
42 | /* Private */
43 | Sticky.prototype.createWrapper = function() {
44 | if (this.options.wrapper) {
45 | this.$element.wrap(this.options.wrapper)
46 | }
47 | this.$wrapper = this.$element.parent()
48 | this.wrapper = this.$wrapper[0]
49 | }
50 |
51 | /* Public */
52 | Sticky.prototype.destroy = function() {
53 | if (this.$element.parent()[0] === this.wrapper) {
54 | this.waypoint.destroy()
55 | this.$element.removeClass(this.options.stuckClass)
56 | if (this.options.wrapper) {
57 | this.$element.unwrap()
58 | }
59 | }
60 | }
61 |
62 | Sticky.defaults = {
63 | wrapper: '
',
64 | stuckClass: 'stuck',
65 | direction: 'down right'
66 | }
67 |
68 | Waypoint.Sticky = Sticky
69 | }())
70 | ;
--------------------------------------------------------------------------------
/practice/lib/shortcuts/infinite.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Infinite Scroll Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var $ = window.jQuery
11 | var Waypoint = window.Waypoint
12 |
13 | /* http://imakewebthings.com/waypoints/shortcuts/infinite-scroll */
14 | function Infinite(options) {
15 | this.options = $.extend({}, Infinite.defaults, options)
16 | this.container = this.options.element
17 | if (this.options.container !== 'auto') {
18 | this.container = this.options.container
19 | }
20 | this.$container = $(this.container)
21 | this.$more = $(this.options.more)
22 |
23 | if (this.$more.length) {
24 | this.setupHandler()
25 | this.waypoint = new Waypoint(this.options)
26 | }
27 | }
28 |
29 | /* Private */
30 | Infinite.prototype.setupHandler = function() {
31 | this.options.handler = $.proxy(function() {
32 | this.options.onBeforePageLoad()
33 | this.destroy()
34 | this.$container.addClass(this.options.loadingClass)
35 |
36 | $.get($(this.options.more).attr('href'), $.proxy(function(data) {
37 | var $data = $($.parseHTML(data))
38 | var $newMore = $data.find(this.options.more)
39 |
40 | var $items = $data.find(this.options.items)
41 | if (!$items.length) {
42 | $items = $data.filter(this.options.items)
43 | }
44 |
45 | this.$container.append($items)
46 | this.$container.removeClass(this.options.loadingClass)
47 |
48 | if (!$newMore.length) {
49 | $newMore = $data.filter(this.options.more)
50 | }
51 | if ($newMore.length) {
52 | this.$more.replaceWith($newMore)
53 | this.$more = $newMore
54 | this.waypoint = new Waypoint(this.options)
55 | }
56 | else {
57 | this.$more.remove()
58 | }
59 |
60 | this.options.onAfterPageLoad($items)
61 | }, this))
62 | }, this)
63 | }
64 |
65 | /* Public */
66 | Infinite.prototype.destroy = function() {
67 | if (this.waypoint) {
68 | this.waypoint.destroy()
69 | }
70 | }
71 |
72 | Infinite.defaults = {
73 | container: 'auto',
74 | items: '.infinite-item',
75 | more: '.infinite-more-link',
76 | offset: 'bottom-in-view',
77 | loadingClass: 'infinite-loading',
78 | onBeforePageLoad: $.noop,
79 | onAfterPageLoad: $.noop
80 | }
81 |
82 | Waypoint.Infinite = Infinite
83 | }())
84 | ;
--------------------------------------------------------------------------------
/practice/layouts.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "layouts"
3 | format: html
4 | ---
5 |
6 | ::::: {.columns .column-page}
7 | :::{.sidebar}
8 | hello there good frriend!
9 | :::
10 | :::{.column-screen-right}
11 | Quarto supports a variety of page layout options that enable you to author content that:
12 |
13 | Fills the main content region
14 | Overflows the content region
15 | Spans the entire page
16 | Occupies the document margin
17 | Quarto uses the concept of columns to describe page layout (e.g. the “body” column, the “margin” column, etc.). Below we’ll describe how to arrange content into these columns.
18 |
19 | All of the layout capabilities described in this document work for HTML output and many work for PDF and LaTeX output. For details about the PDF / LaTeX output, see PDF/LaTeX Layout.
20 | Quarto supports a variety of page layout options that enable you to author content that:
21 |
22 | Fills the main content region
23 | Overflows the content region
24 | Spans the entire page
25 | Occupies the document margin
26 | Quarto uses the concept of columns to describe page layout (e.g. the “body” column, the “margin” column, etc.). Below we’ll describe how to arrange content into these columns.
27 |
28 | All of the layout capabilities described in this document work for HTML output and many work for PDF and LaTeX output. For details about the PDF / LaTeX output, see PDF/LaTeX Layout.
29 | Quarto supports a variety of page layout options that enable you to author content that:
30 |
31 | Fills the main content region
32 | Overflows the content region
33 | Spans the entire page
34 | Occupies the document margin
35 | Quarto uses the concept of columns to describe page layout (e.g. the “body” column, the “margin” column, etc.). Below we’ll describe how to arrange content into these columns.
36 |
37 | All of the layout capabilities described in this document work for HTML output and many work for PDF and LaTeX output. For details about the PDF / LaTeX output, see PDF/LaTeX Layout.
38 | Quarto supports a variety of page layout options that enable you to author content that:
39 |
40 | Fills the main content region
41 | Overflows the content region
42 | Spans the entire page
43 | Occupies the document margin
44 | Quarto uses the concept of columns to describe page layout (e.g. the “body” column, the “margin” column, etc.). Below we’ll describe how to arrange content into these columns.
45 |
46 | All of the layout capabilities described in this document work for HTML output and many work for PDF and LaTeX output. For details about the PDF / LaTeX output, see PDF/LaTeX Layout.
47 | :::
48 | :::
49 |
50 | ```{=html}
51 |
68 | ```
69 |
70 |
--------------------------------------------------------------------------------
/practice/lib/shortcuts/inview.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints Inview Shortcut - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | function noop() {}
11 |
12 | var Waypoint = window.Waypoint
13 |
14 | /* http://imakewebthings.com/waypoints/shortcuts/inview */
15 | function Inview(options) {
16 | this.options = Waypoint.Adapter.extend({}, Inview.defaults, options)
17 | this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
18 | this.waypoints = []
19 | this.element = this.options.element
20 | this.createWaypoints()
21 | }
22 |
23 | /* Private */
24 | Inview.prototype.createWaypoints = function() {
25 | var configs = {
26 | vertical: [{
27 | down: 'enter',
28 | up: 'exited',
29 | offset: '100%'
30 | }, {
31 | down: 'entered',
32 | up: 'exit',
33 | offset: 'bottom-in-view'
34 | }, {
35 | down: 'exit',
36 | up: 'entered',
37 | offset: 0
38 | }, {
39 | down: 'exited',
40 | up: 'enter',
41 | offset: function() {
42 | return -this.adapter.outerHeight()
43 | }
44 | }],
45 | horizontal: [{
46 | right: 'enter',
47 | left: 'exited',
48 | offset: '100%'
49 | }, {
50 | right: 'entered',
51 | left: 'exit',
52 | offset: 'right-in-view'
53 | }, {
54 | right: 'exit',
55 | left: 'entered',
56 | offset: 0
57 | }, {
58 | right: 'exited',
59 | left: 'enter',
60 | offset: function() {
61 | return -this.adapter.outerWidth()
62 | }
63 | }]
64 | }
65 |
66 | for (var i = 0, end = configs[this.axis].length; i < end; i++) {
67 | var config = configs[this.axis][i]
68 | this.createWaypoint(config)
69 | }
70 | }
71 |
72 | /* Private */
73 | Inview.prototype.createWaypoint = function(config) {
74 | var self = this
75 | this.waypoints.push(new Waypoint({
76 | context: this.options.context,
77 | element: this.options.element,
78 | enabled: this.options.enabled,
79 | handler: (function(config) {
80 | return function(direction) {
81 | self.options[config[direction]].call(self, direction)
82 | }
83 | }(config)),
84 | offset: config.offset,
85 | horizontal: this.options.horizontal
86 | }))
87 | }
88 |
89 | /* Public */
90 | Inview.prototype.destroy = function() {
91 | for (var i = 0, end = this.waypoints.length; i < end; i++) {
92 | this.waypoints[i].destroy()
93 | }
94 | this.waypoints = []
95 | }
96 |
97 | Inview.prototype.disable = function() {
98 | for (var i = 0, end = this.waypoints.length; i < end; i++) {
99 | this.waypoints[i].disable()
100 | }
101 | }
102 |
103 | Inview.prototype.enable = function() {
104 | for (var i = 0, end = this.waypoints.length; i < end; i++) {
105 | this.waypoints[i].enable()
106 | }
107 | }
108 |
109 | Inview.defaults = {
110 | context: window,
111 | enabled: true,
112 | enter: noop,
113 | entered: noop,
114 | exit: noop,
115 | exited: noop
116 | }
117 |
118 | Waypoint.Inview = Inview
119 | }())
120 | ;
--------------------------------------------------------------------------------
/gg-close-read-dream-syntax-1.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | format:
3 | close-read-html:
4 | sticky-sidebar:
5 | sidebar-background: black
6 | body-background: white
7 | execute:
8 | echo: false
9 | ---
10 |
11 | :::{.sticky-sidebar}
12 |
13 | # A Grammar of Graphics
14 |
15 | ## A close read of a scatterplot
16 |
17 | By Andrew Bray
18 |
19 | What a lovely graphic this is,
20 |
21 | with its three colors
22 |
23 | and dots all over the place.
24 |
25 | I wonder: how was this made? Let's walk through this step by step, starting with the data.
26 |
27 | ```{r}
28 | #| echo: false
29 | #| eval: true
30 | #| warning: false
31 | #| label: cr-plot1
32 |
33 | ggplot(penguins, aes(x = bill_length_mm,
34 | y = flipper_length_mm,
35 | color = species)) +
36 | geom_point() +
37 | labs(x = "Bill Length",
38 | y = "Flipper Length",
39 | Species = "Species") +
40 | theme_bw()
41 | ```
42 |
43 | ### The Data {.step label="cr-tab1" transition="scrolloff-then-scrollon"}
44 |
45 | At the foundation of any data visualization is the data itself. Here our data come from Dr. Kristen Gorman, who recorded measurements on 344 penguins near Palmer Station, Antarctica. The three variables at hand are the length of the bill (a numerical variable), the length of the flipper (a numerical variable), and the species of the bird (a categorical variable).
46 |
47 | We can see that we have a bump in the road ahead! At least one of these rows has some missing values, as indicated by *NA*. [show highlight of NA row].
48 |
49 | ```{r}
50 | #| echo: false
51 | #| eval: true
52 | #| warning: false
53 | #| label: cr-tab1
54 |
55 | select(penguins, species, bill_length_mm, flipper_length_mm)
56 | ```
57 |
58 |
59 | ### The Canvas {.step label="cr-plot2"}
60 |
61 | You can lay down a blank sheet of paper by calling the `ggplot()` function in the `ggplot2` package in R. Right now, there's nothing to see here, just a blank canvas, waiting to be designed.
62 |
63 | ```{r}
64 | #| echo: true
65 | #| eval: true
66 | #| warning: false
67 | #| label: cr-plot2
68 | #| transition: "fade
69 |
70 | ggplot()
71 | ```
72 |
73 | ### Aesthetic mappings {.step label="cr-plot3" transition="fadeout-then-fadein"}
74 |
75 | The first and most important decision in the design of a graphic is the *aesthetic mapping*. This is a dynamic link that ties the variability found in a column of your data frame to variability in an aesthetic attribute of the plot.
76 |
77 | For a colored scatter plot, we use the following aesthetic mappings:\
78 | - Map bill length to the x-axis\
79 | - Map flipper length to the y-axis\
80 | - Map the species to a color palette\
81 |
82 | This plot still looks quite bare. Where is the data?
83 |
84 | ```{r}
85 | #| echo: true
86 | #| eval: true
87 | #| warning: false
88 | #| label: cr-plot3
89 | #| cr-transition: "
90 |
91 | ggplot(penguins, aes(x = bill_length_mm,
92 | y = flipper_length_mm,
93 | color = species))
94 | ```
95 |
96 | ### Geometry
97 |
98 | The plot comes alive once we've assigned a **geometry**. The geometry describes the manner in which the observations show up in the graphic. In the *point* geometry, every observation is represented by a single circle. Now that our observation are plotted according to their aesthetic mapping, our plot is almost complete.
99 |
100 | What's lacking is some polish.
101 |
102 | ```{r}
103 | #| echo: true
104 | #| eval: true
105 | #| warning: false
106 |
107 | ggplot(penguins, aes(x = bill_length_mm,
108 | y = flipper_length_mm,
109 | color = species)) +
110 | geom_point()
111 | ```
112 |
113 | ### Theme
114 |
115 | To polish up the look of our plot, we'll focus on two things. The most apparent is the *theme*, which encompasses several small design decisions: the color of the background, the number and color of guidelines, the font, etc. `ggplot2` defaults to a gray background but I prefer the more minimal look of the white background in the black-and-white theme.
116 |
117 | The last piece to fix up was those labels. By default, the column names will show up. Those are written so that R can understand them: they lack spaces or punctuation. Here I've rewritten the labels to be ones that can be better understood by a human.
118 |
119 | ```{r}
120 | #| echo: true
121 | #| eval: true
122 | #| warning: false
123 |
124 | ggplot(penguins, aes(x = bill_length_mm,
125 | y = flipper_length_mm,
126 | color = species)) +
127 | geom_point() +
128 | labs(x = "Bill Length",
129 | y = "Flipper Length",
130 | Species = "Species") +
131 | theme_bw()
132 | ```
133 |
134 | # El Fin
135 |
136 | :::
137 |
--------------------------------------------------------------------------------
/practice/sticky-side-original.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Untitled"
3 | format: html
4 | ---
5 |
6 |
7 | ```{=html}
8 |
9 |
10 |
11 |
12 | Scrollama: Sticky Overlay Example
13 |
14 |
15 |
16 |
74 |
75 |
76 |
77 |
78 |
79 | scrollama.js
80 |
87 |
88 |
89 | Sticky Overlay Example
90 |
91 | Start scrolling to see how it works.
92 |
93 |
94 |
95 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
166 |
167 |
168 | ```
--------------------------------------------------------------------------------
/gg-close-read.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | format:
3 | html:
4 | theme:
5 | - custom.scss
6 | fontcolor: black
7 | backgroundcolor: white
8 | page-layout: full
9 | self-contained: true
10 | df-print: paged
11 | execute:
12 | echo: false
13 | ---
14 |
15 | ::::: {.columns .column-page}
16 |
17 | :::: {.column width=35%}
18 |
19 | # A Grammar of Graphics
20 |
21 | ## A close read of a scatterplot
22 |
23 | [By Andrew Bray]{style="font-size: .7em"}
24 |
25 | :::{}
26 | \
27 | :::
28 |
29 | What a lovely graphic this is,
30 |
31 | with its three colors
32 |
33 | and dots all over the place.
34 |
35 | I wonder: how was this made? Let's walk through this step by step, starting with the data.
36 |
37 | ::::
38 |
39 | :::: {.column width="10%"}
40 | ::::
41 |
42 | :::: {.column width="55%" style="padding:20px; position:sticky;top:30vh;"}
43 |
44 | ```{r}
45 | #| echo: false
46 | #| eval: true
47 | #| warning: false
48 |
49 | library(ggplot2)
50 | library(palmerpenguins)
51 | library(dplyr)
52 | ggplot(penguins, aes(x = bill_length_mm,
53 | y = flipper_length_mm,
54 | color = species)) +
55 | geom_point() +
56 | labs(x = "Bill Length",
57 | y = "Flipper Length",
58 | Species = "Species") +
59 | theme_bw()
60 | ```
61 | :::::
62 | :::::
63 |
64 | ::::: {.columns .column-page}
65 | :::: {.column width="35%"}
66 |
67 | ### The Data
68 |
69 | At the foundation of any data visualization is the data itself. Here our data come from Dr. Kristen Gorman, who recorded measurements on 344 penguins near Palmer Station, Antarctica. The three variables at hand are the length of the bill (a numerical variable), the length of the flipper (a numerical variable), and the species of the bird (a categorical variable).
70 |
71 | We can see that we have a bump in the road ahead! At least one of these rows has some missing values, as indicated by *NA*. [show highlight of NA row].
72 |
73 |
74 | \
75 |
76 | ::::
77 |
78 | :::: {.column width="10%"}
79 | ::::
80 |
81 | :::: {.column width="55%" style="padding:20px; position:sticky;top:20vh;"}
82 |
83 | ```{r}
84 | #| echo: false
85 | #| eval: true
86 | #| warning: false
87 |
88 | select(penguins, species, bill_length_mm, flipper_length_mm)
89 | ```
90 |
91 | ::::
92 | :::::
93 |
94 | ::::: {.columns .column-page}
95 | :::: {.column width="35%"}
96 |
97 | ### The Canvas
98 |
99 | You can lay down a blank sheet of paper by calling the `ggplot()` function in the `ggplot2` package in R. Right now, there's nothing to see here, just a blank canvas, waiting to be designed.
100 |
101 | \
102 |
103 | ::::
104 |
105 | :::: {.column width="10%"}
106 | ::::
107 |
108 | :::: {.column width="55%" style="padding:20px; position:sticky;top:20vh;"}
109 |
110 | ```{r}
111 | #| echo: true
112 | #| eval: true
113 | #| warning: false
114 |
115 | ggplot()
116 | ```
117 |
118 | ::::
119 | :::::
120 |
121 |
122 | ::::: {.columns .column-page}
123 | :::: {.column width="35%"}
124 |
125 | ### Aesthetic mappings
126 |
127 | The first and most important decision in the design of a graphic is the *aesthetic mapping*. This is a dynamic link that ties the variability found in a column of your data frame to variability in an aesthetic attribute of the plot.
128 |
129 | For a colored scatter plot, we use the following aesthetic mappings:\
130 | - Map bill length to the x-axis\
131 | - Map flipper length to the y-axis\
132 | - Map the species to a color palette\
133 |
134 | This plot still looks quite bare. Where is the data?
135 |
136 | ::::
137 |
138 | :::: {.column width="10%"}
139 | ::::
140 |
141 | :::: {.column width="55%" style="padding:20px; position:sticky;top:10vh;"}
142 |
143 | ```{r}
144 | #| echo: true
145 | #| eval: true
146 | #| warning: false
147 |
148 | ggplot(penguins, aes(x = bill_length_mm,
149 | y = flipper_length_mm,
150 | color = species))
151 | ```
152 |
153 | ::::
154 | :::::
155 |
156 | ::::: {.columns .column-page}
157 | :::: {.column width="35%"}
158 |
159 | ### Geometry
160 |
161 | The plot comes alive once we've assigned a **geometry**. The geometry describes the manner in which the observations show up in the graphic. In the *point* geometry, every observation is represented by a single circle. Now that our observation are plotted according to their aesthetic mapping, our plot is almost complete.
162 |
163 | What's lacking is some polish.
164 |
165 | ::::
166 |
167 | :::: {.column width="10%"}
168 | ::::
169 |
170 | :::: {.column width="55%" style="padding:20px; position:sticky;top:10vh;"}
171 |
172 | ```{r}
173 | #| echo: true
174 | #| eval: true
175 | #| warning: false
176 |
177 | ggplot(penguins, aes(x = bill_length_mm,
178 | y = flipper_length_mm,
179 | color = species)) +
180 | geom_point()
181 | ```
182 |
183 | ::::
184 | :::::
185 |
186 |
187 | ::::: {.columns .column-page}
188 | :::: {.column width="35%"}
189 |
190 | ### Theme
191 |
192 | To polish up the look of our plot, we'll focus on two things. The most apparent is the *theme*, which encompasses several small design decisions: the color of the background, the number and color of guidelines, the font, etc. `ggplot2` defaults to a gray background but I prefer the more minimal look of the white background in the black-and-white theme.
193 |
194 | :::{}
195 | The last piece to fix up was those labels. By default, the column names will show up. Those are written so that R can understand them: they lack spaces or punctuation. Here I've rewritten the labels to be ones that can be better understood by a human.
196 |
197 | \
198 |
199 | ::::
200 |
201 | :::: {.column width="10%"}
202 | ::::
203 |
204 | :::: {.column width="55%" style="padding:20px; position:sticky;top:7vh;"}
205 |
206 | ```{r}
207 | #| echo: true
208 | #| eval: true
209 | #| warning: false
210 |
211 | ggplot(penguins, aes(x = bill_length_mm,
212 | y = flipper_length_mm,
213 | color = species)) +
214 | geom_point() +
215 | labs(x = "Bill Length",
216 | y = "Flipper Length",
217 | Species = "Species") +
218 | theme_bw()
219 | ```
220 |
221 | ::::
222 | :::::
223 |
224 |
225 | # El Fin
226 |
--------------------------------------------------------------------------------
/practice/scrollama.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | format: html
3 | ---
4 |
5 | ```{=html}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Scrollama: Sticky Side Example
14 |
15 |
16 |
17 |
86 |
87 |
88 |
89 |
92 |
93 |
96 |
99 |
100 |
101 |
102 | Sticky Side Example
103 |
104 | Start scrolling to see how it works.
105 |
106 |
107 |
108 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
197 |
198 |
199 |
200 | ```
--------------------------------------------------------------------------------
/practice/sticky-side.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | format:
3 | html:
4 | theme:
5 | - sandstone
6 | - custom.scss
7 | fontcolor: black
8 | backgroundcolor: white
9 | page-layout: full
10 | execute:
11 | echo: false
12 | ---
13 |
14 | ::::: {.columns .column-page}
15 |
16 | :::: {.column width=35%}
17 |
18 | # A Grammar of Graphics
19 |
20 | ## A close read of a scatterplot
21 |
22 | [By Andrew Bray]{style="font-size: .7em"}
23 |
24 | :::{}
25 | \
26 | :::
27 |
28 | What a lovely graphics this is,
29 |
30 | :::{.step data-img="url(pic2.png)" data-color="blue" data-src="https://rstudio-conf-2022.github.io/rmd-to-quarto/materials/3-computation/slides/computation.html#/generalizing-the-code-chunk-2"}
31 | with its three colors
32 | :::
33 |
34 | :::{.step data-img="url(pic2.png)" data-color="green"}
35 | and dots all over the place.
36 | :::
37 |
38 | I wonder: how was this made?
39 |
40 | ::::
41 |
42 | :::: {.column width="10%"}
43 | ::::
44 |
45 | :::: {.column .sticky-thing width="55%"}
46 |
47 |
48 |
49 |
50 | ```{r}
51 | #| echo: false
52 | #| eval: false
53 | #| warning: false
54 |
55 | library(tidyverse)
56 | library(palmerpenguins)
57 |
58 | ggplot(penguins, aes(x = bill_length_mm,
59 | y = flipper_length_mm,
60 | color = species)) +
61 | geom_point() +
62 | labs(x = "Bill Length",
63 | y = "Flipper Length",
64 | Species = "Species")
65 | ```
66 | ::::
67 | :::::
68 |
69 | ```{=html}
70 |
71 |
72 |
73 |
74 | Scrollama: Sticky Overlay Example
75 |
76 |
77 |
113 |
114 |
115 |
116 |
117 |
118 | Sticky Overlay Example
119 |
120 | Start scrolling to see how it works.
121 |
122 |
123 |
124 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
191 |
192 |
193 | ```
--------------------------------------------------------------------------------
/practice/waypoints.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | format: html
3 | ---
4 |
5 | ```{=html}
6 |
7 |
8 |
22 |
23 |
31 | ```
32 |
33 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
34 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
35 |
36 | :::{#basic-waypoint}
37 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
38 | :::
39 |
40 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
41 |
42 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
43 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.v
44 |
45 |
46 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
47 |
48 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
49 |
50 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
51 |
52 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
53 |
54 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
55 |
56 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
57 |
58 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
59 |
60 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
61 |
62 | v
63 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
64 |
65 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
66 |
67 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
68 |
69 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
70 |
71 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
72 |
73 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
74 |
75 | You may notice the basic example above triggers when we scroll through the waypoint both downwards and upwards. What if we want to perform different actions when scrolling up, or limit our handler to one direction? When a waypoint is triggered, the handler function is passed a direction parameter.
--------------------------------------------------------------------------------
/practice/lib/jquery.waypoints.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(o){if(!o)throw new Error("No options passed to Waypoint constructor");if(!o.element)throw new Error("No element option passed to Waypoint constructor");if(!o.handler)throw new Error("No handler option passed to Waypoint constructor");this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,o),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=o.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var o in i)e.push(i[o]);for(var n=0,r=e.length;r>n;n++)e[n][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.Context.refreshAll();for(var e in i)i[e].enabled=!0;return this},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight()},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth()}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=n.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,o[t.waypointContextKey]=this,i+=1,n.windowContext||(n.windowContext=!0,n.windowContext=new e(window)),this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,o={},n=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical),i=this.element==this.element.window;t&&e&&!i&&(this.adapter.off(".waypoints"),delete o[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,n.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||n.isTouch)&&(e.didScroll=!0,n.requestAnimationFrame(t))})},e.prototype.handleResize=function(){n.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var o=e[i],n=o.newScroll>o.oldScroll,r=n?o.forward:o.backward;for(var s in this.waypoints[i]){var a=this.waypoints[i][s];if(null!==a.triggerPoint){var l=o.oldScroll=a.triggerPoint,p=l&&h,u=!l&&!h;(p||u)&&(a.queueTrigger(r),t[a.group.id]=a.group)}}}for(var c in t)t[c].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?n.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?n.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var o=0,n=t.length;n>o;o++)t[o].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),o={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var a in this.waypoints[r]){var l,h,p,u,c,d=this.waypoints[r][a],f=d.options.offset,w=d.triggerPoint,y=0,g=null==w;d.element!==d.element.window&&(y=d.adapter.offset()[s.offsetProp]),"function"==typeof f?f=f.apply(d):"string"==typeof f&&(f=parseFloat(f),d.options.offset.indexOf("%")>-1&&(f=Math.ceil(s.contextDimension*f/100))),l=s.contextScroll-s.contextOffset,d.triggerPoint=Math.floor(y+l-f),h=w=s.oldScroll,u=h&&p,c=!h&&!p,!g&&u?(d.queueTrigger(s.backward),o[d.group.id]=d.group):!g&&c?(d.queueTrigger(s.forward),o[d.group.id]=d.group):g&&s.oldScroll>=d.triggerPoint&&(d.queueTrigger(s.forward),o[d.group.id]=d.group)}}return n.requestAnimationFrame(function(){for(var t in o)o[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in o)o[t].refresh()},e.findByElement=function(t){return o[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},n.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},n.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),o[this.axis][this.name]=this}var o={vertical:{},horizontal:{}},n=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],right:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var o=this.triggerQueues[i],n="up"===i||"left"===i;o.sort(n?e:t);for(var r=0,s=o.length;s>r;r+=1){var a=o[r];(a.options.continuous||r===o.length-1)&&a.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints),o=i===this.waypoints.length-1;return o?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=n.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return o[t.axis][t.name]||new i(t)},n.Group=i}(),function(){"use strict";function t(t){this.$element=e(t)}var e=window.jQuery,i=window.Waypoint;e.each(["innerHeight","innerWidth","off","offset","on","outerHeight","outerWidth","scrollLeft","scrollTop"],function(e,i){t.prototype[i]=function(){var t=Array.prototype.slice.call(arguments);return this.$element[i].apply(this.$element,t)}}),e.each(["extend","inArray","isEmptyObject"],function(i,o){t[o]=e[o]}),i.adapters.push({name:"jquery",Adapter:t}),i.Adapter=t}(),function(){"use strict";function t(t){return function(){var i=[],o=arguments[0];return t.isFunction(arguments[0])&&(o=t.extend({},arguments[1]),o.handler=arguments[0]),this.each(function(){var n=t.extend({},o,{element:this});"string"==typeof n.context&&(n.context=t(this).closest(n.context)[0]),i.push(new e(n))}),i}}var e=window.Waypoint;window.jQuery&&(window.jQuery.fn.waypoint=t(window.jQuery)),window.Zepto&&(window.Zepto.fn.waypoint=t(window.Zepto))}();
--------------------------------------------------------------------------------
/practice/lib/zepto.waypoints.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(o){if(!o)throw new Error("No options passed to Waypoint constructor");if(!o.element)throw new Error("No element option passed to Waypoint constructor");if(!o.handler)throw new Error("No handler option passed to Waypoint constructor");this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,o),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=o.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var o in i)e.push(i[o]);for(var n=0,r=e.length;r>n;n++)e[n][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.Context.refreshAll();for(var e in i)i[e].enabled=!0;return this},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight()},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth()}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=n.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,o[t.waypointContextKey]=this,i+=1,n.windowContext||(n.windowContext=!0,n.windowContext=new e(window)),this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,o={},n=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical),i=this.element==this.element.window;t&&e&&!i&&(this.adapter.off(".waypoints"),delete o[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,n.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||n.isTouch)&&(e.didScroll=!0,n.requestAnimationFrame(t))})},e.prototype.handleResize=function(){n.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var o=e[i],n=o.newScroll>o.oldScroll,r=n?o.forward:o.backward;for(var s in this.waypoints[i]){var a=this.waypoints[i][s];if(null!==a.triggerPoint){var l=o.oldScroll=a.triggerPoint,p=l&&h,u=!l&&!h;(p||u)&&(a.queueTrigger(r),t[a.group.id]=a.group)}}}for(var c in t)t[c].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?n.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?n.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var o=0,n=t.length;n>o;o++)t[o].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),o={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var a in this.waypoints[r]){var l,h,p,u,c,d=this.waypoints[r][a],f=d.options.offset,w=d.triggerPoint,y=0,g=null==w;d.element!==d.element.window&&(y=d.adapter.offset()[s.offsetProp]),"function"==typeof f?f=f.apply(d):"string"==typeof f&&(f=parseFloat(f),d.options.offset.indexOf("%")>-1&&(f=Math.ceil(s.contextDimension*f/100))),l=s.contextScroll-s.contextOffset,d.triggerPoint=Math.floor(y+l-f),h=w=s.oldScroll,u=h&&p,c=!h&&!p,!g&&u?(d.queueTrigger(s.backward),o[d.group.id]=d.group):!g&&c?(d.queueTrigger(s.forward),o[d.group.id]=d.group):g&&s.oldScroll>=d.triggerPoint&&(d.queueTrigger(s.forward),o[d.group.id]=d.group)}}return n.requestAnimationFrame(function(){for(var t in o)o[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in o)o[t].refresh()},e.findByElement=function(t){return o[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},n.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},n.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),o[this.axis][this.name]=this}var o={vertical:{},horizontal:{}},n=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],right:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var o=this.triggerQueues[i],n="up"===i||"left"===i;o.sort(n?e:t);for(var r=0,s=o.length;s>r;r+=1){var a=o[r];(a.options.continuous||r===o.length-1)&&a.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints),o=i===this.waypoints.length-1;return o?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=n.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return o[t.axis][t.name]||new i(t)},n.Group=i}(),function(){"use strict";function t(t){this.element=t,this.$element=e(t)}var e=window.Zepto,i=window.Waypoint;e.each(["off","on","scrollLeft","scrollTop"],function(e,i){t.prototype[i]=function(){var t=Array.prototype.slice.call(arguments);return this.$element[i].apply(this.$element,t)}}),t.prototype.offset=function(){return this.element!==this.element.window?this.$element.offset():void 0},e.each(["width","height"],function(i,o){function n(t,i){return function(t){var n=this.$element,r=n[o](),s={width:["left","right"],height:["top","bottom"]};return e.each(s[o],function(e,o){r+=parseInt(n.css("padding-"+o),10),i&&(r+=parseInt(n.css("border-"+o+"-width"),10)),t&&(r+=parseInt(n.css("margin-"+o),10))}),r}}var r=e.camelCase("inner-"+o),s=e.camelCase("outer-"+o);t.prototype[r]=n(!1),t.prototype[s]=n(!0)}),e.each(["extend","inArray"],function(i,o){t[o]=e[o]}),t.isEmptyObject=function(t){for(var e in t)return!1;return!0},i.adapters.push({name:"zepto",Adapter:t}),i.Adapter=t}(),function(){"use strict";function t(t){return function(){var i=[],o=arguments[0];return t.isFunction(arguments[0])&&(o=t.extend({},arguments[1]),o.handler=arguments[0]),this.each(function(){var n=t.extend({},o,{element:this});"string"==typeof n.context&&(n.context=t(this).closest(n.context)[0]),i.push(new e(n))}),i}}var e=window.Waypoint;window.jQuery&&(window.jQuery.fn.waypoint=t(window.jQuery)),window.Zepto&&(window.Zepto.fn.waypoint=t(window.Zepto))}();
--------------------------------------------------------------------------------
/practice/lib/noframework.waypoints.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | !function(){"use strict";function t(n){if(!n)throw new Error("No options passed to Waypoint constructor");if(!n.element)throw new Error("No element option passed to Waypoint constructor");if(!n.handler)throw new Error("No handler option passed to Waypoint constructor");this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,n),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=n.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var n in i)e.push(i[n]);for(var o=0,r=e.length;r>o;o++)e[o][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.Context.refreshAll();for(var e in i)i[e].enabled=!0;return this},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight()},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth()}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=o.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,n[t.waypointContextKey]=this,i+=1,o.windowContext||(o.windowContext=!0,o.windowContext=new e(window)),this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,n={},o=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical),i=this.element==this.element.window;t&&e&&!i&&(this.adapter.off(".waypoints"),delete n[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,o.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||o.isTouch)&&(e.didScroll=!0,o.requestAnimationFrame(t))})},e.prototype.handleResize=function(){o.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var n=e[i],o=n.newScroll>n.oldScroll,r=o?n.forward:n.backward;for(var s in this.waypoints[i]){var l=this.waypoints[i][s];if(null!==l.triggerPoint){var a=n.oldScroll=l.triggerPoint,p=a&&h,u=!a&&!h;(p||u)&&(l.queueTrigger(r),t[l.group.id]=l.group)}}}for(var d in t)t[d].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?o.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?o.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var n=0,o=t.length;o>n;n++)t[n].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),n={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var l in this.waypoints[r]){var a,h,p,u,d,f=this.waypoints[r][l],c=f.options.offset,w=f.triggerPoint,y=0,g=null==w;f.element!==f.element.window&&(y=f.adapter.offset()[s.offsetProp]),"function"==typeof c?c=c.apply(f):"string"==typeof c&&(c=parseFloat(c),f.options.offset.indexOf("%")>-1&&(c=Math.ceil(s.contextDimension*c/100))),a=s.contextScroll-s.contextOffset,f.triggerPoint=Math.floor(y+a-c),h=w=s.oldScroll,u=h&&p,d=!h&&!p,!g&&u?(f.queueTrigger(s.backward),n[f.group.id]=f.group):!g&&d?(f.queueTrigger(s.forward),n[f.group.id]=f.group):g&&s.oldScroll>=f.triggerPoint&&(f.queueTrigger(s.forward),n[f.group.id]=f.group)}}return o.requestAnimationFrame(function(){for(var t in n)n[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in n)n[t].refresh()},e.findByElement=function(t){return n[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},o.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},o.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),n[this.axis][this.name]=this}var n={vertical:{},horizontal:{}},o=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],right:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var n=this.triggerQueues[i],o="up"===i||"left"===i;n.sort(o?e:t);for(var r=0,s=n.length;s>r;r+=1){var l=n[r];(l.options.continuous||r===n.length-1)&&l.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=o.Adapter.inArray(e,this.waypoints),n=i===this.waypoints.length-1;return n?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=o.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=o.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return n[t.axis][t.name]||new i(t)},o.Group=i}(),function(){"use strict";function t(t){return t===t.window}function e(e){return t(e)?e:e.defaultView}function i(t){this.element=t,this.handlers={}}var n=window.Waypoint;i.prototype.innerHeight=function(){var e=t(this.element);return e?this.element.innerHeight:this.element.clientHeight},i.prototype.innerWidth=function(){var e=t(this.element);return e?this.element.innerWidth:this.element.clientWidth},i.prototype.off=function(t,e){function i(t,e,i){for(var n=0,o=e.length-1;o>n;n++){var r=e[n];i&&i!==r||t.removeEventListener(r)}}var n=t.split("."),o=n[0],r=n[1],s=this.element;if(r&&this.handlers[r]&&o)i(s,this.handlers[r][o],e),this.handlers[r][o]=[];else if(o)for(var l in this.handlers)i(s,this.handlers[l][o]||[],e),this.handlers[l][o]=[];else if(r&&this.handlers[r]){for(var a in this.handlers[r])i(s,this.handlers[r][a],e);this.handlers[r]={}}},i.prototype.offset=function(){if(!this.element.ownerDocument)return null;var t=this.element.ownerDocument.documentElement,i=e(this.element.ownerDocument),n={top:0,left:0};return this.element.getBoundingClientRect&&(n=this.element.getBoundingClientRect()),{top:n.top+i.pageYOffset-t.clientTop,left:n.left+i.pageXOffset-t.clientLeft}},i.prototype.on=function(t,e){var i=t.split("."),n=i[0],o=i[1]||"__default",r=this.handlers[o]=this.handlers[o]||{},s=r[n]=r[n]||[];s.push(e),this.element.addEventListener(n,e)},i.prototype.outerHeight=function(e){var i,n=this.innerHeight();return e&&!t(this.element)&&(i=window.getComputedStyle(this.element),n+=parseInt(i.marginTop,10),n+=parseInt(i.marginBottom,10)),n},i.prototype.outerWidth=function(e){var i,n=this.innerWidth();return e&&!t(this.element)&&(i=window.getComputedStyle(this.element),n+=parseInt(i.marginLeft,10),n+=parseInt(i.marginRight,10)),n},i.prototype.scrollLeft=function(){var t=e(this.element);return t?t.pageXOffset:this.element.scrollLeft},i.prototype.scrollTop=function(){var t=e(this.element);return t?t.pageYOffset:this.element.scrollTop},i.extend=function(){function t(t,e){if("object"==typeof t&&"object"==typeof e)for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}for(var e=Array.prototype.slice.call(arguments),i=1,n=e.length;n>i;i++)t(e[0],e[i]);return e[0]},i.inArray=function(t,e,i){return null==e?-1:e.indexOf(t,i)},i.isEmptyObject=function(t){for(var e in t)return!1;return!0},n.adapters.push({name:"noframework",Adapter:i}),n.Adapter=i}();
--------------------------------------------------------------------------------
/practice/lib/jquery.waypoints.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var keyCounter = 0
11 | var allWaypoints = {}
12 |
13 | /* http://imakewebthings.com/waypoints/api/waypoint */
14 | function Waypoint(options) {
15 | if (!options) {
16 | throw new Error('No options passed to Waypoint constructor')
17 | }
18 | if (!options.element) {
19 | throw new Error('No element option passed to Waypoint constructor')
20 | }
21 | if (!options.handler) {
22 | throw new Error('No handler option passed to Waypoint constructor')
23 | }
24 |
25 | this.key = 'waypoint-' + keyCounter
26 | this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
27 | this.element = this.options.element
28 | this.adapter = new Waypoint.Adapter(this.element)
29 | this.callback = options.handler
30 | this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
31 | this.enabled = this.options.enabled
32 | this.triggerPoint = null
33 | this.group = Waypoint.Group.findOrCreate({
34 | name: this.options.group,
35 | axis: this.axis
36 | })
37 | this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
38 |
39 | if (Waypoint.offsetAliases[this.options.offset]) {
40 | this.options.offset = Waypoint.offsetAliases[this.options.offset]
41 | }
42 | this.group.add(this)
43 | this.context.add(this)
44 | allWaypoints[this.key] = this
45 | keyCounter += 1
46 | }
47 |
48 | /* Private */
49 | Waypoint.prototype.queueTrigger = function(direction) {
50 | this.group.queueTrigger(this, direction)
51 | }
52 |
53 | /* Private */
54 | Waypoint.prototype.trigger = function(args) {
55 | if (!this.enabled) {
56 | return
57 | }
58 | if (this.callback) {
59 | this.callback.apply(this, args)
60 | }
61 | }
62 |
63 | /* Public */
64 | /* http://imakewebthings.com/waypoints/api/destroy */
65 | Waypoint.prototype.destroy = function() {
66 | this.context.remove(this)
67 | this.group.remove(this)
68 | delete allWaypoints[this.key]
69 | }
70 |
71 | /* Public */
72 | /* http://imakewebthings.com/waypoints/api/disable */
73 | Waypoint.prototype.disable = function() {
74 | this.enabled = false
75 | return this
76 | }
77 |
78 | /* Public */
79 | /* http://imakewebthings.com/waypoints/api/enable */
80 | Waypoint.prototype.enable = function() {
81 | this.context.refresh()
82 | this.enabled = true
83 | return this
84 | }
85 |
86 | /* Public */
87 | /* http://imakewebthings.com/waypoints/api/next */
88 | Waypoint.prototype.next = function() {
89 | return this.group.next(this)
90 | }
91 |
92 | /* Public */
93 | /* http://imakewebthings.com/waypoints/api/previous */
94 | Waypoint.prototype.previous = function() {
95 | return this.group.previous(this)
96 | }
97 |
98 | /* Private */
99 | Waypoint.invokeAll = function(method) {
100 | var allWaypointsArray = []
101 | for (var waypointKey in allWaypoints) {
102 | allWaypointsArray.push(allWaypoints[waypointKey])
103 | }
104 | for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
105 | allWaypointsArray[i][method]()
106 | }
107 | }
108 |
109 | /* Public */
110 | /* http://imakewebthings.com/waypoints/api/destroy-all */
111 | Waypoint.destroyAll = function() {
112 | Waypoint.invokeAll('destroy')
113 | }
114 |
115 | /* Public */
116 | /* http://imakewebthings.com/waypoints/api/disable-all */
117 | Waypoint.disableAll = function() {
118 | Waypoint.invokeAll('disable')
119 | }
120 |
121 | /* Public */
122 | /* http://imakewebthings.com/waypoints/api/enable-all */
123 | Waypoint.enableAll = function() {
124 | Waypoint.Context.refreshAll()
125 | for (var waypointKey in allWaypoints) {
126 | allWaypoints[waypointKey].enabled = true
127 | }
128 | return this
129 | }
130 |
131 | /* Public */
132 | /* http://imakewebthings.com/waypoints/api/refresh-all */
133 | Waypoint.refreshAll = function() {
134 | Waypoint.Context.refreshAll()
135 | }
136 |
137 | /* Public */
138 | /* http://imakewebthings.com/waypoints/api/viewport-height */
139 | Waypoint.viewportHeight = function() {
140 | return window.innerHeight || document.documentElement.clientHeight
141 | }
142 |
143 | /* Public */
144 | /* http://imakewebthings.com/waypoints/api/viewport-width */
145 | Waypoint.viewportWidth = function() {
146 | return document.documentElement.clientWidth
147 | }
148 |
149 | Waypoint.adapters = []
150 |
151 | Waypoint.defaults = {
152 | context: window,
153 | continuous: true,
154 | enabled: true,
155 | group: 'default',
156 | horizontal: false,
157 | offset: 0
158 | }
159 |
160 | Waypoint.offsetAliases = {
161 | 'bottom-in-view': function() {
162 | return this.context.innerHeight() - this.adapter.outerHeight()
163 | },
164 | 'right-in-view': function() {
165 | return this.context.innerWidth() - this.adapter.outerWidth()
166 | }
167 | }
168 |
169 | window.Waypoint = Waypoint
170 | }())
171 | ;(function() {
172 | 'use strict'
173 |
174 | function requestAnimationFrameShim(callback) {
175 | window.setTimeout(callback, 1000 / 60)
176 | }
177 |
178 | var keyCounter = 0
179 | var contexts = {}
180 | var Waypoint = window.Waypoint
181 | var oldWindowLoad = window.onload
182 |
183 | /* http://imakewebthings.com/waypoints/api/context */
184 | function Context(element) {
185 | this.element = element
186 | this.Adapter = Waypoint.Adapter
187 | this.adapter = new this.Adapter(element)
188 | this.key = 'waypoint-context-' + keyCounter
189 | this.didScroll = false
190 | this.didResize = false
191 | this.oldScroll = {
192 | x: this.adapter.scrollLeft(),
193 | y: this.adapter.scrollTop()
194 | }
195 | this.waypoints = {
196 | vertical: {},
197 | horizontal: {}
198 | }
199 |
200 | element.waypointContextKey = this.key
201 | contexts[element.waypointContextKey] = this
202 | keyCounter += 1
203 | if (!Waypoint.windowContext) {
204 | Waypoint.windowContext = true
205 | Waypoint.windowContext = new Context(window)
206 | }
207 |
208 | this.createThrottledScrollHandler()
209 | this.createThrottledResizeHandler()
210 | }
211 |
212 | /* Private */
213 | Context.prototype.add = function(waypoint) {
214 | var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
215 | this.waypoints[axis][waypoint.key] = waypoint
216 | this.refresh()
217 | }
218 |
219 | /* Private */
220 | Context.prototype.checkEmpty = function() {
221 | var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
222 | var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
223 | var isWindow = this.element == this.element.window
224 | if (horizontalEmpty && verticalEmpty && !isWindow) {
225 | this.adapter.off('.waypoints')
226 | delete contexts[this.key]
227 | }
228 | }
229 |
230 | /* Private */
231 | Context.prototype.createThrottledResizeHandler = function() {
232 | var self = this
233 |
234 | function resizeHandler() {
235 | self.handleResize()
236 | self.didResize = false
237 | }
238 |
239 | this.adapter.on('resize.waypoints', function() {
240 | if (!self.didResize) {
241 | self.didResize = true
242 | Waypoint.requestAnimationFrame(resizeHandler)
243 | }
244 | })
245 | }
246 |
247 | /* Private */
248 | Context.prototype.createThrottledScrollHandler = function() {
249 | var self = this
250 | function scrollHandler() {
251 | self.handleScroll()
252 | self.didScroll = false
253 | }
254 |
255 | this.adapter.on('scroll.waypoints', function() {
256 | if (!self.didScroll || Waypoint.isTouch) {
257 | self.didScroll = true
258 | Waypoint.requestAnimationFrame(scrollHandler)
259 | }
260 | })
261 | }
262 |
263 | /* Private */
264 | Context.prototype.handleResize = function() {
265 | Waypoint.Context.refreshAll()
266 | }
267 |
268 | /* Private */
269 | Context.prototype.handleScroll = function() {
270 | var triggeredGroups = {}
271 | var axes = {
272 | horizontal: {
273 | newScroll: this.adapter.scrollLeft(),
274 | oldScroll: this.oldScroll.x,
275 | forward: 'right',
276 | backward: 'left'
277 | },
278 | vertical: {
279 | newScroll: this.adapter.scrollTop(),
280 | oldScroll: this.oldScroll.y,
281 | forward: 'down',
282 | backward: 'up'
283 | }
284 | }
285 |
286 | for (var axisKey in axes) {
287 | var axis = axes[axisKey]
288 | var isForward = axis.newScroll > axis.oldScroll
289 | var direction = isForward ? axis.forward : axis.backward
290 |
291 | for (var waypointKey in this.waypoints[axisKey]) {
292 | var waypoint = this.waypoints[axisKey][waypointKey]
293 | if (waypoint.triggerPoint === null) {
294 | continue
295 | }
296 | var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
297 | var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
298 | var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
299 | var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
300 | if (crossedForward || crossedBackward) {
301 | waypoint.queueTrigger(direction)
302 | triggeredGroups[waypoint.group.id] = waypoint.group
303 | }
304 | }
305 | }
306 |
307 | for (var groupKey in triggeredGroups) {
308 | triggeredGroups[groupKey].flushTriggers()
309 | }
310 |
311 | this.oldScroll = {
312 | x: axes.horizontal.newScroll,
313 | y: axes.vertical.newScroll
314 | }
315 | }
316 |
317 | /* Private */
318 | Context.prototype.innerHeight = function() {
319 | /*eslint-disable eqeqeq */
320 | if (this.element == this.element.window) {
321 | return Waypoint.viewportHeight()
322 | }
323 | /*eslint-enable eqeqeq */
324 | return this.adapter.innerHeight()
325 | }
326 |
327 | /* Private */
328 | Context.prototype.remove = function(waypoint) {
329 | delete this.waypoints[waypoint.axis][waypoint.key]
330 | this.checkEmpty()
331 | }
332 |
333 | /* Private */
334 | Context.prototype.innerWidth = function() {
335 | /*eslint-disable eqeqeq */
336 | if (this.element == this.element.window) {
337 | return Waypoint.viewportWidth()
338 | }
339 | /*eslint-enable eqeqeq */
340 | return this.adapter.innerWidth()
341 | }
342 |
343 | /* Public */
344 | /* http://imakewebthings.com/waypoints/api/context-destroy */
345 | Context.prototype.destroy = function() {
346 | var allWaypoints = []
347 | for (var axis in this.waypoints) {
348 | for (var waypointKey in this.waypoints[axis]) {
349 | allWaypoints.push(this.waypoints[axis][waypointKey])
350 | }
351 | }
352 | for (var i = 0, end = allWaypoints.length; i < end; i++) {
353 | allWaypoints[i].destroy()
354 | }
355 | }
356 |
357 | /* Public */
358 | /* http://imakewebthings.com/waypoints/api/context-refresh */
359 | Context.prototype.refresh = function() {
360 | /*eslint-disable eqeqeq */
361 | var isWindow = this.element == this.element.window
362 | /*eslint-enable eqeqeq */
363 | var contextOffset = isWindow ? undefined : this.adapter.offset()
364 | var triggeredGroups = {}
365 | var axes
366 |
367 | this.handleScroll()
368 | axes = {
369 | horizontal: {
370 | contextOffset: isWindow ? 0 : contextOffset.left,
371 | contextScroll: isWindow ? 0 : this.oldScroll.x,
372 | contextDimension: this.innerWidth(),
373 | oldScroll: this.oldScroll.x,
374 | forward: 'right',
375 | backward: 'left',
376 | offsetProp: 'left'
377 | },
378 | vertical: {
379 | contextOffset: isWindow ? 0 : contextOffset.top,
380 | contextScroll: isWindow ? 0 : this.oldScroll.y,
381 | contextDimension: this.innerHeight(),
382 | oldScroll: this.oldScroll.y,
383 | forward: 'down',
384 | backward: 'up',
385 | offsetProp: 'top'
386 | }
387 | }
388 |
389 | for (var axisKey in axes) {
390 | var axis = axes[axisKey]
391 | for (var waypointKey in this.waypoints[axisKey]) {
392 | var waypoint = this.waypoints[axisKey][waypointKey]
393 | var adjustment = waypoint.options.offset
394 | var oldTriggerPoint = waypoint.triggerPoint
395 | var elementOffset = 0
396 | var freshWaypoint = oldTriggerPoint == null
397 | var contextModifier, wasBeforeScroll, nowAfterScroll
398 | var triggeredBackward, triggeredForward
399 |
400 | if (waypoint.element !== waypoint.element.window) {
401 | elementOffset = waypoint.adapter.offset()[axis.offsetProp]
402 | }
403 |
404 | if (typeof adjustment === 'function') {
405 | adjustment = adjustment.apply(waypoint)
406 | }
407 | else if (typeof adjustment === 'string') {
408 | adjustment = parseFloat(adjustment)
409 | if (waypoint.options.offset.indexOf('%') > - 1) {
410 | adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
411 | }
412 | }
413 |
414 | contextModifier = axis.contextScroll - axis.contextOffset
415 | waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
416 | wasBeforeScroll = oldTriggerPoint < axis.oldScroll
417 | nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
418 | triggeredBackward = wasBeforeScroll && nowAfterScroll
419 | triggeredForward = !wasBeforeScroll && !nowAfterScroll
420 |
421 | if (!freshWaypoint && triggeredBackward) {
422 | waypoint.queueTrigger(axis.backward)
423 | triggeredGroups[waypoint.group.id] = waypoint.group
424 | }
425 | else if (!freshWaypoint && triggeredForward) {
426 | waypoint.queueTrigger(axis.forward)
427 | triggeredGroups[waypoint.group.id] = waypoint.group
428 | }
429 | else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
430 | waypoint.queueTrigger(axis.forward)
431 | triggeredGroups[waypoint.group.id] = waypoint.group
432 | }
433 | }
434 | }
435 |
436 | Waypoint.requestAnimationFrame(function() {
437 | for (var groupKey in triggeredGroups) {
438 | triggeredGroups[groupKey].flushTriggers()
439 | }
440 | })
441 |
442 | return this
443 | }
444 |
445 | /* Private */
446 | Context.findOrCreateByElement = function(element) {
447 | return Context.findByElement(element) || new Context(element)
448 | }
449 |
450 | /* Private */
451 | Context.refreshAll = function() {
452 | for (var contextId in contexts) {
453 | contexts[contextId].refresh()
454 | }
455 | }
456 |
457 | /* Public */
458 | /* http://imakewebthings.com/waypoints/api/context-find-by-element */
459 | Context.findByElement = function(element) {
460 | return contexts[element.waypointContextKey]
461 | }
462 |
463 | window.onload = function() {
464 | if (oldWindowLoad) {
465 | oldWindowLoad()
466 | }
467 | Context.refreshAll()
468 | }
469 |
470 |
471 | Waypoint.requestAnimationFrame = function(callback) {
472 | var requestFn = window.requestAnimationFrame ||
473 | window.mozRequestAnimationFrame ||
474 | window.webkitRequestAnimationFrame ||
475 | requestAnimationFrameShim
476 | requestFn.call(window, callback)
477 | }
478 | Waypoint.Context = Context
479 | }())
480 | ;(function() {
481 | 'use strict'
482 |
483 | function byTriggerPoint(a, b) {
484 | return a.triggerPoint - b.triggerPoint
485 | }
486 |
487 | function byReverseTriggerPoint(a, b) {
488 | return b.triggerPoint - a.triggerPoint
489 | }
490 |
491 | var groups = {
492 | vertical: {},
493 | horizontal: {}
494 | }
495 | var Waypoint = window.Waypoint
496 |
497 | /* http://imakewebthings.com/waypoints/api/group */
498 | function Group(options) {
499 | this.name = options.name
500 | this.axis = options.axis
501 | this.id = this.name + '-' + this.axis
502 | this.waypoints = []
503 | this.clearTriggerQueues()
504 | groups[this.axis][this.name] = this
505 | }
506 |
507 | /* Private */
508 | Group.prototype.add = function(waypoint) {
509 | this.waypoints.push(waypoint)
510 | }
511 |
512 | /* Private */
513 | Group.prototype.clearTriggerQueues = function() {
514 | this.triggerQueues = {
515 | up: [],
516 | down: [],
517 | left: [],
518 | right: []
519 | }
520 | }
521 |
522 | /* Private */
523 | Group.prototype.flushTriggers = function() {
524 | for (var direction in this.triggerQueues) {
525 | var waypoints = this.triggerQueues[direction]
526 | var reverse = direction === 'up' || direction === 'left'
527 | waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
528 | for (var i = 0, end = waypoints.length; i < end; i += 1) {
529 | var waypoint = waypoints[i]
530 | if (waypoint.options.continuous || i === waypoints.length - 1) {
531 | waypoint.trigger([direction])
532 | }
533 | }
534 | }
535 | this.clearTriggerQueues()
536 | }
537 |
538 | /* Private */
539 | Group.prototype.next = function(waypoint) {
540 | this.waypoints.sort(byTriggerPoint)
541 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
542 | var isLast = index === this.waypoints.length - 1
543 | return isLast ? null : this.waypoints[index + 1]
544 | }
545 |
546 | /* Private */
547 | Group.prototype.previous = function(waypoint) {
548 | this.waypoints.sort(byTriggerPoint)
549 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
550 | return index ? this.waypoints[index - 1] : null
551 | }
552 |
553 | /* Private */
554 | Group.prototype.queueTrigger = function(waypoint, direction) {
555 | this.triggerQueues[direction].push(waypoint)
556 | }
557 |
558 | /* Private */
559 | Group.prototype.remove = function(waypoint) {
560 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
561 | if (index > -1) {
562 | this.waypoints.splice(index, 1)
563 | }
564 | }
565 |
566 | /* Public */
567 | /* http://imakewebthings.com/waypoints/api/first */
568 | Group.prototype.first = function() {
569 | return this.waypoints[0]
570 | }
571 |
572 | /* Public */
573 | /* http://imakewebthings.com/waypoints/api/last */
574 | Group.prototype.last = function() {
575 | return this.waypoints[this.waypoints.length - 1]
576 | }
577 |
578 | /* Private */
579 | Group.findOrCreate = function(options) {
580 | return groups[options.axis][options.name] || new Group(options)
581 | }
582 |
583 | Waypoint.Group = Group
584 | }())
585 | ;(function() {
586 | 'use strict'
587 |
588 | var $ = window.jQuery
589 | var Waypoint = window.Waypoint
590 |
591 | function JQueryAdapter(element) {
592 | this.$element = $(element)
593 | }
594 |
595 | $.each([
596 | 'innerHeight',
597 | 'innerWidth',
598 | 'off',
599 | 'offset',
600 | 'on',
601 | 'outerHeight',
602 | 'outerWidth',
603 | 'scrollLeft',
604 | 'scrollTop'
605 | ], function(i, method) {
606 | JQueryAdapter.prototype[method] = function() {
607 | var args = Array.prototype.slice.call(arguments)
608 | return this.$element[method].apply(this.$element, args)
609 | }
610 | })
611 |
612 | $.each([
613 | 'extend',
614 | 'inArray',
615 | 'isEmptyObject'
616 | ], function(i, method) {
617 | JQueryAdapter[method] = $[method]
618 | })
619 |
620 | Waypoint.adapters.push({
621 | name: 'jquery',
622 | Adapter: JQueryAdapter
623 | })
624 | Waypoint.Adapter = JQueryAdapter
625 | }())
626 | ;(function() {
627 | 'use strict'
628 |
629 | var Waypoint = window.Waypoint
630 |
631 | function createExtension(framework) {
632 | return function() {
633 | var waypoints = []
634 | var overrides = arguments[0]
635 |
636 | if (framework.isFunction(arguments[0])) {
637 | overrides = framework.extend({}, arguments[1])
638 | overrides.handler = arguments[0]
639 | }
640 |
641 | this.each(function() {
642 | var options = framework.extend({}, overrides, {
643 | element: this
644 | })
645 | if (typeof options.context === 'string') {
646 | options.context = framework(this).closest(options.context)[0]
647 | }
648 | waypoints.push(new Waypoint(options))
649 | })
650 |
651 | return waypoints
652 | }
653 | }
654 |
655 | if (window.jQuery) {
656 | window.jQuery.fn.waypoint = createExtension(window.jQuery)
657 | }
658 | if (window.Zepto) {
659 | window.Zepto.fn.waypoint = createExtension(window.Zepto)
660 | }
661 | }())
662 | ;
--------------------------------------------------------------------------------
/practice/lib/zepto.waypoints.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var keyCounter = 0
11 | var allWaypoints = {}
12 |
13 | /* http://imakewebthings.com/waypoints/api/waypoint */
14 | function Waypoint(options) {
15 | if (!options) {
16 | throw new Error('No options passed to Waypoint constructor')
17 | }
18 | if (!options.element) {
19 | throw new Error('No element option passed to Waypoint constructor')
20 | }
21 | if (!options.handler) {
22 | throw new Error('No handler option passed to Waypoint constructor')
23 | }
24 |
25 | this.key = 'waypoint-' + keyCounter
26 | this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
27 | this.element = this.options.element
28 | this.adapter = new Waypoint.Adapter(this.element)
29 | this.callback = options.handler
30 | this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
31 | this.enabled = this.options.enabled
32 | this.triggerPoint = null
33 | this.group = Waypoint.Group.findOrCreate({
34 | name: this.options.group,
35 | axis: this.axis
36 | })
37 | this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
38 |
39 | if (Waypoint.offsetAliases[this.options.offset]) {
40 | this.options.offset = Waypoint.offsetAliases[this.options.offset]
41 | }
42 | this.group.add(this)
43 | this.context.add(this)
44 | allWaypoints[this.key] = this
45 | keyCounter += 1
46 | }
47 |
48 | /* Private */
49 | Waypoint.prototype.queueTrigger = function(direction) {
50 | this.group.queueTrigger(this, direction)
51 | }
52 |
53 | /* Private */
54 | Waypoint.prototype.trigger = function(args) {
55 | if (!this.enabled) {
56 | return
57 | }
58 | if (this.callback) {
59 | this.callback.apply(this, args)
60 | }
61 | }
62 |
63 | /* Public */
64 | /* http://imakewebthings.com/waypoints/api/destroy */
65 | Waypoint.prototype.destroy = function() {
66 | this.context.remove(this)
67 | this.group.remove(this)
68 | delete allWaypoints[this.key]
69 | }
70 |
71 | /* Public */
72 | /* http://imakewebthings.com/waypoints/api/disable */
73 | Waypoint.prototype.disable = function() {
74 | this.enabled = false
75 | return this
76 | }
77 |
78 | /* Public */
79 | /* http://imakewebthings.com/waypoints/api/enable */
80 | Waypoint.prototype.enable = function() {
81 | this.context.refresh()
82 | this.enabled = true
83 | return this
84 | }
85 |
86 | /* Public */
87 | /* http://imakewebthings.com/waypoints/api/next */
88 | Waypoint.prototype.next = function() {
89 | return this.group.next(this)
90 | }
91 |
92 | /* Public */
93 | /* http://imakewebthings.com/waypoints/api/previous */
94 | Waypoint.prototype.previous = function() {
95 | return this.group.previous(this)
96 | }
97 |
98 | /* Private */
99 | Waypoint.invokeAll = function(method) {
100 | var allWaypointsArray = []
101 | for (var waypointKey in allWaypoints) {
102 | allWaypointsArray.push(allWaypoints[waypointKey])
103 | }
104 | for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
105 | allWaypointsArray[i][method]()
106 | }
107 | }
108 |
109 | /* Public */
110 | /* http://imakewebthings.com/waypoints/api/destroy-all */
111 | Waypoint.destroyAll = function() {
112 | Waypoint.invokeAll('destroy')
113 | }
114 |
115 | /* Public */
116 | /* http://imakewebthings.com/waypoints/api/disable-all */
117 | Waypoint.disableAll = function() {
118 | Waypoint.invokeAll('disable')
119 | }
120 |
121 | /* Public */
122 | /* http://imakewebthings.com/waypoints/api/enable-all */
123 | Waypoint.enableAll = function() {
124 | Waypoint.Context.refreshAll()
125 | for (var waypointKey in allWaypoints) {
126 | allWaypoints[waypointKey].enabled = true
127 | }
128 | return this
129 | }
130 |
131 | /* Public */
132 | /* http://imakewebthings.com/waypoints/api/refresh-all */
133 | Waypoint.refreshAll = function() {
134 | Waypoint.Context.refreshAll()
135 | }
136 |
137 | /* Public */
138 | /* http://imakewebthings.com/waypoints/api/viewport-height */
139 | Waypoint.viewportHeight = function() {
140 | return window.innerHeight || document.documentElement.clientHeight
141 | }
142 |
143 | /* Public */
144 | /* http://imakewebthings.com/waypoints/api/viewport-width */
145 | Waypoint.viewportWidth = function() {
146 | return document.documentElement.clientWidth
147 | }
148 |
149 | Waypoint.adapters = []
150 |
151 | Waypoint.defaults = {
152 | context: window,
153 | continuous: true,
154 | enabled: true,
155 | group: 'default',
156 | horizontal: false,
157 | offset: 0
158 | }
159 |
160 | Waypoint.offsetAliases = {
161 | 'bottom-in-view': function() {
162 | return this.context.innerHeight() - this.adapter.outerHeight()
163 | },
164 | 'right-in-view': function() {
165 | return this.context.innerWidth() - this.adapter.outerWidth()
166 | }
167 | }
168 |
169 | window.Waypoint = Waypoint
170 | }())
171 | ;(function() {
172 | 'use strict'
173 |
174 | function requestAnimationFrameShim(callback) {
175 | window.setTimeout(callback, 1000 / 60)
176 | }
177 |
178 | var keyCounter = 0
179 | var contexts = {}
180 | var Waypoint = window.Waypoint
181 | var oldWindowLoad = window.onload
182 |
183 | /* http://imakewebthings.com/waypoints/api/context */
184 | function Context(element) {
185 | this.element = element
186 | this.Adapter = Waypoint.Adapter
187 | this.adapter = new this.Adapter(element)
188 | this.key = 'waypoint-context-' + keyCounter
189 | this.didScroll = false
190 | this.didResize = false
191 | this.oldScroll = {
192 | x: this.adapter.scrollLeft(),
193 | y: this.adapter.scrollTop()
194 | }
195 | this.waypoints = {
196 | vertical: {},
197 | horizontal: {}
198 | }
199 |
200 | element.waypointContextKey = this.key
201 | contexts[element.waypointContextKey] = this
202 | keyCounter += 1
203 | if (!Waypoint.windowContext) {
204 | Waypoint.windowContext = true
205 | Waypoint.windowContext = new Context(window)
206 | }
207 |
208 | this.createThrottledScrollHandler()
209 | this.createThrottledResizeHandler()
210 | }
211 |
212 | /* Private */
213 | Context.prototype.add = function(waypoint) {
214 | var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
215 | this.waypoints[axis][waypoint.key] = waypoint
216 | this.refresh()
217 | }
218 |
219 | /* Private */
220 | Context.prototype.checkEmpty = function() {
221 | var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
222 | var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
223 | var isWindow = this.element == this.element.window
224 | if (horizontalEmpty && verticalEmpty && !isWindow) {
225 | this.adapter.off('.waypoints')
226 | delete contexts[this.key]
227 | }
228 | }
229 |
230 | /* Private */
231 | Context.prototype.createThrottledResizeHandler = function() {
232 | var self = this
233 |
234 | function resizeHandler() {
235 | self.handleResize()
236 | self.didResize = false
237 | }
238 |
239 | this.adapter.on('resize.waypoints', function() {
240 | if (!self.didResize) {
241 | self.didResize = true
242 | Waypoint.requestAnimationFrame(resizeHandler)
243 | }
244 | })
245 | }
246 |
247 | /* Private */
248 | Context.prototype.createThrottledScrollHandler = function() {
249 | var self = this
250 | function scrollHandler() {
251 | self.handleScroll()
252 | self.didScroll = false
253 | }
254 |
255 | this.adapter.on('scroll.waypoints', function() {
256 | if (!self.didScroll || Waypoint.isTouch) {
257 | self.didScroll = true
258 | Waypoint.requestAnimationFrame(scrollHandler)
259 | }
260 | })
261 | }
262 |
263 | /* Private */
264 | Context.prototype.handleResize = function() {
265 | Waypoint.Context.refreshAll()
266 | }
267 |
268 | /* Private */
269 | Context.prototype.handleScroll = function() {
270 | var triggeredGroups = {}
271 | var axes = {
272 | horizontal: {
273 | newScroll: this.adapter.scrollLeft(),
274 | oldScroll: this.oldScroll.x,
275 | forward: 'right',
276 | backward: 'left'
277 | },
278 | vertical: {
279 | newScroll: this.adapter.scrollTop(),
280 | oldScroll: this.oldScroll.y,
281 | forward: 'down',
282 | backward: 'up'
283 | }
284 | }
285 |
286 | for (var axisKey in axes) {
287 | var axis = axes[axisKey]
288 | var isForward = axis.newScroll > axis.oldScroll
289 | var direction = isForward ? axis.forward : axis.backward
290 |
291 | for (var waypointKey in this.waypoints[axisKey]) {
292 | var waypoint = this.waypoints[axisKey][waypointKey]
293 | if (waypoint.triggerPoint === null) {
294 | continue
295 | }
296 | var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
297 | var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
298 | var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
299 | var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
300 | if (crossedForward || crossedBackward) {
301 | waypoint.queueTrigger(direction)
302 | triggeredGroups[waypoint.group.id] = waypoint.group
303 | }
304 | }
305 | }
306 |
307 | for (var groupKey in triggeredGroups) {
308 | triggeredGroups[groupKey].flushTriggers()
309 | }
310 |
311 | this.oldScroll = {
312 | x: axes.horizontal.newScroll,
313 | y: axes.vertical.newScroll
314 | }
315 | }
316 |
317 | /* Private */
318 | Context.prototype.innerHeight = function() {
319 | /*eslint-disable eqeqeq */
320 | if (this.element == this.element.window) {
321 | return Waypoint.viewportHeight()
322 | }
323 | /*eslint-enable eqeqeq */
324 | return this.adapter.innerHeight()
325 | }
326 |
327 | /* Private */
328 | Context.prototype.remove = function(waypoint) {
329 | delete this.waypoints[waypoint.axis][waypoint.key]
330 | this.checkEmpty()
331 | }
332 |
333 | /* Private */
334 | Context.prototype.innerWidth = function() {
335 | /*eslint-disable eqeqeq */
336 | if (this.element == this.element.window) {
337 | return Waypoint.viewportWidth()
338 | }
339 | /*eslint-enable eqeqeq */
340 | return this.adapter.innerWidth()
341 | }
342 |
343 | /* Public */
344 | /* http://imakewebthings.com/waypoints/api/context-destroy */
345 | Context.prototype.destroy = function() {
346 | var allWaypoints = []
347 | for (var axis in this.waypoints) {
348 | for (var waypointKey in this.waypoints[axis]) {
349 | allWaypoints.push(this.waypoints[axis][waypointKey])
350 | }
351 | }
352 | for (var i = 0, end = allWaypoints.length; i < end; i++) {
353 | allWaypoints[i].destroy()
354 | }
355 | }
356 |
357 | /* Public */
358 | /* http://imakewebthings.com/waypoints/api/context-refresh */
359 | Context.prototype.refresh = function() {
360 | /*eslint-disable eqeqeq */
361 | var isWindow = this.element == this.element.window
362 | /*eslint-enable eqeqeq */
363 | var contextOffset = isWindow ? undefined : this.adapter.offset()
364 | var triggeredGroups = {}
365 | var axes
366 |
367 | this.handleScroll()
368 | axes = {
369 | horizontal: {
370 | contextOffset: isWindow ? 0 : contextOffset.left,
371 | contextScroll: isWindow ? 0 : this.oldScroll.x,
372 | contextDimension: this.innerWidth(),
373 | oldScroll: this.oldScroll.x,
374 | forward: 'right',
375 | backward: 'left',
376 | offsetProp: 'left'
377 | },
378 | vertical: {
379 | contextOffset: isWindow ? 0 : contextOffset.top,
380 | contextScroll: isWindow ? 0 : this.oldScroll.y,
381 | contextDimension: this.innerHeight(),
382 | oldScroll: this.oldScroll.y,
383 | forward: 'down',
384 | backward: 'up',
385 | offsetProp: 'top'
386 | }
387 | }
388 |
389 | for (var axisKey in axes) {
390 | var axis = axes[axisKey]
391 | for (var waypointKey in this.waypoints[axisKey]) {
392 | var waypoint = this.waypoints[axisKey][waypointKey]
393 | var adjustment = waypoint.options.offset
394 | var oldTriggerPoint = waypoint.triggerPoint
395 | var elementOffset = 0
396 | var freshWaypoint = oldTriggerPoint == null
397 | var contextModifier, wasBeforeScroll, nowAfterScroll
398 | var triggeredBackward, triggeredForward
399 |
400 | if (waypoint.element !== waypoint.element.window) {
401 | elementOffset = waypoint.adapter.offset()[axis.offsetProp]
402 | }
403 |
404 | if (typeof adjustment === 'function') {
405 | adjustment = adjustment.apply(waypoint)
406 | }
407 | else if (typeof adjustment === 'string') {
408 | adjustment = parseFloat(adjustment)
409 | if (waypoint.options.offset.indexOf('%') > - 1) {
410 | adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
411 | }
412 | }
413 |
414 | contextModifier = axis.contextScroll - axis.contextOffset
415 | waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
416 | wasBeforeScroll = oldTriggerPoint < axis.oldScroll
417 | nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
418 | triggeredBackward = wasBeforeScroll && nowAfterScroll
419 | triggeredForward = !wasBeforeScroll && !nowAfterScroll
420 |
421 | if (!freshWaypoint && triggeredBackward) {
422 | waypoint.queueTrigger(axis.backward)
423 | triggeredGroups[waypoint.group.id] = waypoint.group
424 | }
425 | else if (!freshWaypoint && triggeredForward) {
426 | waypoint.queueTrigger(axis.forward)
427 | triggeredGroups[waypoint.group.id] = waypoint.group
428 | }
429 | else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
430 | waypoint.queueTrigger(axis.forward)
431 | triggeredGroups[waypoint.group.id] = waypoint.group
432 | }
433 | }
434 | }
435 |
436 | Waypoint.requestAnimationFrame(function() {
437 | for (var groupKey in triggeredGroups) {
438 | triggeredGroups[groupKey].flushTriggers()
439 | }
440 | })
441 |
442 | return this
443 | }
444 |
445 | /* Private */
446 | Context.findOrCreateByElement = function(element) {
447 | return Context.findByElement(element) || new Context(element)
448 | }
449 |
450 | /* Private */
451 | Context.refreshAll = function() {
452 | for (var contextId in contexts) {
453 | contexts[contextId].refresh()
454 | }
455 | }
456 |
457 | /* Public */
458 | /* http://imakewebthings.com/waypoints/api/context-find-by-element */
459 | Context.findByElement = function(element) {
460 | return contexts[element.waypointContextKey]
461 | }
462 |
463 | window.onload = function() {
464 | if (oldWindowLoad) {
465 | oldWindowLoad()
466 | }
467 | Context.refreshAll()
468 | }
469 |
470 |
471 | Waypoint.requestAnimationFrame = function(callback) {
472 | var requestFn = window.requestAnimationFrame ||
473 | window.mozRequestAnimationFrame ||
474 | window.webkitRequestAnimationFrame ||
475 | requestAnimationFrameShim
476 | requestFn.call(window, callback)
477 | }
478 | Waypoint.Context = Context
479 | }())
480 | ;(function() {
481 | 'use strict'
482 |
483 | function byTriggerPoint(a, b) {
484 | return a.triggerPoint - b.triggerPoint
485 | }
486 |
487 | function byReverseTriggerPoint(a, b) {
488 | return b.triggerPoint - a.triggerPoint
489 | }
490 |
491 | var groups = {
492 | vertical: {},
493 | horizontal: {}
494 | }
495 | var Waypoint = window.Waypoint
496 |
497 | /* http://imakewebthings.com/waypoints/api/group */
498 | function Group(options) {
499 | this.name = options.name
500 | this.axis = options.axis
501 | this.id = this.name + '-' + this.axis
502 | this.waypoints = []
503 | this.clearTriggerQueues()
504 | groups[this.axis][this.name] = this
505 | }
506 |
507 | /* Private */
508 | Group.prototype.add = function(waypoint) {
509 | this.waypoints.push(waypoint)
510 | }
511 |
512 | /* Private */
513 | Group.prototype.clearTriggerQueues = function() {
514 | this.triggerQueues = {
515 | up: [],
516 | down: [],
517 | left: [],
518 | right: []
519 | }
520 | }
521 |
522 | /* Private */
523 | Group.prototype.flushTriggers = function() {
524 | for (var direction in this.triggerQueues) {
525 | var waypoints = this.triggerQueues[direction]
526 | var reverse = direction === 'up' || direction === 'left'
527 | waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
528 | for (var i = 0, end = waypoints.length; i < end; i += 1) {
529 | var waypoint = waypoints[i]
530 | if (waypoint.options.continuous || i === waypoints.length - 1) {
531 | waypoint.trigger([direction])
532 | }
533 | }
534 | }
535 | this.clearTriggerQueues()
536 | }
537 |
538 | /* Private */
539 | Group.prototype.next = function(waypoint) {
540 | this.waypoints.sort(byTriggerPoint)
541 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
542 | var isLast = index === this.waypoints.length - 1
543 | return isLast ? null : this.waypoints[index + 1]
544 | }
545 |
546 | /* Private */
547 | Group.prototype.previous = function(waypoint) {
548 | this.waypoints.sort(byTriggerPoint)
549 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
550 | return index ? this.waypoints[index - 1] : null
551 | }
552 |
553 | /* Private */
554 | Group.prototype.queueTrigger = function(waypoint, direction) {
555 | this.triggerQueues[direction].push(waypoint)
556 | }
557 |
558 | /* Private */
559 | Group.prototype.remove = function(waypoint) {
560 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
561 | if (index > -1) {
562 | this.waypoints.splice(index, 1)
563 | }
564 | }
565 |
566 | /* Public */
567 | /* http://imakewebthings.com/waypoints/api/first */
568 | Group.prototype.first = function() {
569 | return this.waypoints[0]
570 | }
571 |
572 | /* Public */
573 | /* http://imakewebthings.com/waypoints/api/last */
574 | Group.prototype.last = function() {
575 | return this.waypoints[this.waypoints.length - 1]
576 | }
577 |
578 | /* Private */
579 | Group.findOrCreate = function(options) {
580 | return groups[options.axis][options.name] || new Group(options)
581 | }
582 |
583 | Waypoint.Group = Group
584 | }())
585 | ;(function() {
586 | 'use strict'
587 |
588 | var $ = window.Zepto
589 | var Waypoint = window.Waypoint
590 |
591 | function ZeptoAdapter(element) {
592 | this.element = element
593 | this.$element = $(element)
594 | }
595 |
596 | $.each([
597 | 'off',
598 | 'on',
599 | 'scrollLeft',
600 | 'scrollTop'
601 | ], function(i, method) {
602 | ZeptoAdapter.prototype[method] = function() {
603 | var args = Array.prototype.slice.call(arguments)
604 | return this.$element[method].apply(this.$element, args)
605 | }
606 | })
607 |
608 | ZeptoAdapter.prototype.offset = function() {
609 | if (this.element !== this.element.window) {
610 | return this.$element.offset()
611 | }
612 | }
613 |
614 | // Adapted from https://gist.github.com/wheresrhys/5823198
615 | $.each([
616 | 'width',
617 | 'height'
618 | ], function(i, dimension) {
619 | function createDimensionMethod($element, includeBorder) {
620 | return function(includeMargin) {
621 | var $element = this.$element
622 | var size = $element[dimension]()
623 | var sides = {
624 | width: ['left', 'right'],
625 | height: ['top', 'bottom']
626 | }
627 |
628 | $.each(sides[dimension], function(i, side) {
629 | size += parseInt($element.css('padding-' + side), 10)
630 | if (includeBorder) {
631 | size += parseInt($element.css('border-' + side + '-width'), 10)
632 | }
633 | if (includeMargin) {
634 | size += parseInt($element.css('margin-' + side), 10)
635 | }
636 | })
637 | return size
638 | }
639 | }
640 |
641 | var innerMethod = $.camelCase('inner-' + dimension)
642 | var outerMethod = $.camelCase('outer-' + dimension)
643 |
644 | ZeptoAdapter.prototype[innerMethod] = createDimensionMethod(false)
645 | ZeptoAdapter.prototype[outerMethod] = createDimensionMethod(true)
646 | })
647 |
648 | $.each([
649 | 'extend',
650 | 'inArray'
651 | ], function(i, method) {
652 | ZeptoAdapter[method] = $[method]
653 | })
654 |
655 | ZeptoAdapter.isEmptyObject = function(obj) {
656 | /* eslint no-unused-vars: 0 */
657 | for (var name in obj) {
658 | return false
659 | }
660 | return true
661 | }
662 |
663 | Waypoint.adapters.push({
664 | name: 'zepto',
665 | Adapter: ZeptoAdapter
666 | })
667 | Waypoint.Adapter = ZeptoAdapter
668 | }())
669 | ;(function() {
670 | 'use strict'
671 |
672 | var Waypoint = window.Waypoint
673 |
674 | function createExtension(framework) {
675 | return function() {
676 | var waypoints = []
677 | var overrides = arguments[0]
678 |
679 | if (framework.isFunction(arguments[0])) {
680 | overrides = framework.extend({}, arguments[1])
681 | overrides.handler = arguments[0]
682 | }
683 |
684 | this.each(function() {
685 | var options = framework.extend({}, overrides, {
686 | element: this
687 | })
688 | if (typeof options.context === 'string') {
689 | options.context = framework(this).closest(options.context)[0]
690 | }
691 | waypoints.push(new Waypoint(options))
692 | })
693 |
694 | return waypoints
695 | }
696 | }
697 |
698 | if (window.jQuery) {
699 | window.jQuery.fn.waypoint = createExtension(window.jQuery)
700 | }
701 | if (window.Zepto) {
702 | window.Zepto.fn.waypoint = createExtension(window.Zepto)
703 | }
704 | }())
705 | ;
--------------------------------------------------------------------------------
/practice/lib/noframework.waypoints.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Waypoints - 4.0.1
3 | Copyright © 2011-2016 Caleb Troughton
4 | Licensed under the MIT license.
5 | https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6 | */
7 | (function() {
8 | 'use strict'
9 |
10 | var keyCounter = 0
11 | var allWaypoints = {}
12 |
13 | /* http://imakewebthings.com/waypoints/api/waypoint */
14 | function Waypoint(options) {
15 | if (!options) {
16 | throw new Error('No options passed to Waypoint constructor')
17 | }
18 | if (!options.element) {
19 | throw new Error('No element option passed to Waypoint constructor')
20 | }
21 | if (!options.handler) {
22 | throw new Error('No handler option passed to Waypoint constructor')
23 | }
24 |
25 | this.key = 'waypoint-' + keyCounter
26 | this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
27 | this.element = this.options.element
28 | this.adapter = new Waypoint.Adapter(this.element)
29 | this.callback = options.handler
30 | this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
31 | this.enabled = this.options.enabled
32 | this.triggerPoint = null
33 | this.group = Waypoint.Group.findOrCreate({
34 | name: this.options.group,
35 | axis: this.axis
36 | })
37 | this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
38 |
39 | if (Waypoint.offsetAliases[this.options.offset]) {
40 | this.options.offset = Waypoint.offsetAliases[this.options.offset]
41 | }
42 | this.group.add(this)
43 | this.context.add(this)
44 | allWaypoints[this.key] = this
45 | keyCounter += 1
46 | }
47 |
48 | /* Private */
49 | Waypoint.prototype.queueTrigger = function(direction) {
50 | this.group.queueTrigger(this, direction)
51 | }
52 |
53 | /* Private */
54 | Waypoint.prototype.trigger = function(args) {
55 | if (!this.enabled) {
56 | return
57 | }
58 | if (this.callback) {
59 | this.callback.apply(this, args)
60 | }
61 | }
62 |
63 | /* Public */
64 | /* http://imakewebthings.com/waypoints/api/destroy */
65 | Waypoint.prototype.destroy = function() {
66 | this.context.remove(this)
67 | this.group.remove(this)
68 | delete allWaypoints[this.key]
69 | }
70 |
71 | /* Public */
72 | /* http://imakewebthings.com/waypoints/api/disable */
73 | Waypoint.prototype.disable = function() {
74 | this.enabled = false
75 | return this
76 | }
77 |
78 | /* Public */
79 | /* http://imakewebthings.com/waypoints/api/enable */
80 | Waypoint.prototype.enable = function() {
81 | this.context.refresh()
82 | this.enabled = true
83 | return this
84 | }
85 |
86 | /* Public */
87 | /* http://imakewebthings.com/waypoints/api/next */
88 | Waypoint.prototype.next = function() {
89 | return this.group.next(this)
90 | }
91 |
92 | /* Public */
93 | /* http://imakewebthings.com/waypoints/api/previous */
94 | Waypoint.prototype.previous = function() {
95 | return this.group.previous(this)
96 | }
97 |
98 | /* Private */
99 | Waypoint.invokeAll = function(method) {
100 | var allWaypointsArray = []
101 | for (var waypointKey in allWaypoints) {
102 | allWaypointsArray.push(allWaypoints[waypointKey])
103 | }
104 | for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
105 | allWaypointsArray[i][method]()
106 | }
107 | }
108 |
109 | /* Public */
110 | /* http://imakewebthings.com/waypoints/api/destroy-all */
111 | Waypoint.destroyAll = function() {
112 | Waypoint.invokeAll('destroy')
113 | }
114 |
115 | /* Public */
116 | /* http://imakewebthings.com/waypoints/api/disable-all */
117 | Waypoint.disableAll = function() {
118 | Waypoint.invokeAll('disable')
119 | }
120 |
121 | /* Public */
122 | /* http://imakewebthings.com/waypoints/api/enable-all */
123 | Waypoint.enableAll = function() {
124 | Waypoint.Context.refreshAll()
125 | for (var waypointKey in allWaypoints) {
126 | allWaypoints[waypointKey].enabled = true
127 | }
128 | return this
129 | }
130 |
131 | /* Public */
132 | /* http://imakewebthings.com/waypoints/api/refresh-all */
133 | Waypoint.refreshAll = function() {
134 | Waypoint.Context.refreshAll()
135 | }
136 |
137 | /* Public */
138 | /* http://imakewebthings.com/waypoints/api/viewport-height */
139 | Waypoint.viewportHeight = function() {
140 | return window.innerHeight || document.documentElement.clientHeight
141 | }
142 |
143 | /* Public */
144 | /* http://imakewebthings.com/waypoints/api/viewport-width */
145 | Waypoint.viewportWidth = function() {
146 | return document.documentElement.clientWidth
147 | }
148 |
149 | Waypoint.adapters = []
150 |
151 | Waypoint.defaults = {
152 | context: window,
153 | continuous: true,
154 | enabled: true,
155 | group: 'default',
156 | horizontal: false,
157 | offset: 0
158 | }
159 |
160 | Waypoint.offsetAliases = {
161 | 'bottom-in-view': function() {
162 | return this.context.innerHeight() - this.adapter.outerHeight()
163 | },
164 | 'right-in-view': function() {
165 | return this.context.innerWidth() - this.adapter.outerWidth()
166 | }
167 | }
168 |
169 | window.Waypoint = Waypoint
170 | }())
171 | ;(function() {
172 | 'use strict'
173 |
174 | function requestAnimationFrameShim(callback) {
175 | window.setTimeout(callback, 1000 / 60)
176 | }
177 |
178 | var keyCounter = 0
179 | var contexts = {}
180 | var Waypoint = window.Waypoint
181 | var oldWindowLoad = window.onload
182 |
183 | /* http://imakewebthings.com/waypoints/api/context */
184 | function Context(element) {
185 | this.element = element
186 | this.Adapter = Waypoint.Adapter
187 | this.adapter = new this.Adapter(element)
188 | this.key = 'waypoint-context-' + keyCounter
189 | this.didScroll = false
190 | this.didResize = false
191 | this.oldScroll = {
192 | x: this.adapter.scrollLeft(),
193 | y: this.adapter.scrollTop()
194 | }
195 | this.waypoints = {
196 | vertical: {},
197 | horizontal: {}
198 | }
199 |
200 | element.waypointContextKey = this.key
201 | contexts[element.waypointContextKey] = this
202 | keyCounter += 1
203 | if (!Waypoint.windowContext) {
204 | Waypoint.windowContext = true
205 | Waypoint.windowContext = new Context(window)
206 | }
207 |
208 | this.createThrottledScrollHandler()
209 | this.createThrottledResizeHandler()
210 | }
211 |
212 | /* Private */
213 | Context.prototype.add = function(waypoint) {
214 | var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
215 | this.waypoints[axis][waypoint.key] = waypoint
216 | this.refresh()
217 | }
218 |
219 | /* Private */
220 | Context.prototype.checkEmpty = function() {
221 | var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
222 | var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
223 | var isWindow = this.element == this.element.window
224 | if (horizontalEmpty && verticalEmpty && !isWindow) {
225 | this.adapter.off('.waypoints')
226 | delete contexts[this.key]
227 | }
228 | }
229 |
230 | /* Private */
231 | Context.prototype.createThrottledResizeHandler = function() {
232 | var self = this
233 |
234 | function resizeHandler() {
235 | self.handleResize()
236 | self.didResize = false
237 | }
238 |
239 | this.adapter.on('resize.waypoints', function() {
240 | if (!self.didResize) {
241 | self.didResize = true
242 | Waypoint.requestAnimationFrame(resizeHandler)
243 | }
244 | })
245 | }
246 |
247 | /* Private */
248 | Context.prototype.createThrottledScrollHandler = function() {
249 | var self = this
250 | function scrollHandler() {
251 | self.handleScroll()
252 | self.didScroll = false
253 | }
254 |
255 | this.adapter.on('scroll.waypoints', function() {
256 | if (!self.didScroll || Waypoint.isTouch) {
257 | self.didScroll = true
258 | Waypoint.requestAnimationFrame(scrollHandler)
259 | }
260 | })
261 | }
262 |
263 | /* Private */
264 | Context.prototype.handleResize = function() {
265 | Waypoint.Context.refreshAll()
266 | }
267 |
268 | /* Private */
269 | Context.prototype.handleScroll = function() {
270 | var triggeredGroups = {}
271 | var axes = {
272 | horizontal: {
273 | newScroll: this.adapter.scrollLeft(),
274 | oldScroll: this.oldScroll.x,
275 | forward: 'right',
276 | backward: 'left'
277 | },
278 | vertical: {
279 | newScroll: this.adapter.scrollTop(),
280 | oldScroll: this.oldScroll.y,
281 | forward: 'down',
282 | backward: 'up'
283 | }
284 | }
285 |
286 | for (var axisKey in axes) {
287 | var axis = axes[axisKey]
288 | var isForward = axis.newScroll > axis.oldScroll
289 | var direction = isForward ? axis.forward : axis.backward
290 |
291 | for (var waypointKey in this.waypoints[axisKey]) {
292 | var waypoint = this.waypoints[axisKey][waypointKey]
293 | if (waypoint.triggerPoint === null) {
294 | continue
295 | }
296 | var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
297 | var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
298 | var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
299 | var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
300 | if (crossedForward || crossedBackward) {
301 | waypoint.queueTrigger(direction)
302 | triggeredGroups[waypoint.group.id] = waypoint.group
303 | }
304 | }
305 | }
306 |
307 | for (var groupKey in triggeredGroups) {
308 | triggeredGroups[groupKey].flushTriggers()
309 | }
310 |
311 | this.oldScroll = {
312 | x: axes.horizontal.newScroll,
313 | y: axes.vertical.newScroll
314 | }
315 | }
316 |
317 | /* Private */
318 | Context.prototype.innerHeight = function() {
319 | /*eslint-disable eqeqeq */
320 | if (this.element == this.element.window) {
321 | return Waypoint.viewportHeight()
322 | }
323 | /*eslint-enable eqeqeq */
324 | return this.adapter.innerHeight()
325 | }
326 |
327 | /* Private */
328 | Context.prototype.remove = function(waypoint) {
329 | delete this.waypoints[waypoint.axis][waypoint.key]
330 | this.checkEmpty()
331 | }
332 |
333 | /* Private */
334 | Context.prototype.innerWidth = function() {
335 | /*eslint-disable eqeqeq */
336 | if (this.element == this.element.window) {
337 | return Waypoint.viewportWidth()
338 | }
339 | /*eslint-enable eqeqeq */
340 | return this.adapter.innerWidth()
341 | }
342 |
343 | /* Public */
344 | /* http://imakewebthings.com/waypoints/api/context-destroy */
345 | Context.prototype.destroy = function() {
346 | var allWaypoints = []
347 | for (var axis in this.waypoints) {
348 | for (var waypointKey in this.waypoints[axis]) {
349 | allWaypoints.push(this.waypoints[axis][waypointKey])
350 | }
351 | }
352 | for (var i = 0, end = allWaypoints.length; i < end; i++) {
353 | allWaypoints[i].destroy()
354 | }
355 | }
356 |
357 | /* Public */
358 | /* http://imakewebthings.com/waypoints/api/context-refresh */
359 | Context.prototype.refresh = function() {
360 | /*eslint-disable eqeqeq */
361 | var isWindow = this.element == this.element.window
362 | /*eslint-enable eqeqeq */
363 | var contextOffset = isWindow ? undefined : this.adapter.offset()
364 | var triggeredGroups = {}
365 | var axes
366 |
367 | this.handleScroll()
368 | axes = {
369 | horizontal: {
370 | contextOffset: isWindow ? 0 : contextOffset.left,
371 | contextScroll: isWindow ? 0 : this.oldScroll.x,
372 | contextDimension: this.innerWidth(),
373 | oldScroll: this.oldScroll.x,
374 | forward: 'right',
375 | backward: 'left',
376 | offsetProp: 'left'
377 | },
378 | vertical: {
379 | contextOffset: isWindow ? 0 : contextOffset.top,
380 | contextScroll: isWindow ? 0 : this.oldScroll.y,
381 | contextDimension: this.innerHeight(),
382 | oldScroll: this.oldScroll.y,
383 | forward: 'down',
384 | backward: 'up',
385 | offsetProp: 'top'
386 | }
387 | }
388 |
389 | for (var axisKey in axes) {
390 | var axis = axes[axisKey]
391 | for (var waypointKey in this.waypoints[axisKey]) {
392 | var waypoint = this.waypoints[axisKey][waypointKey]
393 | var adjustment = waypoint.options.offset
394 | var oldTriggerPoint = waypoint.triggerPoint
395 | var elementOffset = 0
396 | var freshWaypoint = oldTriggerPoint == null
397 | var contextModifier, wasBeforeScroll, nowAfterScroll
398 | var triggeredBackward, triggeredForward
399 |
400 | if (waypoint.element !== waypoint.element.window) {
401 | elementOffset = waypoint.adapter.offset()[axis.offsetProp]
402 | }
403 |
404 | if (typeof adjustment === 'function') {
405 | adjustment = adjustment.apply(waypoint)
406 | }
407 | else if (typeof adjustment === 'string') {
408 | adjustment = parseFloat(adjustment)
409 | if (waypoint.options.offset.indexOf('%') > - 1) {
410 | adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
411 | }
412 | }
413 |
414 | contextModifier = axis.contextScroll - axis.contextOffset
415 | waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
416 | wasBeforeScroll = oldTriggerPoint < axis.oldScroll
417 | nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
418 | triggeredBackward = wasBeforeScroll && nowAfterScroll
419 | triggeredForward = !wasBeforeScroll && !nowAfterScroll
420 |
421 | if (!freshWaypoint && triggeredBackward) {
422 | waypoint.queueTrigger(axis.backward)
423 | triggeredGroups[waypoint.group.id] = waypoint.group
424 | }
425 | else if (!freshWaypoint && triggeredForward) {
426 | waypoint.queueTrigger(axis.forward)
427 | triggeredGroups[waypoint.group.id] = waypoint.group
428 | }
429 | else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
430 | waypoint.queueTrigger(axis.forward)
431 | triggeredGroups[waypoint.group.id] = waypoint.group
432 | }
433 | }
434 | }
435 |
436 | Waypoint.requestAnimationFrame(function() {
437 | for (var groupKey in triggeredGroups) {
438 | triggeredGroups[groupKey].flushTriggers()
439 | }
440 | })
441 |
442 | return this
443 | }
444 |
445 | /* Private */
446 | Context.findOrCreateByElement = function(element) {
447 | return Context.findByElement(element) || new Context(element)
448 | }
449 |
450 | /* Private */
451 | Context.refreshAll = function() {
452 | for (var contextId in contexts) {
453 | contexts[contextId].refresh()
454 | }
455 | }
456 |
457 | /* Public */
458 | /* http://imakewebthings.com/waypoints/api/context-find-by-element */
459 | Context.findByElement = function(element) {
460 | return contexts[element.waypointContextKey]
461 | }
462 |
463 | window.onload = function() {
464 | if (oldWindowLoad) {
465 | oldWindowLoad()
466 | }
467 | Context.refreshAll()
468 | }
469 |
470 |
471 | Waypoint.requestAnimationFrame = function(callback) {
472 | var requestFn = window.requestAnimationFrame ||
473 | window.mozRequestAnimationFrame ||
474 | window.webkitRequestAnimationFrame ||
475 | requestAnimationFrameShim
476 | requestFn.call(window, callback)
477 | }
478 | Waypoint.Context = Context
479 | }())
480 | ;(function() {
481 | 'use strict'
482 |
483 | function byTriggerPoint(a, b) {
484 | return a.triggerPoint - b.triggerPoint
485 | }
486 |
487 | function byReverseTriggerPoint(a, b) {
488 | return b.triggerPoint - a.triggerPoint
489 | }
490 |
491 | var groups = {
492 | vertical: {},
493 | horizontal: {}
494 | }
495 | var Waypoint = window.Waypoint
496 |
497 | /* http://imakewebthings.com/waypoints/api/group */
498 | function Group(options) {
499 | this.name = options.name
500 | this.axis = options.axis
501 | this.id = this.name + '-' + this.axis
502 | this.waypoints = []
503 | this.clearTriggerQueues()
504 | groups[this.axis][this.name] = this
505 | }
506 |
507 | /* Private */
508 | Group.prototype.add = function(waypoint) {
509 | this.waypoints.push(waypoint)
510 | }
511 |
512 | /* Private */
513 | Group.prototype.clearTriggerQueues = function() {
514 | this.triggerQueues = {
515 | up: [],
516 | down: [],
517 | left: [],
518 | right: []
519 | }
520 | }
521 |
522 | /* Private */
523 | Group.prototype.flushTriggers = function() {
524 | for (var direction in this.triggerQueues) {
525 | var waypoints = this.triggerQueues[direction]
526 | var reverse = direction === 'up' || direction === 'left'
527 | waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
528 | for (var i = 0, end = waypoints.length; i < end; i += 1) {
529 | var waypoint = waypoints[i]
530 | if (waypoint.options.continuous || i === waypoints.length - 1) {
531 | waypoint.trigger([direction])
532 | }
533 | }
534 | }
535 | this.clearTriggerQueues()
536 | }
537 |
538 | /* Private */
539 | Group.prototype.next = function(waypoint) {
540 | this.waypoints.sort(byTriggerPoint)
541 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
542 | var isLast = index === this.waypoints.length - 1
543 | return isLast ? null : this.waypoints[index + 1]
544 | }
545 |
546 | /* Private */
547 | Group.prototype.previous = function(waypoint) {
548 | this.waypoints.sort(byTriggerPoint)
549 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
550 | return index ? this.waypoints[index - 1] : null
551 | }
552 |
553 | /* Private */
554 | Group.prototype.queueTrigger = function(waypoint, direction) {
555 | this.triggerQueues[direction].push(waypoint)
556 | }
557 |
558 | /* Private */
559 | Group.prototype.remove = function(waypoint) {
560 | var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
561 | if (index > -1) {
562 | this.waypoints.splice(index, 1)
563 | }
564 | }
565 |
566 | /* Public */
567 | /* http://imakewebthings.com/waypoints/api/first */
568 | Group.prototype.first = function() {
569 | return this.waypoints[0]
570 | }
571 |
572 | /* Public */
573 | /* http://imakewebthings.com/waypoints/api/last */
574 | Group.prototype.last = function() {
575 | return this.waypoints[this.waypoints.length - 1]
576 | }
577 |
578 | /* Private */
579 | Group.findOrCreate = function(options) {
580 | return groups[options.axis][options.name] || new Group(options)
581 | }
582 |
583 | Waypoint.Group = Group
584 | }())
585 | ;(function() {
586 | 'use strict'
587 |
588 | var Waypoint = window.Waypoint
589 |
590 | function isWindow(element) {
591 | return element === element.window
592 | }
593 |
594 | function getWindow(element) {
595 | if (isWindow(element)) {
596 | return element
597 | }
598 | return element.defaultView
599 | }
600 |
601 | function NoFrameworkAdapter(element) {
602 | this.element = element
603 | this.handlers = {}
604 | }
605 |
606 | NoFrameworkAdapter.prototype.innerHeight = function() {
607 | var isWin = isWindow(this.element)
608 | return isWin ? this.element.innerHeight : this.element.clientHeight
609 | }
610 |
611 | NoFrameworkAdapter.prototype.innerWidth = function() {
612 | var isWin = isWindow(this.element)
613 | return isWin ? this.element.innerWidth : this.element.clientWidth
614 | }
615 |
616 | NoFrameworkAdapter.prototype.off = function(event, handler) {
617 | function removeListeners(element, listeners, handler) {
618 | for (var i = 0, end = listeners.length - 1; i < end; i++) {
619 | var listener = listeners[i]
620 | if (!handler || handler === listener) {
621 | element.removeEventListener(listener)
622 | }
623 | }
624 | }
625 |
626 | var eventParts = event.split('.')
627 | var eventType = eventParts[0]
628 | var namespace = eventParts[1]
629 | var element = this.element
630 |
631 | if (namespace && this.handlers[namespace] && eventType) {
632 | removeListeners(element, this.handlers[namespace][eventType], handler)
633 | this.handlers[namespace][eventType] = []
634 | }
635 | else if (eventType) {
636 | for (var ns in this.handlers) {
637 | removeListeners(element, this.handlers[ns][eventType] || [], handler)
638 | this.handlers[ns][eventType] = []
639 | }
640 | }
641 | else if (namespace && this.handlers[namespace]) {
642 | for (var type in this.handlers[namespace]) {
643 | removeListeners(element, this.handlers[namespace][type], handler)
644 | }
645 | this.handlers[namespace] = {}
646 | }
647 | }
648 |
649 | /* Adapted from jQuery 1.x offset() */
650 | NoFrameworkAdapter.prototype.offset = function() {
651 | if (!this.element.ownerDocument) {
652 | return null
653 | }
654 |
655 | var documentElement = this.element.ownerDocument.documentElement
656 | var win = getWindow(this.element.ownerDocument)
657 | var rect = {
658 | top: 0,
659 | left: 0
660 | }
661 |
662 | if (this.element.getBoundingClientRect) {
663 | rect = this.element.getBoundingClientRect()
664 | }
665 |
666 | return {
667 | top: rect.top + win.pageYOffset - documentElement.clientTop,
668 | left: rect.left + win.pageXOffset - documentElement.clientLeft
669 | }
670 | }
671 |
672 | NoFrameworkAdapter.prototype.on = function(event, handler) {
673 | var eventParts = event.split('.')
674 | var eventType = eventParts[0]
675 | var namespace = eventParts[1] || '__default'
676 | var nsHandlers = this.handlers[namespace] = this.handlers[namespace] || {}
677 | var nsTypeList = nsHandlers[eventType] = nsHandlers[eventType] || []
678 |
679 | nsTypeList.push(handler)
680 | this.element.addEventListener(eventType, handler)
681 | }
682 |
683 | NoFrameworkAdapter.prototype.outerHeight = function(includeMargin) {
684 | var height = this.innerHeight()
685 | var computedStyle
686 |
687 | if (includeMargin && !isWindow(this.element)) {
688 | computedStyle = window.getComputedStyle(this.element)
689 | height += parseInt(computedStyle.marginTop, 10)
690 | height += parseInt(computedStyle.marginBottom, 10)
691 | }
692 |
693 | return height
694 | }
695 |
696 | NoFrameworkAdapter.prototype.outerWidth = function(includeMargin) {
697 | var width = this.innerWidth()
698 | var computedStyle
699 |
700 | if (includeMargin && !isWindow(this.element)) {
701 | computedStyle = window.getComputedStyle(this.element)
702 | width += parseInt(computedStyle.marginLeft, 10)
703 | width += parseInt(computedStyle.marginRight, 10)
704 | }
705 |
706 | return width
707 | }
708 |
709 | NoFrameworkAdapter.prototype.scrollLeft = function() {
710 | var win = getWindow(this.element)
711 | return win ? win.pageXOffset : this.element.scrollLeft
712 | }
713 |
714 | NoFrameworkAdapter.prototype.scrollTop = function() {
715 | var win = getWindow(this.element)
716 | return win ? win.pageYOffset : this.element.scrollTop
717 | }
718 |
719 | NoFrameworkAdapter.extend = function() {
720 | var args = Array.prototype.slice.call(arguments)
721 |
722 | function merge(target, obj) {
723 | if (typeof target === 'object' && typeof obj === 'object') {
724 | for (var key in obj) {
725 | if (obj.hasOwnProperty(key)) {
726 | target[key] = obj[key]
727 | }
728 | }
729 | }
730 |
731 | return target
732 | }
733 |
734 | for (var i = 1, end = args.length; i < end; i++) {
735 | merge(args[0], args[i])
736 | }
737 | return args[0]
738 | }
739 |
740 | NoFrameworkAdapter.inArray = function(element, array, i) {
741 | return array == null ? -1 : array.indexOf(element, i)
742 | }
743 |
744 | NoFrameworkAdapter.isEmptyObject = function(obj) {
745 | /* eslint no-unused-vars: 0 */
746 | for (var name in obj) {
747 | return false
748 | }
749 | return true
750 | }
751 |
752 | Waypoint.adapters.push({
753 | name: 'noframework',
754 | Adapter: NoFrameworkAdapter
755 | })
756 | Waypoint.Adapter = NoFrameworkAdapter
757 | }())
758 | ;
--------------------------------------------------------------------------------