Initial commit — Provoc Group website

Full website with security hardening:
- Redesigned sections: hero, services, capabilities, clients, partners, stats, about, workflow, contact
- Contact form fixed (variable names, XSS sanitisation, rate limiting, open redirect removed)
- .htaccess with security headers (CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- error_log blocked from public access
- Robots.txt corrected to allow JS/CSS for SEO rendering
This commit is contained in:
kutesir
2026-05-16 21:26:49 +03:00
commit fe5f232c6a
105 changed files with 16212 additions and 0 deletions

2006
js/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

155
js/countUp.js Normal file
View File

@@ -0,0 +1,155 @@
/*
countUp.js
by @inorganik
v 1.0.0
*/
// target = id of 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 in number, default 0
// duration = duration in seconds, default 2
function countUp(target, startVal, endVal, decimals, duration) {
// 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'];
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);
}
}
var self = this;
// toggle easing
this.useEasing = true;
this.d = document.getElementById(target);
self.startVal = Number(startVal);
endVal = Number(endVal);
this.countDown = (startVal > endVal) ? true : false;
decimals = Math.max(0, decimals || 0);
this.dec = Math.pow(10, decimals);
this.duration = duration * 1000 || 2000;
this.startTime = null;
this.timestamp = null;
this.remaining = null;
this.frameVal = startVal;
this.rAF = null;
// 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 === null) self.startTime = timestamp;
self.timestamp = timestamp;
var progress = timestamp - self.startTime;
self.remaining = self.duration - progress;
// to ease or not to ease
if (self.useEasing) {
if (self.countDown) {
var i = self.easeOutExpo(progress, 0, self.startVal - endVal, self.duration);
self.frameVal = startVal - i;
} else {
self.frameVal = self.easeOutExpo(progress, self.startVal, endVal - self.startVal, self.duration);
}
} else {
if (self.countDown) {
var i = (self.startVal - endVal) * (progress / self.duration);
self.frameVal = self.startVal - i;
} else {
self.frameVal = self.startVal + (endVal - self.startVal) * (progress / self.duration);
}
}
// decimal
self.frameVal = Math.round(self.frameVal*self.dec)/self.dec;
// don't go past endVal since progress can exceed duration in the last frame
if (self.countDown) {
self.frameVal = (self.frameVal < endVal) ? endVal : self.frameVal;
} else {
self.frameVal = (self.frameVal > endVal) ? endVal : self.frameVal;
}
// format and print value
self.d.innerHTML = self.addCommas(self.frameVal.toFixed(decimals));
// whether to continue
if (progress < self.duration) {
self.rAF = requestAnimationFrame(self.count);
} else {
if (self.callback != null) self.callback();
}
}
this.start = function(callback) {
self.callback = callback;
// make sure values are valid
if (!isNaN(endVal) && !isNaN(startVal)) {
self.rAF = requestAnimationFrame(self.count);
} else {
console.log('countUp error: startVal or endVal is not a number');
self.d.innerHTML = '--';
}
return false;
}
this.stop = function() {
cancelAnimationFrame(self.rAF);
}
this.reset = function() {
cancelAnimationFrame(self.rAF);
self.d.innerHTML = self.addCommas(startVal.toFixed(decimals));
}
this.resume = function() {
self.startTime = null;
self.duration = self.remaining;
self.startVal = self.frameVal;
requestAnimationFrame(self.count);
}
this.addCommas = function(nStr) {
nStr += '';
var x, x1, x2, rgx;
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
// format startVal on initialization
self.d.innerHTML = self.addCommas(startVal.toFixed(decimals));
}
// Example:
// var numAnim = new countUp("SomeElementYouWantToAnimate", 0, 99.99, 2, 1.5);
// numAnim.start();
// with optional callback
// numAnim.start(someMethodToCallOnComplete);

523
js/grid.js Normal file
View File

