tramway-landing 1.0 → 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/tramway/landing/application.js.coffee +5 -0
- data/app/assets/javascripts/tramway/landing/footer.js.coffee +22 -22
- data/app/assets/javascripts/tramway/landing/smooth-scroll.js +576 -0
- data/app/views/tramway/landing/blocks/block_types/_cards.html.haml +3 -3
- data/app/views/tramway/landing/blocks/block_types/_contacts.html.haml +3 -3
- data/app/views/tramway/landing/blocks/block_types/_features.html.haml +2 -2
- data/app/views/tramway/landing/blocks/block_types/_header.html.haml +3 -0
- data/app/views/tramway/landing/blocks/block_types/_page.html.haml +1 -1
- data/config/initializers/assets.rb +2 -1
- data/lib/tramway/landing/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd058864a8e673a0844ed5ea8658cd76a099f98b07ada97e6cd746886a7f4b51
|
4
|
+
data.tar.gz: 02a1df7f3d382e6ef33f2b6c9ab0a40033ca94b5538ac1b1dc89c3cffd9e3d82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6375d3ce59889cc3cefe58e9dbb0fec7299dc62c6055068ce2505ecb5bad33226dee39eaa172a0a9306e3325b0cd75e48273093b5ec7748ced59599aa96c0ba
|
7
|
+
data.tar.gz: cd5bf362a70462faa7c8054672f2fca26929c260eeb04a1e0b24db89288a076af829665373a736fa539883c60cf02e768635b413e7a1e73f7c4f10917f46e429
|
@@ -1,24 +1,24 @@
|
|
1
1
|
#= require justified_images
|
2
2
|
|
3
|
-
|
4
|
-
$('.logo_collage1').empty().justifiedImages
|
5
|
-
images: photos
|
6
|
-
rowHeight: 200
|
7
|
-
maxRowHeight: 400
|
8
|
-
thumbnailPath: (photo, width, height) ->
|
9
|
-
purl = photo.url_s
|
10
|
-
if photo.url_n and (width > photo.width_s * 1.2 or height > photo.height_s * 1.2)
|
11
|
-
purl = photo.url_n
|
12
|
-
if photo.url_m and (width > photo.width_n * 1.2 or height > photo.height_n * 1.2)
|
13
|
-
purl = photo.url_m
|
14
|
-
if photo.url_z and (width > photo.width_m * 1.2 or height > photo.height_m * 1.2)
|
15
|
-
purl = photo.url_z
|
16
|
-
if photo.url_l and (width > photo.width_z * 1.2 or height > photo.height_z * 1.2)
|
17
|
-
purl = photo.url_l
|
18
|
-
purl
|
19
|
-
getSize: (photo) ->
|
20
|
-
{
|
21
|
-
width: photo.width_s
|
22
|
-
height: photo.height_s
|
23
|
-
}
|
24
|
-
margin: 1
|
3
|
+
#$(document).ready ->
|
4
|
+
# $('.logo_collage1').empty().justifiedImages
|
5
|
+
# images: photos
|
6
|
+
# rowHeight: 200
|
7
|
+
# maxRowHeight: 400
|
8
|
+
# thumbnailPath: (photo, width, height) ->
|
9
|
+
# purl = photo.url_s
|
10
|
+
# if photo.url_n and (width > photo.width_s * 1.2 or height > photo.height_s * 1.2)
|
11
|
+
# purl = photo.url_n
|
12
|
+
# if photo.url_m and (width > photo.width_n * 1.2 or height > photo.height_n * 1.2)
|
13
|
+
# purl = photo.url_m
|
14
|
+
# if photo.url_z and (width > photo.width_m * 1.2 or height > photo.height_m * 1.2)
|
15
|
+
# purl = photo.url_z
|
16
|
+
# if photo.url_l and (width > photo.width_z * 1.2 or height > photo.height_z * 1.2)
|
17
|
+
# purl = photo.url_l
|
18
|
+
# purl
|
19
|
+
# getSize: (photo) ->
|
20
|
+
# {
|
21
|
+
# width: photo.width_s
|
22
|
+
# height: photo.height_s
|
23
|
+
# }
|
24
|
+
# margin: 1
|
@@ -0,0 +1,576 @@
|
|
1
|
+
/*!
|
2
|
+
* smooth-scroll v12.1.5: Animate scrolling to anchor links
|
3
|
+
* (c) 2017 Chris Ferdinandi
|
4
|
+
* MIT License
|
5
|
+
* http://github.com/cferdinandi/smooth-scroll
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function (root, factory) {
|
9
|
+
if ( typeof define === 'function' && define.amd ) {
|
10
|
+
define([], (function () {
|
11
|
+
return factory(root);
|
12
|
+
}));
|
13
|
+
} else if ( typeof exports === 'object' ) {
|
14
|
+
module.exports = factory(root);
|
15
|
+
} else {
|
16
|
+
root.SmoothScroll = factory(root);
|
17
|
+
}
|
18
|
+
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window) {
|
19
|
+
|
20
|
+
'use strict';
|
21
|
+
|
22
|
+
//
|
23
|
+
// Feature Test
|
24
|
+
//
|
25
|
+
|
26
|
+
var supports =
|
27
|
+
'querySelector' in document &&
|
28
|
+
'addEventListener' in window &&
|
29
|
+
'requestAnimationFrame' in window &&
|
30
|
+
'closest' in window.Element.prototype;
|
31
|
+
|
32
|
+
|
33
|
+
//
|
34
|
+
// Default settings
|
35
|
+
//
|
36
|
+
|
37
|
+
var defaults = {
|
38
|
+
// Selectors
|
39
|
+
ignore: '[data-scroll-ignore]',
|
40
|
+
header: null,
|
41
|
+
|
42
|
+
// Speed & Easing
|
43
|
+
speed: 500,
|
44
|
+
offset: 0,
|
45
|
+
easing: 'easeInOutCubic',
|
46
|
+
customEasing: null,
|
47
|
+
|
48
|
+
// Callback API
|
49
|
+
before: function () {},
|
50
|
+
after: function () {}
|
51
|
+
};
|
52
|
+
|
53
|
+
|
54
|
+
//
|
55
|
+
// Utility Methods
|
56
|
+
//
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Merge two or more objects. Returns a new object.
|
60
|
+
* @param {Object} objects The objects to merge together
|
61
|
+
* @returns {Object} Merged values of defaults and options
|
62
|
+
*/
|
63
|
+
var extend = function () {
|
64
|
+
|
65
|
+
// Variables
|
66
|
+
var extended = {};
|
67
|
+
var deep = false;
|
68
|
+
var i = 0;
|
69
|
+
var length = arguments.length;
|
70
|
+
|
71
|
+
// Merge the object into the extended object
|
72
|
+
var merge = function (obj) {
|
73
|
+
for (var prop in obj) {
|
74
|
+
if (obj.hasOwnProperty(prop)) {
|
75
|
+
extended[prop] = obj[prop];
|
76
|
+
}
|
77
|
+
}
|
78
|
+
};
|
79
|
+
|
80
|
+
// Loop through each object and conduct a merge
|
81
|
+
for ( ; i < length; i++ ) {
|
82
|
+
var obj = arguments[i];
|
83
|
+
merge(obj);
|
84
|
+
}
|
85
|
+
|
86
|
+
return extended;
|
87
|
+
|
88
|
+
};
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Get the height of an element.
|
92
|
+
* @param {Node} elem The element to get the height of
|
93
|
+
* @return {Number} The element's height in pixels
|
94
|
+
*/
|
95
|
+
var getHeight = function (elem) {
|
96
|
+
return parseInt(window.getComputedStyle(elem).height, 10);
|
97
|
+
};
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Escape special characters for use with querySelector
|
101
|
+
* @param {String} id The anchor ID to escape
|
102
|
+
* @author Mathias Bynens
|
103
|
+
* @link https://github.com/mathiasbynens/CSS.escape
|
104
|
+
*/
|
105
|
+
var escapeCharacters = function (id) {
|
106
|
+
|
107
|
+
// Remove leading hash
|
108
|
+
if (id.charAt(0) === '#') {
|
109
|
+
id = id.substr(1);
|
110
|
+
}
|
111
|
+
|
112
|
+
var string = String(id);
|
113
|
+
var length = string.length;
|
114
|
+
var index = -1;
|
115
|
+
var codeUnit;
|
116
|
+
var result = '';
|
117
|
+
var firstCodeUnit = string.charCodeAt(0);
|
118
|
+
while (++index < length) {
|
119
|
+
codeUnit = string.charCodeAt(index);
|
120
|
+
// Note: there’s no need to special-case astral symbols, surrogate
|
121
|
+
// pairs, or lone surrogates.
|
122
|
+
|
123
|
+
// If the character is NULL (U+0000), then throw an
|
124
|
+
// `InvalidCharacterError` exception and terminate these steps.
|
125
|
+
if (codeUnit === 0x0000) {
|
126
|
+
throw new InvalidCharacterError(
|
127
|
+
'Invalid character: the input contains U+0000.'
|
128
|
+
);
|
129
|
+
}
|
130
|
+
|
131
|
+
if (
|
132
|
+
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
|
133
|
+
// U+007F, […]
|
134
|
+
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
|
135
|
+
// If the character is the first character and is in the range [0-9]
|
136
|
+
// (U+0030 to U+0039), […]
|
137
|
+
(index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
|
138
|
+
// If the character is the second character and is in the range [0-9]
|
139
|
+
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
|
140
|
+
(
|
141
|
+
index === 1 &&
|
142
|
+
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
|
143
|
+
firstCodeUnit === 0x002D
|
144
|
+
)
|
145
|
+
) {
|
146
|
+
// http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
|
147
|
+
result += '\\' + codeUnit.toString(16) + ' ';
|
148
|
+
continue;
|
149
|
+
}
|
150
|
+
|
151
|
+
// If the character is not handled by one of the above rules and is
|
152
|
+
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
|
153
|
+
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
|
154
|
+
// U+005A), or [a-z] (U+0061 to U+007A), […]
|
155
|
+
if (
|
156
|
+
codeUnit >= 0x0080 ||
|
157
|
+
codeUnit === 0x002D ||
|
158
|
+
codeUnit === 0x005F ||
|
159
|
+
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
|
160
|
+
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
|
161
|
+
codeUnit >= 0x0061 && codeUnit <= 0x007A
|
162
|
+
) {
|
163
|
+
// the character itself
|
164
|
+
result += string.charAt(index);
|
165
|
+
continue;
|
166
|
+
}
|
167
|
+
|
168
|
+
// Otherwise, the escaped character.
|
169
|
+
// http://dev.w3.org/csswg/cssom/#escape-a-character
|
170
|
+
result += '\\' + string.charAt(index);
|
171
|
+
|
172
|
+
}
|
173
|
+
|
174
|
+
return '#' + result;
|
175
|
+
|
176
|
+
};
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Calculate the easing pattern
|
180
|
+
* @link https://gist.github.com/gre/1650294
|
181
|
+
* @param {String} type Easing pattern
|
182
|
+
* @param {Number} time Time animation should take to complete
|
183
|
+
* @returns {Number}
|
184
|
+
*/
|
185
|
+
var easingPattern = function (settings, time) {
|
186
|
+
var pattern;
|
187
|
+
|
188
|
+
// Default Easing Patterns
|
189
|
+
if (settings.easing === 'easeInQuad') pattern = time * time; // accelerating from zero velocity
|
190
|
+
if (settings.easing === 'easeOutQuad') pattern = time * (2 - time); // decelerating to zero velocity
|
191
|
+
if (settings.easing === 'easeInOutQuad') pattern = time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
|
192
|
+
if (settings.easing === 'easeInCubic') pattern = time * time * time; // accelerating from zero velocity
|
193
|
+
if (settings.easing === 'easeOutCubic') pattern = (--time) * time * time + 1; // decelerating to zero velocity
|
194
|
+
if (settings.easing === 'easeInOutCubic') pattern = time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
|
195
|
+
if (settings.easing === 'easeInQuart') pattern = time * time * time * time; // accelerating from zero velocity
|
196
|
+
if (settings.easing === 'easeOutQuart') pattern = 1 - (--time) * time * time * time; // decelerating to zero velocity
|
197
|
+
if (settings.easing === 'easeInOutQuart') pattern = time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
|
198
|
+
if (settings.easing === 'easeInQuint') pattern = time * time * time * time * time; // accelerating from zero velocity
|
199
|
+
if (settings.easing === 'easeOutQuint') pattern = 1 + (--time) * time * time * time * time; // decelerating to zero velocity
|
200
|
+
if (settings.easing === 'easeInOutQuint') pattern = time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration
|
201
|
+
|
202
|
+
// Custom Easing Patterns
|
203
|
+
if (!!settings.customEasing) pattern = settings.customEasing(time);
|
204
|
+
|
205
|
+
return pattern || time; // no easing, no acceleration
|
206
|
+
};
|
207
|
+
|
208
|
+
/**
|
209
|
+
* Determine the document's height
|
210
|
+
* @returns {Number}
|
211
|
+
*/
|
212
|
+
var getDocumentHeight = function () {
|
213
|
+
return Math.max(
|
214
|
+
document.body.scrollHeight, document.documentElement.scrollHeight,
|
215
|
+
document.body.offsetHeight, document.documentElement.offsetHeight,
|
216
|
+
document.body.clientHeight, document.documentElement.clientHeight
|
217
|
+
);
|
218
|
+
};
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Calculate how far to scroll
|
222
|
+
* @param {Element} anchor The anchor element to scroll to
|
223
|
+
* @param {Number} headerHeight Height of a fixed header, if any
|
224
|
+
* @param {Number} offset Number of pixels by which to offset scroll
|
225
|
+
* @returns {Number}
|
226
|
+
*/
|
227
|
+
var getEndLocation = function (anchor, headerHeight, offset) {
|
228
|
+
var location = 0;
|
229
|
+
if (anchor.offsetParent) {
|
230
|
+
do {
|
231
|
+
location += anchor.offsetTop;
|
232
|
+
anchor = anchor.offsetParent;
|
233
|
+
} while (anchor);
|
234
|
+
}
|
235
|
+
location = Math.max(location - headerHeight - offset, 0);
|
236
|
+
return location;
|
237
|
+
};
|
238
|
+
|
239
|
+
/**
|
240
|
+
* Get the height of the fixed header
|
241
|
+
* @param {Node} header The header
|
242
|
+
* @return {Number} The height of the header
|
243
|
+
*/
|
244
|
+
var getHeaderHeight = function (header) {
|
245
|
+
return !header ? 0 : (getHeight(header) + header.offsetTop);
|
246
|
+
};
|
247
|
+
|
248
|
+
/**
|
249
|
+
* Bring the anchored element into focus
|
250
|
+
* @param {Node} anchor The anchor element
|
251
|
+
* @param {Number} endLocation The end location to scroll to
|
252
|
+
* @param {Boolean} isNum If true, scroll is to a position rather than an element
|
253
|
+
*/
|
254
|
+
var adjustFocus = function (anchor, endLocation, isNum) {
|
255
|
+
|
256
|
+
// Don't run if scrolling to a number on the page
|
257
|
+
if (isNum) return;
|
258
|
+
|
259
|
+
// Otherwise, bring anchor element into focus
|
260
|
+
anchor.focus();
|
261
|
+
if (document.activeElement.id !== anchor.id) {
|
262
|
+
anchor.setAttribute('tabindex', '-1');
|
263
|
+
anchor.focus();
|
264
|
+
anchor.style.outline = 'none';
|
265
|
+
}
|
266
|
+
window.scrollTo(0 , endLocation);
|
267
|
+
|
268
|
+
};
|
269
|
+
|
270
|
+
/**
|
271
|
+
* Check to see if user prefers reduced motion
|
272
|
+
* @param {Object} settings Script settings
|
273
|
+
*/
|
274
|
+
var reduceMotion = function (settings) {
|
275
|
+
if ('matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches) {
|
276
|
+
return true;
|
277
|
+
}
|
278
|
+
return false;
|
279
|
+
};
|
280
|
+
|
281
|
+
|
282
|
+
//
|
283
|
+
// SmoothScroll Constructor
|
284
|
+
//
|
285
|
+
|
286
|
+
var SmoothScroll = function (selector, options) {
|
287
|
+
|
288
|
+
//
|
289
|
+
// Variables
|
290
|
+
//
|
291
|
+
|
292
|
+
var smoothScroll = {}; // Object for public APIs
|
293
|
+
var settings, anchor, toggle, fixedHeader, headerHeight, eventTimeout, animationInterval;
|
294
|
+
|
295
|
+
|
296
|
+
//
|
297
|
+
// Methods
|
298
|
+
//
|
299
|
+
|
300
|
+
/**
|
301
|
+
* Cancel a scroll-in-progress
|
302
|
+
*/
|
303
|
+
smoothScroll.cancelScroll = function () {
|
304
|
+
// clearInterval(animationInterval);
|
305
|
+
cancelAnimationFrame(animationInterval);
|
306
|
+
};
|
307
|
+
|
308
|
+
/**
|
309
|
+
* Start/stop the scrolling animation
|
310
|
+
* @param {Node|Number} anchor The element or position to scroll to
|
311
|
+
* @param {Element} toggle The element that toggled the scroll event
|
312
|
+
* @param {Object} options
|
313
|
+
*/
|
314
|
+
smoothScroll.animateScroll = function (anchor, toggle, options) {
|
315
|
+
|
316
|
+
// Local settings
|
317
|
+
var animateSettings = extend(settings || defaults, options || {}); // Merge user options with defaults
|
318
|
+
|
319
|
+
// Selectors and variables
|
320
|
+
var isNum = Object.prototype.toString.call(anchor) === '[object Number]' ? true : false;
|
321
|
+
var anchorElem = isNum || !anchor.tagName ? null : anchor;
|
322
|
+
if (!isNum && !anchorElem) return;
|
323
|
+
var startLocation = window.pageYOffset; // Current location on the page
|
324
|
+
if (animateSettings.header && !fixedHeader) {
|
325
|
+
// Get the fixed header if not already set
|
326
|
+
fixedHeader = document.querySelector( animateSettings.header );
|
327
|
+
}
|
328
|
+
if (!headerHeight) {
|
329
|
+
// Get the height of a fixed header if one exists and not already set
|
330
|
+
headerHeight = getHeaderHeight(fixedHeader);
|
331
|
+
}
|
332
|
+
var endLocation = isNum ? anchor : getEndLocation(anchorElem, headerHeight, parseInt((typeof animateSettings.offset === 'function' ? animateSettings.offset() : animateSettings.offset), 10)); // Location to scroll to
|
333
|
+
var distance = endLocation - startLocation; // distance to travel
|
334
|
+
var documentHeight = getDocumentHeight();
|
335
|
+
var timeLapsed = 0;
|
336
|
+
var start, percentage, position;
|
337
|
+
|
338
|
+
/**
|
339
|
+
* Stop the scroll animation when it reaches its target (or the bottom/top of page)
|
340
|
+
* @param {Number} position Current position on the page
|
341
|
+
* @param {Number} endLocation Scroll to location
|
342
|
+
* @param {Number} animationInterval How much to scroll on this loop
|
343
|
+
*/
|
344
|
+
var stopAnimateScroll = function (position, endLocation) {
|
345
|
+
|
346
|
+
// Get the current location
|
347
|
+
var currentLocation = window.pageYOffset;
|
348
|
+
|
349
|
+
// Check if the end location has been reached yet (or we've hit the end of the document)
|
350
|
+
if ( position == endLocation || currentLocation == endLocation || ((startLocation < endLocation && window.innerHeight + currentLocation) >= documentHeight )) {
|
351
|
+
|
352
|
+
// Clear the animation timer
|
353
|
+
smoothScroll.cancelScroll();
|
354
|
+
|
355
|
+
// Bring the anchored element into focus
|
356
|
+
adjustFocus(anchor, endLocation, isNum);
|
357
|
+
|
358
|
+
// Run callback after animation complete
|
359
|
+
animateSettings.after(anchor, toggle);
|
360
|
+
|
361
|
+
// Reset start
|
362
|
+
start = null;
|
363
|
+
|
364
|
+
return true;
|
365
|
+
|
366
|
+
}
|
367
|
+
};
|
368
|
+
|
369
|
+
/**
|
370
|
+
* Loop scrolling animation
|
371
|
+
*/
|
372
|
+
var loopAnimateScroll = function (timestamp) {
|
373
|
+
if (!start) { start = timestamp; }
|
374
|
+
timeLapsed += timestamp - start;
|
375
|
+
percentage = (timeLapsed / parseInt(animateSettings.speed, 10));
|
376
|
+
percentage = (percentage > 1) ? 1 : percentage;
|
377
|
+
position = startLocation + (distance * easingPattern(animateSettings, percentage));
|
378
|
+
window.scrollTo(0, Math.floor(position));
|
379
|
+
if (!stopAnimateScroll(position, endLocation)) {
|
380
|
+
window.requestAnimationFrame(loopAnimateScroll);
|
381
|
+
start = timestamp;
|
382
|
+
}
|
383
|
+
};
|
384
|
+
|
385
|
+
/**
|
386
|
+
* Reset position to fix weird iOS bug
|
387
|
+
* @link https://github.com/cferdinandi/smooth-scroll/issues/45
|
388
|
+
*/
|
389
|
+
if (window.pageYOffset === 0) {
|
390
|
+
window.scrollTo( 0, 0 );
|
391
|
+
}
|
392
|
+
|
393
|
+
// Run callback before animation starts
|
394
|
+
animateSettings.before(anchor, toggle);
|
395
|
+
|
396
|
+
// Start scrolling animation
|
397
|
+
smoothScroll.cancelScroll();
|
398
|
+
window.requestAnimationFrame(loopAnimateScroll);
|
399
|
+
|
400
|
+
|
401
|
+
};
|
402
|
+
|
403
|
+
/**
|
404
|
+
* Handle has change event
|
405
|
+
*/
|
406
|
+
var hashChangeHandler = function (event) {
|
407
|
+
|
408
|
+
// Only run if there's an anchor element to scroll to
|
409
|
+
if (!anchor) return;
|
410
|
+
|
411
|
+
// Reset the anchor element's ID
|
412
|
+
anchor.id = anchor.getAttribute('data-scroll-id');
|
413
|
+
|
414
|
+
// Scroll to the anchored content
|
415
|
+
smoothScroll.animateScroll(anchor, toggle);
|
416
|
+
|
417
|
+
// Reset anchor and toggle
|
418
|
+
anchor = null;
|
419
|
+
toggle = null;
|
420
|
+
|
421
|
+
};
|
422
|
+
|
423
|
+
/**
|
424
|
+
* If smooth scroll element clicked, animate scroll
|
425
|
+
*/
|
426
|
+
var clickHandler = function (event) {
|
427
|
+
|
428
|
+
// Don't run if the user prefers reduced motion
|
429
|
+
if (reduceMotion(settings)) return;
|
430
|
+
|
431
|
+
// Don't run if right-click or command/control + click
|
432
|
+
if (event.button !== 0 || event.metaKey || event.ctrlKey) return;
|
433
|
+
|
434
|
+
// Check if a smooth scroll link was clicked
|
435
|
+
toggle = event.target.closest(selector);
|
436
|
+
if (!toggle || toggle.tagName.toLowerCase() !== 'a' || event.target.closest(settings.ignore)) return;
|
437
|
+
|
438
|
+
// Only run if link is an anchor and points to the current page
|
439
|
+
if (toggle.hostname !== window.location.hostname || toggle.pathname !== window.location.pathname || !/#/.test(toggle.href)) return;
|
440
|
+
|
441
|
+
// Get the sanitized hash
|
442
|
+
var hash;
|
443
|
+
try {
|
444
|
+
hash = escapeCharacters(decodeURIComponent(toggle.hash));
|
445
|
+
} catch(e) {
|
446
|
+
hash = escapeCharacters(toggle.hash);
|
447
|
+
}
|
448
|
+
|
449
|
+
// If the hash is empty, scroll to the top of the page
|
450
|
+
if (hash === '#') {
|
451
|
+
|
452
|
+
// Prevent default link behavior
|
453
|
+
event.preventDefault();
|
454
|
+
|
455
|
+
// Set the anchored element
|
456
|
+
anchor = document.body;
|
457
|
+
|
458
|
+
// Save or create the ID as a data attribute and remove it (prevents scroll jump)
|
459
|
+
var id = anchor.id ? anchor.id : 'smooth-scroll-top';
|
460
|
+
anchor.setAttribute('data-scroll-id', id);
|
461
|
+
anchor.id = '';
|
462
|
+
|
463
|
+
// If no hash change event will happen, fire manually
|
464
|
+
// Otherwise, update the hash
|
465
|
+
if (window.location.hash.substring(1) === id) {
|
466
|
+
hashChangeHandler();
|
467
|
+
} else {
|
468
|
+
window.location.hash = id;
|
469
|
+
}
|
470
|
+
|
471
|
+
return;
|
472
|
+
|
473
|
+
}
|
474
|
+
|
475
|
+
// Get the anchored element
|
476
|
+
anchor = document.querySelector(hash);
|
477
|
+
|
478
|
+
// If anchored element exists, save the ID as a data attribute and remove it (prevents scroll jump)
|
479
|
+
if (!anchor) return;
|
480
|
+
anchor.setAttribute('data-scroll-id', anchor.id);
|
481
|
+
anchor.id = '';
|
482
|
+
|
483
|
+
// If no hash change event will happen, fire manually
|
484
|
+
if (toggle.hash === window.location.hash) {
|
485
|
+
event.preventDefault();
|
486
|
+
hashChangeHandler();
|
487
|
+
}
|
488
|
+
|
489
|
+
};
|
490
|
+
|
491
|
+
/**
|
492
|
+
* On window scroll and resize, only run events at a rate of 15fps for better performance
|
493
|
+
*/
|
494
|
+
var resizeThrottler = function (event) {
|
495
|
+
if (!eventTimeout) {
|
496
|
+
eventTimeout = setTimeout((function() {
|
497
|
+
eventTimeout = null; // Reset timeout
|
498
|
+
headerHeight = getHeaderHeight(fixedHeader); // Get the height of a fixed header if one exists
|
499
|
+
}), 66);
|
500
|
+
}
|
501
|
+
};
|
502
|
+
|
503
|
+
/**
|
504
|
+
* Destroy the current initialization.
|
505
|
+
*/
|
506
|
+
smoothScroll.destroy = function () {
|
507
|
+
|
508
|
+
// If plugin isn't already initialized, stop
|
509
|
+
if (!settings) return;
|
510
|
+
|
511
|
+
// Remove event listeners
|
512
|
+
document.removeEventListener('click', clickHandler, false);
|
513
|
+
window.removeEventListener('resize', resizeThrottler, false);
|
514
|
+
|
515
|
+
// Cancel any scrolls-in-progress
|
516
|
+
smoothScroll.cancelScroll();
|
517
|
+
|
518
|
+
// Reset variables
|
519
|
+
settings = null;
|
520
|
+
anchor = null;
|
521
|
+
toggle = null;
|
522
|
+
fixedHeader = null;
|
523
|
+
headerHeight = null;
|
524
|
+
eventTimeout = null;
|
525
|
+
animationInterval = null;
|
526
|
+
};
|
527
|
+
|
528
|
+
/**
|
529
|
+
* Initialize Smooth Scroll
|
530
|
+
* @param {Object} options User settings
|
531
|
+
*/
|
532
|
+
smoothScroll.init = function (options) {
|
533
|
+
|
534
|
+
// feature test
|
535
|
+
if (!supports) return;
|
536
|
+
|
537
|
+
// Destroy any existing initializations
|
538
|
+
smoothScroll.destroy();
|
539
|
+
|
540
|
+
// Selectors and variables
|
541
|
+
settings = extend(defaults, options || {}); // Merge user options with defaults
|
542
|
+
fixedHeader = settings.header ? document.querySelector(settings.header) : null; // Get the fixed header
|
543
|
+
headerHeight = getHeaderHeight(fixedHeader);
|
544
|
+
|
545
|
+
// When a toggle is clicked, run the click handler
|
546
|
+
document.addEventListener('click', clickHandler, false);
|
547
|
+
|
548
|
+
// Listen for hash changes
|
549
|
+
window.addEventListener('hashchange', hashChangeHandler, false);
|
550
|
+
|
551
|
+
// If window is resized and there's a fixed header, recalculate its size
|
552
|
+
if (fixedHeader) {
|
553
|
+
window.addEventListener('resize', resizeThrottler, false);
|
554
|
+
}
|
555
|
+
|
556
|
+
};
|
557
|
+
|
558
|
+
|
559
|
+
//
|
560
|
+
// Initialize plugin
|
561
|
+
//
|
562
|
+
|
563
|
+
smoothScroll.init(options);
|
564
|
+
|
565
|
+
|
566
|
+
//
|
567
|
+
// Public APIs
|
568
|
+
//
|
569
|
+
|
570
|
+
return smoothScroll;
|
571
|
+
|
572
|
+
};
|
573
|
+
|
574
|
+
return SmoothScroll;
|
575
|
+
|
576
|
+
}));
|
@@ -1,11 +1,11 @@
|
|
1
|
-
.container.text-center
|
1
|
+
.container.text-center{ id: block.anchor }
|
2
2
|
%h2.mb-4.font-weight-bold
|
3
3
|
= block.title
|
4
4
|
%p.grey-text
|
5
5
|
= block.description
|
6
|
-
.row
|
6
|
+
.row
|
7
7
|
-# FIXME bad guy mode ON
|
8
|
-
- eval("@collection_#{block.anchor}")
|
8
|
+
- eval("@collection_#{block.anchor}")&.each do |item|
|
9
9
|
.col-lg-4.col-md-12.mb-4
|
10
10
|
- if item.path.present?
|
11
11
|
= link_to item.path do
|
@@ -1,4 +1,4 @@
|
|
1
|
-
%script{ src: 'https://maps.google.com/maps/api/js?key=
|
1
|
+
%script{ src: 'https://maps.google.com/maps/api/js?key=AIzaSyD4shvkgS4S4Mz-SEWbigeCQ54fHmFPxUo' }
|
2
2
|
:javascript
|
3
3
|
function regular_map() {
|
4
4
|
var var_location = new google.maps.LatLng(#{yield(:latitude)}, #{yield(:longtitude)});
|
@@ -14,11 +14,11 @@
|
|
14
14
|
var var_marker = new google.maps.Marker({
|
15
15
|
position: var_location,
|
16
16
|
map: var_map,
|
17
|
-
title: "
|
17
|
+
title: "School"
|
18
18
|
});
|
19
19
|
}
|
20
20
|
google.maps.event.addDomListener(window, 'load', regular_map);
|
21
|
-
#
|
21
|
+
#contacts
|
22
22
|
%h2.mb-5.font-weight-bold.text-center
|
23
23
|
= block.title
|
24
24
|
.row
|
@@ -1,3 +1,4 @@
|
|
1
|
+
= javascript_include_tag 'tramway/landing/smooth-scroll'
|
1
2
|
%header
|
2
3
|
%nav.navbar.navbar-expand-lg.navbar-dark.indigo.scrolling-navbar.fixed-top
|
3
4
|
= link_to yield(:application_name), '#', class: 'navbar-brand'
|
@@ -20,3 +21,5 @@
|
|
20
21
|
- @blocks.with_navbar_link.each do |block|
|
21
22
|
%button.btn.btn-outline-white.waves-effect.waves-light.header-buttons{ type: :button, data: { anchor: "##{block.anchor}" } }
|
22
23
|
= block.title
|
24
|
+
%script
|
25
|
+
var scroll = new SmoothScroll('a[href*="#"]');
|
@@ -1 +1,2 @@
|
|
1
|
-
Rails.application.config.assets.precompile += %w( tramway/landing/footer.js
|
1
|
+
Rails.application.config.assets.precompile += %w( tramway/landing/footer.js )
|
2
|
+
Rails.application.config.assets.precompile += %w( tramway/landing/smooth-scroll.js )
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tramway-landing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Kalashnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Landing Engine for your Rails projects
|
14
14
|
email:
|
@@ -24,6 +24,7 @@ files:
|
|
24
24
|
- app/assets/javascripts/justified_images.js
|
25
25
|
- app/assets/javascripts/tramway/landing/application.js.coffee
|
26
26
|
- app/assets/javascripts/tramway/landing/footer.js.coffee
|
27
|
+
- app/assets/javascripts/tramway/landing/smooth-scroll.js
|
27
28
|
- app/assets/stylesheets/tramway/landing/application.css.sass
|
28
29
|
- app/assets/stylesheets/tramway/landing/collage.css.sass
|
29
30
|
- app/assets/stylesheets/tramway/landing/justified.css
|