add counter on "dossier de presse" page
It looks for a text cell with a chiffres-XXX slug (id) and will split the XXX as the number to count to.
This commit is contained in:
parent
ea9a92cd7b
commit
b144e74b0e
|
@ -815,3 +815,21 @@ div.textcell.transition {
|
|||
color: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
span#counter {
|
||||
position: absolute;
|
||||
bottom: 1em;
|
||||
right: 0px;
|
||||
font-size: 60px;
|
||||
max-width: 6em;
|
||||
line-height: 100%;
|
||||
text-align: right;
|
||||
font-family: Abeezee;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
@media(max-width: 900px) {
|
||||
span#counter {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,4 +16,19 @@ $(function() {
|
|||
$ecrans.css('background-position', (offset + pos/2) + 'px 0px');
|
||||
});
|
||||
}
|
||||
if ($('div[id|=chiffres]').length) {
|
||||
var $chiffres_section = $('div[id|=chiffres]');
|
||||
$chiffres_section.css('position', 'relative');
|
||||
var total = $chiffres_section.attr('id').split('-')[1];
|
||||
var $counter = $('<span id="counter"></span>').appendTo($chiffres_section);
|
||||
var options = {
|
||||
useEasing : true,
|
||||
useGrouping : true,
|
||||
separator : ' ',
|
||||
prefix : '',
|
||||
suffix : ' usagers'
|
||||
};
|
||||
var count = new CountUp("counter", 1234, parseInt(total), 0, 4.5, options);
|
||||
$chiffres_section.on('inview', function() { count.start(); });
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
|
||||
countUp.js
|
||||
by @inorganik
|
||||
|
||||
*/
|
||||
|
||||
// target = id of html element or var of previously selected html element where counting occurs
|
||||
// startVal = the value you want to begin at
|
||||
// endVal = the value you want to arrive at
|
||||
// decimals = number of decimal places, default 0
|
||||
// duration = duration of animation in seconds, default 2
|
||||
// options = optional object of options (see below)
|
||||
|
||||
var CountUp = function(target, startVal, endVal, decimals, duration, options) {
|
||||
|
||||
// make sure requestAnimationFrame and cancelAnimationFrame are defined
|
||||
// polyfill for browsers without native support
|
||||
// by Opera engineer Erik Möller
|
||||
var lastTime = 0;
|
||||
var vendors = ['webkit', 'moz', 'ms', 'o'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame =
|
||||
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
if (!window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
}
|
||||
if (!window.cancelAnimationFrame) {
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}
|
||||
|
||||
// default options
|
||||
this.options = {
|
||||
useEasing : true, // toggle easing
|
||||
useGrouping : true, // 1,000,000 vs 1000000
|
||||
separator : ',', // character to use as a separator
|
||||
decimal : '.' // character to use as a decimal
|
||||
};
|
||||
// extend default options with passed options object
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
this.options[key] = options[key];
|
||||
}
|
||||
}
|
||||
if (this.options.separator === '') this.options.useGrouping = false;
|
||||
if (!this.options.prefix) this.options.prefix = '';
|
||||
if (!this.options.suffix) this.options.suffix = '';
|
||||
|
||||
this.d = (typeof target === 'string') ? document.getElementById(target) : target;
|
||||
this.startVal = Number(startVal);
|
||||
this.endVal = Number(endVal);
|
||||
this.countDown = (this.startVal > this.endVal);
|
||||
this.frameVal = this.startVal;
|
||||
this.decimals = Math.max(0, decimals || 0);
|
||||
this.dec = Math.pow(10, this.decimals);
|
||||
this.duration = Number(duration) * 1000 || 2000;
|
||||
var self = this;
|
||||
|
||||
this.version = function () { return '1.6.0'; };
|
||||
|
||||
// Print value to target
|
||||
this.printValue = function(value) {
|
||||
var result = (!isNaN(value)) ? self.formatNumber(value) : '--';
|
||||
if (self.d.tagName == 'INPUT') {
|
||||
this.d.value = result;
|
||||
}
|
||||
else if (self.d.tagName == 'text' || self.d.tagName == 'tspan') {
|
||||
this.d.textContent = result;
|
||||
}
|
||||
else {
|
||||
this.d.innerHTML = result;
|
||||
}
|
||||
};
|
||||
|
||||
// Robert Penner's easeOutExpo
|
||||
this.easeOutExpo = function(t, b, c, d) {
|
||||
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
|
||||
};
|
||||
this.count = function(timestamp) {
|
||||
|
||||
if (!self.startTime) self.startTime = timestamp;
|
||||
|
||||
self.timestamp = timestamp;
|
||||
|
||||
var progress = timestamp - self.startTime;
|
||||
self.remaining = self.duration - progress;
|
||||
|
||||
// to ease or not to ease
|
||||
if (self.options.useEasing) {
|
||||
if (self.countDown) {
|
||||
self.frameVal = self.startVal - self.easeOutExpo(progress, 0, self.startVal - self.endVal, self.duration);
|
||||
} else {
|
||||
self.frameVal = self.easeOutExpo(progress, self.startVal, self.endVal - self.startVal, self.duration);
|
||||
}
|
||||
} else {
|
||||
if (self.countDown) {
|
||||
self.frameVal = self.startVal - ((self.startVal - self.endVal) * (progress / self.duration));
|
||||
} else {
|
||||
self.frameVal = self.startVal + (self.endVal - self.startVal) * (progress / self.duration);
|
||||
}
|
||||
}
|
||||
|
||||
// don't go past endVal since progress can exceed duration in the last frame
|
||||
if (self.countDown) {
|
||||
self.frameVal = (self.frameVal < self.endVal) ? self.endVal : self.frameVal;
|
||||
} else {
|
||||
self.frameVal = (self.frameVal > self.endVal) ? self.endVal : self.frameVal;
|
||||
}
|
||||
|
||||
// decimal
|
||||
self.frameVal = Math.round(self.frameVal*self.dec)/self.dec;
|
||||
|
||||
// format and print value
|
||||
self.printValue(self.frameVal);
|
||||
|
||||
// whether to continue
|
||||
if (progress < self.duration) {
|
||||
self.rAF = requestAnimationFrame(self.count);
|
||||
} else {
|
||||
if (self.callback) self.callback();
|
||||
}
|
||||
};
|
||||
// start your animation
|
||||
this.start = function(callback) {
|
||||
self.callback = callback;
|
||||
self.rAF = requestAnimationFrame(self.count);
|
||||
return false;
|
||||
};
|
||||
// toggles pause/resume animation
|
||||
this.pauseResume = function() {
|
||||
if (!self.paused) {
|
||||
self.paused = true;
|
||||
cancelAnimationFrame(self.rAF);
|
||||
} else {
|
||||
self.paused = false;
|
||||
delete self.startTime;
|
||||
self.duration = self.remaining;
|
||||
self.startVal = self.frameVal;
|
||||
requestAnimationFrame(self.count);
|
||||
}
|
||||
};
|
||||
// reset to startVal so animation can be run again
|
||||
this.reset = function() {
|
||||
self.paused = false;
|
||||
delete self.startTime;
|
||||
self.startVal = startVal;
|
||||
cancelAnimationFrame(self.rAF);
|
||||
self.printValue(self.startVal);
|
||||
};
|
||||
// pass a new endVal and start animation
|
||||
this.update = function (newEndVal) {
|
||||
cancelAnimationFrame(self.rAF);
|
||||
self.paused = false;
|
||||
delete self.startTime;
|
||||
self.startVal = self.frameVal;
|
||||
self.endVal = Number(newEndVal);
|
||||
self.countDown = (self.startVal > self.endVal);
|
||||
self.rAF = requestAnimationFrame(self.count);
|
||||
};
|
||||
this.formatNumber = function(nStr) {
|
||||
nStr = nStr.toFixed(self.decimals);
|
||||
nStr += '';
|
||||
var x, x1, x2, rgx;
|
||||
x = nStr.split('.');
|
||||
x1 = x[0];
|
||||
x2 = x.length > 1 ? self.options.decimal + x[1] : '';
|
||||
rgx = /(\d+)(\d{3})/;
|
||||
if (self.options.useGrouping) {
|
||||
while (rgx.test(x1)) {
|
||||
x1 = x1.replace(rgx, '$1' + self.options.separator + '$2');
|
||||
}
|
||||
}
|
||||
return self.options.prefix + x1 + x2 + self.options.suffix;
|
||||
};
|
||||
|
||||
// format startVal on initialization
|
||||
self.printValue(self.startVal);
|
||||
};
|
||||
|
||||
// Example:
|
||||
// var numAnim = new countUp("SomeElementYouWantToAnimate", 0, 99.99, 2, 2.5);
|
||||
// numAnim.start();
|
||||
// numAnim.update(135);
|
||||
// with optional callback:
|
||||
// numAnim.start(someMethodToCallOnComplete);
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* author Christopher Blum
|
||||
* - based on the idea of Remy Sharp, http://remysharp.com/2009/01/26/element-in-view-event-plugin/
|
||||
* - forked from http://github.com/zuk/jquery.inview/
|
||||
*/
|
||||
(function (factory) {
|
||||
if (typeof define == 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node, CommonJS
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
var inviewObjects = {}, viewportSize, viewportOffset,
|
||||
d = document, w = window, documentElement = d.documentElement, expando = $.expando, timer;
|
||||
|
||||
$.event.special.inview = {
|
||||
add: function(data) {
|
||||
inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) };
|
||||
|
||||
// Use setInterval in order to also make sure this captures elements within
|
||||
// "overflow:scroll" elements or elements that appeared in the dom tree due to
|
||||
// dom manipulation and reflow
|
||||
// old: $(window).scroll(checkInView);
|
||||
//
|
||||
// By the way, iOS (iPad, iPhone, ...) seems to not execute, or at least delays
|
||||
// intervals while the user scrolls. Therefore the inview event might fire a bit late there
|
||||
//
|
||||
// Don't waste cycles with an interval until we get at least one element that
|
||||
// has bound to the inview event.
|
||||
if (!timer && !$.isEmptyObject(inviewObjects)) {
|
||||
timer = setInterval(checkInView, 250);
|
||||
}
|
||||
},
|
||||
|
||||
remove: function(data) {
|
||||
try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {}
|
||||
|
||||
// Clear interval when we no longer have any elements listening
|
||||
if ($.isEmptyObject(inviewObjects)) {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getViewportSize() {
|
||||
var mode, domObject, size = { height: w.innerHeight, width: w.innerWidth };
|
||||
|
||||
// if this is correct then return it. iPad has compat Mode, so will
|
||||
// go into check clientHeight/clientWidth (which has the wrong value).
|
||||
if (!size.height) {
|
||||
mode = d.compatMode;
|
||||
if (mode || !$.support.boxModel) { // IE, Gecko
|
||||
domObject = mode === 'CSS1Compat' ?
|
||||
documentElement : // Standards
|
||||
d.body; // Quirks
|
||||
size = {
|
||||
height: domObject.clientHeight,
|
||||
width: domObject.clientWidth
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
function getViewportOffset() {
|
||||
return {
|
||||
top: w.pageYOffset || documentElement.scrollTop || d.body.scrollTop,
|
||||
left: w.pageXOffset || documentElement.scrollLeft || d.body.scrollLeft
|
||||
};
|
||||
}
|
||||
|
||||
function checkInView() {
|
||||
var $elements = [], elementsLength, i = 0;
|
||||
|
||||
$.each(inviewObjects, function(i, inviewObject) {
|
||||
var selector = inviewObject.data.selector,
|
||||
$element = inviewObject.$element;
|
||||
$elements.push(selector ? $element.find(selector) : $element);
|
||||
});
|
||||
|
||||
elementsLength = $elements.length;
|
||||
if (elementsLength) {
|
||||
viewportSize = viewportSize || getViewportSize();
|
||||
viewportOffset = viewportOffset || getViewportOffset();
|
||||
|
||||
for (; i<elementsLength; i++) {
|
||||
// Ignore elements that are not in the DOM tree
|
||||
if (!$.contains(documentElement, $elements[i][0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var $element = $($elements[i]),
|
||||
elementSize = { height: $element.height(), width: $element.width() },
|
||||
elementOffset = $element.offset(),
|
||||
inView = $element.data('inview'),
|
||||
visiblePartX,
|
||||
visiblePartY,
|
||||
visiblePartsMerged;
|
||||
|
||||
// Don't ask me why because I haven't figured out yet:
|
||||
// viewportOffset and viewportSize are sometimes suddenly null in Firefox 5.
|
||||
// Even though it sounds weird:
|
||||
// It seems that the execution of this function is interferred by the onresize/onscroll event
|
||||
// where viewportOffset and viewportSize are unset
|
||||
if (!viewportOffset || !viewportSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (elementOffset.top + elementSize.height > viewportOffset.top &&
|
||||
elementOffset.top < viewportOffset.top + viewportSize.height &&
|
||||
elementOffset.left + elementSize.width > viewportOffset.left &&
|
||||
elementOffset.left < viewportOffset.left + viewportSize.width) {
|
||||
visiblePartX = (viewportOffset.left > elementOffset.left ?
|
||||
'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ?
|
||||
'left' : 'both');
|
||||
visiblePartY = (viewportOffset.top > elementOffset.top ?
|
||||
'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ?
|
||||
'top' : 'both');
|
||||
visiblePartsMerged = visiblePartX + "-" + visiblePartY;
|
||||
if (!inView || inView !== visiblePartsMerged) {
|
||||
$element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]);
|
||||
}
|
||||
} else if (inView) {
|
||||
$element.data('inview', false).trigger('inview', [false]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(w).bind("scroll resize scrollstop", function() {
|
||||
viewportSize = viewportOffset = null;
|
||||
});
|
||||
|
||||
// IE < 9 scrolls to focused elements without firing the "scroll" event
|
||||
if (!documentElement.addEventListener && documentElement.attachEvent) {
|
||||
documentElement.attachEvent("onfocusin", function() {
|
||||
viewportOffset = null;
|
||||
});
|
||||
}
|
||||
}));
|
|
@ -11,6 +11,8 @@
|
|||
<script src="{% xstatic 'jquery' 'jquery.min.js' %}"></script>
|
||||
<script src="{{ STATIC_URL }}js/jquery.parallax-1.1.3.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/jquery.scrollTo.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/countUp.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/jquery.inview.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/combo.public.js"></script>
|
||||
</head>
|
||||
<body class="page-{{ page.slug }}">
|
||||
|
|
Loading…
Reference in New Issue