@@ -0,0 +1,523 @@
/*
* debouncedresize: special jQuery event that happens once after a window resize
*
* latest version and complete README available on Github:
* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js
*
* Copyright 2011 @louis_remi
* Licensed under the MIT license.
*/
var $event = $.event,
$special,
resizeTimeout;
$special = $event.special.debouncedresize = {
setup: function() {
$( this ).on( "resize", $special.handler );
},
teardown: function() {
$( this ).off( "resize", $special.handler );
},
handler: function( event, execAsap ) {
// Save the context
var context = this,
args = arguments,
dispatch = function() {
// set correct event type
event.type = "debouncedresize";
$event.dispatch.apply( context, args );
};
if ( resizeTimeout ) {
clearTimeout( resizeTimeout );
}
execAsap ?
dispatch() :
resizeTimeout = setTimeout( dispatch, $special.threshold );
},
threshold: 250
};
// ======================= imagesLoaded Plugin ===============================
// https://github.com/desandro/imagesloaded
// $('#my-container').imagesLoaded(myFunction)
// execute a callback when all images have loaded.
// needed because .load() doesn't work on cached images
// callback function gets image collection as argument
// this is the container
// original: MIT license. Paul Irish. 2010.
// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
// blank image data-uri bypasses webkit log warning (thx doug jones)
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
$.fn.imagesLoaded = function( callback ) {
var $this = this,
deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
hasNotify = $.isFunction(deferred.notify),
$images = $this.find('img').add( $this.filter('img') ),
loaded = [],
proper = [],
broken = [];
// Register deferred callbacks
if ($.isPlainObject(callback)) {
$.each(callback, function (key, value) {
if (key === 'callback') {
callback = value;
} else if (deferred) {
deferred[key](value);
}
});
}
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
if ( deferred ) {
if ( broken.length ) {
deferred.reject( $images, $proper, $broken );
} else {
deferred.resolve( $images );
}
}
if ( $.isFunction( callback ) ) {
callback.call( $this, $images, $proper, $broken );
}
}
function imgLoaded( img, isBroken ) {
// don't proceed if BLANK image, or image is already loaded
if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) {
return;
}
// store element in loaded images array
loaded.push( img );
// keep track of broken and properly loaded images
if ( isBroken ) {
broken.push( img );
} else {
proper.push( img );
}
// cache image and its state for future calls
$.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } );
// trigger deferred progress method if present
if ( hasNotify ) {
deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] );
}
// call doneLoading and clean listeners if all images are loaded
if ( $images.length === loaded.length ){
setTimeout( doneLoading );
$images.unbind( '.imagesLoaded' );
}
}
// if no images, trigger immediately
if ( !$images.length ) {
doneLoading();
} else {
$images.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){
// trigger imgLoaded
imgLoaded( event.target, event.type === 'error' );
}).each( function( i, el ) {
var src = el.src;
// find out if this image has been already checked for status
// if it was, and src has not changed, call imgLoaded on it
var cached = $.data( el, 'imagesLoaded' );
if ( cached && cached.src === src ) {
imgLoaded( el, cached.isBroken );
return;
}
// if complete is true and browser supports natural sizes, try
// to check for image status manually
if ( el.complete && el.naturalWidth !== undefined ) {
imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 );
return;
}
// cached images don't fire load sometimes, so we reset src, but only when
// dealing with IE, or image is complete (loaded) and failed manual check
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
if ( el.readyState || el.complete ) {
el.src = BLANK;
el.src = src;
}
});
}
return deferred ? deferred.promise( $this ) : $this;
};
var Grid = (function() {
// list of items
var $grid = $( '#og-grid' ),
// the items
$items = $grid.children( 'li' ),
// current expanded item's index
current = -1,
// position (top) of the expanded item
// used to know if the preview will expand in a different row
previewPos = -1,
// extra amount of pixels to scroll the window
scrollExtra = 0,
// extra margin when expanded (between preview overlay and the next items)
marginExpanded = 10,
$window = $( window ), winsize,
$body = $( 'html, body' ),
// transitionend events
transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
// support for csstransitions
support = Modernizr.csstransitions,
// default settings
settings = {
minHeight : 100,
speed : 350,
easing : 'ease'
};
function init( config ) {
// the settings..
settings = $.extend( true, {}, settings, config );
// preload all images
$grid.imagesLoaded( function() {
// save item´s size and offset
saveItemInfo( true );
// get window´s size
getWinSize();
// initialize some events
initEvents();
} );
}
// add more items to the grid.
// the new items need to appended to the grid.
// after that call Grid.addItems(theItems);
function addItems( $newitems ) {
$items = $items.add( $newitems );
$newitems.each( function() {
var $item = $( this );
$item.data( {
offsetTop : $item.offset().top,
height : $item.height()
} );
} );
initItemsEvents( $newitems );
}
// saves the item´s offset top and height (if saveheight is true)
function saveItemInfo( saveheight ) {
$items.each( function() {
var $item = $( this );
$item.data( 'offsetTop', $item.offset().top );
if( saveheight ) {
$item.data( 'height', $item.height() );
}
} );
}
function initEvents() {
// when clicking an item, show the preview with the item´s info and large image.
// close the item if already expanded.
// also close if clicking on the item´s cross
initItemsEvents( $items );
// on window resize get the window´s size again
// reset some values..
$window.on( 'debouncedresize', function() {
scrollExtra = 0;
previewPos = -1;
// save item´s offset
saveItemInfo();
getWinSize();
var preview = $.data( this, 'preview' );
if( typeof preview != 'undefined' ) {
hidePreview();
}
} );
}
function initItemsEvents( $items ) {
$items.on( 'click', 'span.og-close', function() {
hidePreview();
return false;
} ).children( 'a' ).on( 'click', function(e) {
var $item = $( this ).parent();
// check if item already opened
current === $item.index() ? hidePreview() : showPreview( $item );
return false;
} );
}
function getWinSize() {
winsize = { width : $window.width(), height : $window.height() };
}
function showPreview( $item ) {
var preview = $.data( this, 'preview' ),
// item´s offset top
position = $item.data( 'offsetTop' );
scrollExtra = 0;
// if a preview exists and previewPos is different (different row) from item´s top then close it
if( typeof preview != 'undefined' ) {
// not in the same row
if( previewPos !== position ) {
// if position > previewPos then we need to take te current preview´s height in consideration when scrolling the window
if( position > previewPos ) {
scrollExtra = preview.height;
}
hidePreview();
}
// same row
else {
preview.update( $item );
return false;
}
}
// update previewPos
previewPos = position;
// initialize new preview for the clicked item
preview = $.data( this, 'preview', new Preview( $item ) );
// expand preview overlay
preview.open();
}
function hidePreview() {
current = -1;
var preview = $.data( this, 'preview' );
preview.close();
$.removeData( this, 'preview' );
}
// the preview obj / overlay
function Preview( $item ) {
this.$item = $item;
this.expandedIdx = this.$item.index();
this.create();
this.update();
}
Preview.prototype = {
create : function() {
// create Preview structure:
this.$title = $( '<h3></h3>' );
this.$description = $( '<p></p>' );
this.$twitter = $('<a href="" class="social"><i class="fa fa-twitter"></i></a>');
this.$facebook = $('<a href="" class="social"><i class="fa fa-facebook"></i></a>');
this.$href = $( '<a href="#">Visit website</a>' );
this.$details = $( '<div class="og-details"></div>' ).append( this.$title, this.$description, this.$twitter, this.$facebook);
this.$loading = $( '<div class="og-loading"></div>' );
this.$fullimage = $( '<div class="og-fullimg"></div>' ).append( this.$loading );
this.$closePreview = $( '<span class="og-close"></span>' );
this.$previewInner = $( '<div class="col-md-offset-2 col-md-8"></div>' ).append( this.$closePreview, this.$details );
this.$row = $('<div class="row"></div>').append(this.$previewInner);
this.$container = $('<div class="container"></div>').append(this.$row)
this.$previewEl = $( '<div class="team-extended"></div>' ).append( this.$container );
// append preview element to the item
this.$item.append( this.getEl() );
// set the transitions for the preview and the item
if( support ) {
this.setTransition();
}
},
update : function( $item ) {
if( $item ) {
this.$item = $item;
}
// if already expanded remove class "og-expanded" from current item and add it to new item
if( current !== -1 ) {
var $currentItem = $items.eq( current );
$currentItem.removeClass( 'og-expanded' );
this.$item.addClass( 'og-expanded' );
// position the preview correctly
this.positionPreview();
}
// update current value
current = this.$item.index();
// update preview´s content
var $itemEl = this.$item.children( 'a' ),
eldata = {
href : $itemEl.attr( 'href' ),
largesrc : $itemEl.data( 'largesrc' ),
title : $itemEl.data( 'title' ),
description : $itemEl.data( 'description' ),
twitter: $itemEl.data('twitter'),
facebook: $itemEl.data('facebook')
};
this.$title.html( eldata.title );
this.$description.html( eldata.description );
this.$twitter.attr('href', 'https://twitter.com/'+eldata.twitter);
this.$facebook.attr('href', 'https://www.facebook.com/'+eldata.facebook);
this.$href.attr( 'href', eldata.href );
var self = this;
// remove the current image in the preview
if( typeof self.$largeImg != 'undefined' ) {
self.$largeImg.remove();
}
// preload large image and add it to the preview
// for smaller screens we don´t display the large image (the media query will hide the fullimage wrapper)
if( self.$fullimage.is( ':visible' ) ) {
this.$loading.show();
$( '<img/>' ).load( function() {
var $img = $( this );
if( $img.attr( 'src' ) === self.$item.children('a').data( 'largesrc' ) ) {
self.$loading.hide();
self.$fullimage.find( 'img' ).remove();
self.$largeImg = $img.fadeIn( 350 );
self.$fullimage.append( self.$largeImg );
}
} ).attr( 'src', eldata.largesrc );
}
},
open : function() {
setTimeout( $.proxy( function() {
// set the height for the preview and the item
this.setHeights();
// scroll to position the preview in the right place
this.positionPreview();
}, this ), 25 );
},
close : function() {
var self = this,
onEndFn = function() {
if( support ) {
$( this ).off( transEndEventName );
}
self.$item.removeClass( 'og-expanded' );
self.$previewEl.remove();
};
setTimeout( $.proxy( function() {
if( typeof this.$largeImg !== 'undefined' ) {
this.$largeImg.fadeOut( 'fast' );
}
this.$previewEl.css( 'height', 0 );
// the current expanded item (might be different from this.$item)
var $expandedItem = $items.eq( this.expandedIdx );
$expandedItem.css( 'height', $expandedItem.data( 'height' ) ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
}, this ), 25 );
return false;
},
calcHeight : function() {
var heightPreview = winsize.height - this.$item.data( 'height' ) - marginExpanded,
itemHeight = winsize.height;
if( heightPreview < settings.minHeight ) {
heightPreview = settings.minHeight;
itemHeight = settings.minHeight + this.$item.data( 'height' ) + marginExpanded;
}
this.height = heightPreview;
this.itemHeight = itemHeight;
},
setHeights : function() {
var self = this,
onEndFn = function() {
if( support ) {
self.$item.off( transEndEventName );
}
self.$item.addClass( 'og-expanded' );
};
this.calcHeight();
this.$previewEl.css( 'height', this.height );
this.$item.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn );
if( !support ) {
onEndFn.call();
}
},
positionPreview : function() {
// scroll page
// case 1 : preview height + item height fits in window´s height
// case 2 : preview height + item height does not fit in window´s height and preview height is smaller than window´s height
// case 3 : preview height + item height does not fit in window´s height and preview height is bigger than window´s height
var position = this.$item.data( 'offsetTop' ),
previewOffsetT = this.$previewEl.offset().top - scrollExtra,
scrollVal = this.height + this.$item.data( 'height' ) + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - ( winsize.height - this.height ) : previewOffsetT;
$body.animate( { scrollTop : scrollVal }, settings.speed );
},
setTransition : function() {
this.$previewEl.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing );
this.$item.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing );
},
getEl : function() {
return this.$previewEl;
}
}
return {
init : init,
addItems : addItems
};
})();

1315
js/jquery.bxslider.js Normal file

File diff suppressed because it is too large Load Diff

344
js/jquery.easypiechart.js Normal file
View File

@@ -0,0 +1,344 @@
/**!
* easyPieChart
* Lightweight plugin to render simple, animated and retina optimized pie charts
*
* @license Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
* @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
* @version 2.1.3
**/
(function(root, factory) {
if(typeof exports === 'object') {
module.exports = factory(require('jquery'));
}
else if(typeof define === 'function' && define.amd) {
define('EasyPieChart', ['jquery'], factory);
}
else {
factory(root.jQuery);
}
}(this, function($) {
/**
* Renderer to render the chart on a canvas object
* @param {DOMElement} el DOM element to host the canvas (root of the plugin)
* @param {object} options options object of the plugin
*/
var CanvasRenderer = function(el, options) {
var cachedBackground;
var canvas = document.createElement('canvas');
if (typeof(G_vmlCanvasManager) !== 'undefined') {
G_vmlCanvasManager.initElement(canvas);
}
var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;
el.appendChild(canvas);
// canvas on retina devices
var scaleBy = 1;
if (window.devicePixelRatio > 1) {
scaleBy = window.devicePixelRatio;
canvas.style.width = canvas.style.height = [options.size, 'px'].join('');
canvas.width = canvas.height = options.size * scaleBy;
ctx.scale(scaleBy, scaleBy);
}
// move 0,0 coordinates to the center
ctx.translate(options.size / 2, options.size / 2);
// rotate canvas -90deg
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);
var radius = (options.size - options.lineWidth) / 2;
if (options.scaleColor && options.scaleLength) {
radius -= options.scaleLength + 2; // 2 is the distance between scale and bar
}
// IE polyfill for Date
Date.now = Date.now || function() {
return +(new Date());
};
/**
* Draw a circle around the center of the canvas
* @param {strong} color Valid CSS color string
* @param {number} lineWidth Width of the line in px
* @param {number} percent Percentage to draw (float between -1 and 1)
*/
var drawCircle = function(color, lineWidth, percent) {
percent = Math.min(Math.max(-1, percent || 0), 1);
var isNegative = percent <= 0 ? true : false;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
ctx.stroke();
};
/**
* Draw the scale of the chart
*/
var drawScale = function() {
var offset;
var length;
var i = 24;
ctx.lineWidth = 1
ctx.fillStyle = options.scaleColor;
ctx.save();
for (var i = 24; i > 0; --i) {
if (i%6 === 0) {
length = options.scaleLength;
offset = 0;
} else {
length = options.scaleLength * .6;
offset = options.scaleLength - length;
}
ctx.fillRect(-options.size/2 + offset, 0, length, 1);
ctx.rotate(Math.PI / 12);
}
ctx.restore();
};
/**
* Request animation frame wrapper with polyfill
* @return {function} Request animation frame method or timeout fallback
*/
var reqAnimationFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
}());
/**
* Draw the background of the plugin including the scale and the track
*/
var drawBackground = function() {
options.scaleColor && drawScale();
options.trackColor && drawCircle(options.trackColor, options.lineWidth, 1);
};
/**
* Clear the complete canvas
*/
this.clear = function() {
ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);
};
/**
* Draw the complete chart
* @param {number} percent Percent shown by the chart between -100 and 100
*/
this.draw = function(percent) {
// do we need to render a background
if (!!options.scaleColor || !!options.trackColor) {
// getImageData and putImageData are supported
if (ctx.getImageData && ctx.putImageData) {
if (!cachedBackground) {
drawBackground();
cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);
} else {
ctx.putImageData(cachedBackground, 0, 0);
}
} else {
this.clear();
drawBackground();
}
} else {
this.clear();
}
ctx.lineCap = options.lineCap;
// if barcolor is a function execute it and pass the percent as a value
var color;
if (typeof(options.barColor) === 'function') {
color = options.barColor(percent);
} else {
color = options.barColor;
}
// draw bar
drawCircle(color, options.lineWidth, percent / 100);
}.bind(this);
/**
* Animate from some percent to some other percentage
* @param {number} from Starting percentage
* @param {number} to Final percentage
*/
this.animate = function(from, to) {
var startTime = Date.now();
options.onStart(from, to);
var animation = function() {
var process = Math.min(Date.now() - startTime, options.animate.duration);
var currentValue = options.easing(this, process, from, to - from, options.animate.duration);
this.draw(currentValue);
options.onStep(from, to, currentValue);
if (process >= options.animate.duration) {
options.onStop(from, to);
} else {
reqAnimationFrame(animation);
}
}.bind(this);
reqAnimationFrame(animation);
}.bind(this);
};
var EasyPieChart = function(el, opts) {
var defaultOptions = {
barColor: '#ef1e25',
trackColor: '#f9f9f9',
scaleColor: '#dfe0e0',
scaleLength: 5,
lineCap: 'round',
lineWidth: 3,
size: 110,
rotate: 0,
animate: {
duration: 1000,
enabled: true
},
easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/
t = t / (d/2);
if (t < 1) {
return c / 2 * t * t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
onStart: function(from, to) {
return;
},
onStep: function(from, to, currentValue) {
return;
},
onStop: function(from, to) {
return;
}
};
// detect present renderer
if (typeof(CanvasRenderer) !== 'undefined') {
defaultOptions.renderer = CanvasRenderer;
} else if (typeof(SVGRenderer) !== 'undefined') {
defaultOptions.renderer = SVGRenderer;
} else {
throw new Error('Please load either the SVG- or the CanvasRenderer');
}
var options = {};
var currentValue = 0;
/**
* Initialize the plugin by creating the options object and initialize rendering
*/
var init = function() {
this.el = el;
this.options = options;
// merge user options into default options
for (var i in defaultOptions) {
if (defaultOptions.hasOwnProperty(i)) {
options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];
if (typeof(options[i]) === 'function') {
options[i] = options[i].bind(this);
}
}
}
// check for jQuery easing
if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {
options.easing = jQuery.easing[options.easing];
} else {
options.easing = defaultOptions.easing;
}
// process earlier animate option to avoid bc breaks
if (typeof(options.animate) === 'number') {
options.animate = {
duration: options.animate,
enabled: true
};
}
if (typeof(options.animate) === 'boolean' && !options.animate) {
options.animate = {
duration: 1000,
enabled: options.animate
};
}
// create renderer
this.renderer = new options.renderer(el, options);
// initial draw
this.renderer.draw(currentValue);
// initial update
if (el.dataset && el.dataset.percent) {
this.update(parseFloat(el.dataset.percent));
} else if (el.getAttribute && el.getAttribute('data-percent')) {
this.update(parseFloat(el.getAttribute('data-percent')));
}
}.bind(this);
/**
* Update the value of the chart
* @param {number} newValue Number between 0 and 100
* @return {object} Instance of the plugin for method chaining
*/
this.update = function(newValue) {
newValue = parseFloat(newValue);
if (options.animate.enabled) {
this.renderer.animate(currentValue, newValue);
} else {
this.renderer.draw(newValue);
}
currentValue = newValue;
return this;
}.bind(this);
/**
* Disable animation
* @return {object} Instance of the plugin for method chaining
*/
this.disableAnimation = function() {
options.animate.enabled = false;
return this;
};
/**
* Enable animation
* @return {object} Instance of the plugin for method chaining
*/
this.enableAnimation = function() {
options.animate.enabled = true;
return this;
};
init();
};
$.fn.easyPieChart = function(options) {
return this.each(function() {
var instanceOptions;
if (!$.data(this, 'easyPieChart')) {
instanceOptions = $.extend({}, options, $(this).data());
$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));
}
});
};
}));

60
js/jquery.inview.js Normal file
View File

@@ -0,0 +1,60 @@
/**
* author Remy Sharp
* url http://remysharp.com/2009/01/26/element-in-view-event-plugin/
*/
(function ($) {
function getViewportHeight() {
var height = window.innerHeight; // Safari, Opera
var mode = document.compatMode;
if ( (mode || !$.support.boxModel) ) { // IE, Gecko
height = (mode == 'CSS1Compat') ?
document.documentElement.clientHeight : // Standards
document.body.clientHeight; // Quirks
}
return height;
}
$(window).scroll(function () {
var vpH = getViewportHeight(),
scrolltop = (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop),
elems = [];
// naughty, but this is how it knows which elements to check for
$.each($.cache, function () {
if (this.events && this.events.inview) {
elems.push(this.handle.elem);
}
});
if (elems.length) {
$(elems).each(function () {
var $el = $(this),
top = $el.offset().top,
height = $el.height(),
inview = $el.data('inview') || false;
if (scrolltop > (top + height) || scrolltop + vpH < top) {
if (inview) {
$el.data('inview', false);
$el.trigger('inview', [ false ]);
}
} else if (scrolltop < (top + height)) {
if (!inview) {
$el.data('inview', true);
$el.trigger('inview', [ true ]);
}
}
});
}
});
// kick the event to pick up any elements already in view.
// note however, this only works if the plugin is included after the elements are bound to 'inview'
$(function () {
$(window).scroll();
});
})(jQuery);

2
js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

160
js/jquery.label_better.js Normal file
View File

@@ -0,0 +1,160 @@
/* ===========================================================
* jquery-label_better.js v1.1
* ===========================================================
* Copyright 2013 Pete Rojwongsuriya.
* http://www.thepetedesign.com
*
* Label your form input like a boss with
* beautiful animation and without taking up space
*
* https://github.com/peachananr/label_better
*
* ========================================================== */
!function($){
var defaults = {
position: "top",
animationTime: 500,
easing: "ease-in-out",
offset: 20,
hidePlaceholderOnFocus: true
};
$.fn.animateLabel = function(settings, btn) {
var position = btn.data("position") || settings.position,
posx = 0,
posy = 0;
$(this).css({
"left": "auto",
"right": "auto",
"position": "absolute",
"-webkit-transition": "all " + settings.animationTime + "ms " + settings.easing,
"-moz-transition": "all " + settings.animationTime + "ms " + settings.easing,
"-ms-transition": "all " + settings.animationTime + "ms " + settings.easing,
"transition": "all " + settings.animationTime + "ms " + settings.easing
});
switch (position) {
case 'top':
posx = 0;
posy = ($(this).height() + settings.offset) * -1;
$(this).css({
"top": "0",
"opacity": "1",
"-webkit-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-moz-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-ms-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"transform": "translate3d(" + posx + ", " + posy + "px, 0)"
});
break;
case 'bottom':
posx = 0;
posy = ($(this).height() + settings.offset);
$(this).css({
"bottom": "0",
"opacity": "1",
"-webkit-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-moz-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-ms-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"transform": "translate3d(" + posx + ", " + posy + "px, 0)"
});
break;
case 'left':
posx = ($(this).width() + settings.offset) * -1;
posy = 0;
$(this).css({
"left": 0,
"top": 0,
"opacity": "1",
"-webkit-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"-moz-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"-ms-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"transform": "translate3d(" + posx + "px, " + posy + "px, 0)"
});
break;
case 'right':
posx = $(this).width() + settings.offset;
posy = 0;
$(this).css({
"right": 0,
"top": 0,
"opacity": "1",
"-webkit-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"-moz-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"-ms-transform": "translate3d(" + posx + "px, " + posy + "px, 0)",
"transform": "translate3d(" + posx + "px, " + posy + "px, 0)"
});
break;
}
}
$.fn.removeAnimate = function(settings, btn) {
var position = btn.data("position") || settings.position,
posx = 0,
posy = 0;
$(this).css({
"top": "0",
"opacity": "0",
"-webkit-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-moz-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"-ms-transform": "translate3d(" + posx + ", " + posy + "px, 0)",
"transform": "translate3d(" + posx + ", " + posy + "px, 0)"
});
}
$.fn.label_better = function(options){
var settings = $.extend({}, defaults, options),
el = $(this),
triggerIn = "focus",
triggerOut = "blur";
if(settings.easing == "bounce") settings.easing = "cubic-bezier(0.175, 0.885, 0.420, 1.310)"
el.each(function( index, value ) {
var btn = $(this),
position = btn.data("position") || settings.position;
btn.wrapAll("<div class='lb_wrap' style='position:relative; display: inline;'></div>")
if( btn.val().length > 0) {
var text = btn.data("new-placeholder") || btn.attr("placeholder");
$("<div class='lb_label " + position + "'>"+ text + "</div>").css("opacity", "0").insertAfter(btn).animateLabel(settings, btn);
}
btn.bind(triggerIn, function() {
if(btn.val().length < 1) {
var text = btn.data("new-placeholder") || btn.attr("placeholder"),
position = btn.data("position") || settings.position;
$("<div class='lb_label " + position + "'>"+ text + "</div>").css("opacity", "0").insertAfter(btn).animateLabel(settings, btn);
}
if (settings.hidePlaceholderOnFocus == true) {
btn.data("default-placeholder", btn.attr("placeholder"))
btn.attr("placeholder", "")
}
btn.parent().find(".lb_label").addClass("active");
}).bind(triggerOut, function() {
if(btn.val().length < 1) {
btn.parent().find(".lb_label").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ $(this).remove(); }).removeAnimate(settings, btn)
}
if (settings.hidePlaceholderOnFocus == true) {
btn.attr("placeholder", btn.data("default-placeholder"))
btn.data("default-placeholder", "")
}
btn.parent().find(".lb_label").removeClass("active");
});
});
}
}(window.jQuery);

1356
js/jquery.mixitup.js Normal file

File diff suppressed because it is too large Load Diff

269
js/main.js Normal file
View File

@@ -0,0 +1,269 @@
'use strict';
//Initial testimonial slider
$('#testimonials').bxSlider({
mode: 'fade',
auto: true,
autoControls: true,
controls: false
});
//carusel for clients
$('.client-slider').bxSlider({
pager: false,
minSlides: 1,
maxSlides: 6,
moveSlides: 2,
slideWidth: 130,
slideMargin: 25,
prevSelector: $('#client-prev'),
nextSelector: $('#client-next'),
prevText: '<i class="fa fa-angle-double-left"></i>',
nextText: '<i class="fa fa-angle-double-right"></i>'
});
$('.text-slider').bxSlider({
pager: false,
prevText: '<i class="fa fa-angle-left fa-3x"></i>',
nextText: '<i class="fa fa-angle-right fa-3x"></i>'
});
//Efext on labels on contact form
$("input.label_better, textarea.label_better").label_better({
animationTime: 500,
easing: "bounce",
offset: 0,
hidePlaceholderOnFocus: true
});
$("#Grid").mixitup({});
function homeFullScreen() {
var homeSection = $('.home');
var windowHeight = $(window).outerHeight();
if (homeSection.hasClass('home-fullscreen')) {
$('.home-fullscreen').css('height', windowHeight);
}
}
function stickyMenu() {
var scrollTop = $(window).scrollTop();
var offset = 0;
if (scrollTop > offset) {
$('#navbar').addClass('navbar-small');
} else {
$('#navbar').removeClass('navbar-small');
}
}
function inviewAnimation() {
$('.skills').bind('inview', function () {
$('.skill').easyPieChart({
size: 140,
animate: 2000,
lineWidth: 6,
lineCap: 'square',
barColor: '#ffe600',
trackColor: '#ffffff',
scaleColor: false
});
})
$('.numbers').one('inview', function (event, visible) {
if (visible === true) {
$('.numbers .number').each(function () {
var element = $(this);
var duration = element.attr('data-duration');
var count = element.attr('data-count')
var id = element.attr('id');
var numAnim = new countUp(id, 0, count, 0, duration);
numAnim.start();
})
}
})
$('.heading > h1').one('inview', function(event, visible){
$(this).addClass('animate fadeInRight');
});
$('.heading > div').one('inview', function(event, visible){
$(this).addClass('animate fadeInLeft');
});
$('.process-item').one('inview', function(event, visible){
$(this).addClass('animate fadeInLeft');
});
$('.service-item').one('inview', function(event, visible){
$(this).addClass('animate');
})
$('.adress-element').one('inview', function(event, visible){
$(this).addClass('animate fadeInUp');
})
$('.about-item').one('inview', function(event, visible){
$(this).addClass('animate fadeInUp');
})
}
function filterPath(string) {
return string.replace(/^\//, '').replace(/(index|default).[a-zA-Z]{3,4}$/, '').replace(/\/$/, '');
}
function singlePageNav() {
var lastId,
topMenu = $(".navbar"),
topMenuHeight = topMenu.outerHeight(),
// All list items
menuItems = topMenu.find("a"),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function () {
var item = $($(this).attr("href"));
if (item.length) {
return item;
}
});
$('a[href*=#]').each(function () {
if (filterPath(location.pathname) == filterPath(this.pathname) && location.hostname == this.hostname && this.hash.replace(/#/, '')) {
var $targetId = $(this.hash),
$targetAnchor = $('[name=' + this.hash.slice(1) + ']');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false;
if ($target) {
$(this).click(function () {
//Hack collapse top navigation after clicking
topMenu.parent().attr('style', 'height:0px').removeClass('in'); //Close navigation
$('.navbar .btn-navbar').addClass('collapsed');
var targetOffset = $target.offset().top - 52;
$('html, body').animate({
scrollTop: targetOffset
}, 800);
return false;
});
}
}
});
// Bind to scroll
$(window).scroll(function () {
//Display or hide scroll to top button
if ($(this).scrollTop() > 100) {
$('.scrollup').fadeIn();
} else {
$('.scrollup').fadeOut();
}
// Get container scroll position
var fromTop = $(this).scrollTop() + topMenuHeight + 10;
// Get id of current scroll item
var cur = scrollItems.map(function () {
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length - 1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id) {
lastId = id;
// Set/remove active class
menuItems
.parent().removeClass("active")
.end().filter("[href=#" + id + "]").parent().addClass("active");
}
});
}
function openProject() {
var portfolioItem = $('.portfolio-item > a');
var singleProject = $('#single-project');
var loader = "<div class=\"project-loader\"><div class=\"bubblingG\"><span id=\"bubblingG_1\"></span><span id=\"bubblingG_2\"></span><span id=\"bubblingG_3\"></span></div>Loading...</div>";
portfolioItem.click(function () {
var link = $(this).attr('href');
$('html, body').animate({
scrollTop: singleProject.offset().top - 90
}, 500);
singleProject.slideUp(500).addClass("project");
singleProject.after(loader);
singleProject.empty();
setTimeout(function () {
singleProject.load(link, function (response, status) {
if (status === "error") {
alert("An error");
} else {
singleProject.slideDown(500);
var closeProject = $('#close-project');
closeProject.on('click', function () {
singleProject.slideUp(500);
setTimeout(function () {
singleProject.empty();
}, 500);
});
}
$('.project-loader').remove();
});
}, 500);
return false;
});
}
//Initialization
openProject();
homeFullScreen();
inviewAnimation();
singlePageNav();
window.onload = function() {
$('#wrapper').removeClass('loading');
$('.loader').addClass('removing');
setTimeout(function(){
$('.loader').remove();
}, 2000)
};
//What happen on window resize
$(window).resize(function () {
homeFullScreen();
});
//What happen on window scroll
$(window).on("scroll", function (e) {
setTimeout(function () {
stickyMenu();
}, 300)
});

4
js/modernizr.custom.js Normal file

File diff suppressed because one or more lines are too long