<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/bpainter/pen/azNZdK?depth=everything&order=popularity&page=36&q=services&show_forks=false" />
<script src="https://s.codepen.io/assets/libs/modernizr.js" type="text/javascript"></script>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css'>
<style class="cp-pen-styles">@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,700);
@-webkit-keyframes gradientAnimation {
0% {
background-position: 50% 0%;
}
50% {
background-position: 50% 100%;
}
100% {
background-position: 50% 0%;
}
}
@-moz-keyframes AnimationName {
0% {
background-position: 50% 0%;
}
50% {
background-position: 50% 100%;
}
100% {
background-position: 50% 0%;
}
}
@keyframes AnimationName {
0% {
background-position: 50% 0%;
}
50% {
background-position: 50% 100%;
}
100% {
background-position: 50% 0%;
}
}
html {
font: 100% Open Sans;
}
.typed-cursor {
opacity: 1;
-webkit-animation: blink 0.7s infinite;
-moz-animation: blink 0.7s infinite;
animation: blink 0.7s infinite;
}
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-moz-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
nav {
padding: 24px 24px;
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 10;
}
nav a {
border: 2px solid transparent;
color: #fff;
padding: 12px 24px;
text-decoration: none;
text-transform: uppercase;
}
nav a:hover {
border-color: #fff;
}
nav ul {
float: right;
}
nav li {
display: inline-block;
margin-left: 6px;
}
#logo {
display: block;
float: left;
padding: 12px 24px;
}
#masthead {
background-color: #4F8CC1;
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzNiNzM4YiIvPjxzdG9wIG9mZnNldD0iMTYuNjY2NjclIiBzdG9wLWNvbG9yPSIjNTc5ZmM1Ii8+PHN0b3Agb2Zmc2V0PSIzMy4zMzMzMyUiIHN0b3AtY29sb3I9IiNjMDRhMzQiLz48c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2UxNzA1YiIvPjxzdG9wIG9mZnNldD0iNjYuNjY2NjclIiBzdG9wLWNvbG9yPSIjMjA0ZTQwIi8+PHN0b3Agb2Zmc2V0PSI4My4zMzMzMyUiIHN0b3AtY29sb3I9IiM1NzljODciLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMzYjczOGEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #3b738b), color-stop(16.66667%, #579fc5), color-stop(33.33333%, #c04a34), color-stop(50%, #e1705b), color-stop(66.66667%, #204e40), color-stop(83.33333%, #579c87), color-stop(100%, #3b738a));
background: -moz-linear-gradient(#3b738b, #579fc5, #c04a34, #e1705b, #204e40, #579c87, #3b738a);
background: -webkit-linear-gradient(#3b738b, #579fc5, #c04a34, #e1705b, #204e40, #579c87, #3b738a);
background: linear-gradient(#3b738b, #579fc5, #c04a34, #e1705b, #204e40, #579c87, #3b738a);
background-size: 1400% 1400%;
-moz-animation: gradientAnimation 240s ease infinite;
-webkit-animation: gradientAnimation 240s ease infinite;
animation: gradientAnimation 240s ease infinite;
min-height: 500px;
position: relative;
overflow: hidden;
}
#masthead h1 {
color: #fff;
line-height: 1;
margin: 0 auto;
padding: 0;
font-size: 50px;
font-weight: 100;
position: relative;
top: 180px;
max-width: 90%;
z-index: 100;
word-spacing: 0.3em;
text-transform: uppercase;
text-align: center;
}
#masthead strong,
#masthead span {
font-size: 72px;
}
#nodes {
opacity: .4;
position: absolute;
overflow: hidden;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
}
</style></head><body>
<nav role="navigation">
<a href="#" id="logo">Logo</a>
<ul>
<li>
<a href="#">Home</a>
</li>
<li>
<a href="#">Services</a>
</li>
<li>
<a href="#">Approach</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</nav>
<section id="masthead" role="banner">
<h1>
In-House Support With <br /><strong id="typing-text"></strong>
</h1>
<canvas id="nodes"></canvas>
</section>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script>// jQuery extension for dynamic font sizes
// Source: github.com/NathanRutzky/jQuery.fontFlex
// Version: 1.0
(function($) {
$.fn.fontFlex = function(min, max, mid) {
var $this = this;
$(window).resize(function() {
var size = window.innerWidth / mid;
if (size < min) size = min;
if (size > max) size = max;
$this.css('font-size', size + 'px');
}).trigger('resize');
};
})(jQuery);</script>
<script>// The MIT License (MIT)
// Typed.js | Copyright (c) 2014 Matt Boldt | www.mattboldt.com
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
! function($) {
"use strict";
var Typed = function(el, options) {
// chosen element to manipulate text
this.el = $(el);
// options
this.options = $.extend({}, $.fn.typed.defaults, options);
// attribute to type into
this.isInput = this.el.is('input');
this.attr = this.options.attr;
// show cursor
this.showCursor = this.isInput ? false : this.options.showCursor;
// text content of element
this.elContent = this.attr ? this.el.attr(this.attr) : this.el.text()
// html or plain text
this.contentType = this.options.contentType;
// typing speed
this.typeSpeed = this.options.typeSpeed;
// add a delay before typing starts
this.startDelay = this.options.startDelay;
// backspacing speed
this.backSpeed = this.options.backSpeed;
// amount of time to wait before backspacing
this.backDelay = this.options.backDelay;
// input strings of text
this.strings = this.options.strings;
// character number position of current string
this.strPos = 0;
// current array position
this.arrayPos = 0;
// number to stop backspacing on.
// default 0, can change depending on how many chars
// you want to remove at the time
this.stopNum = 0;
// Looping logic
this.loop = this.options.loop;
this.loopCount = this.options.loopCount;
this.curLoop = 0;
// for stopping
this.stop = false;
// custom cursor
this.cursorChar = this.options.cursorChar;
// All systems go!
this.build();
};
Typed.prototype = {
constructor: Typed
,
init: function() {
// begin the loop w/ first current string (global self.string)
// current string will be passed as an argument each time after this
var self = this;
self.timeout = setTimeout(function() {
// Start typing
self.typewrite(self.strings[self.arrayPos], self.strPos);
}, self.startDelay);
}
,
build: function() {
// Insert cursor
if (this.showCursor === true) {
this.cursor = $("<span class=\"typed-cursor\">" + this.cursorChar + "</span>");
this.el.after(this.cursor);
}
this.init();
}
// pass current string state to each function, types 1 char per call
,
typewrite: function(curString, curStrPos) {
// exit when stopped
if (this.stop === true) {
return;
}
// varying values for setTimeout during typing
// can't be global since number changes each time loop is executed
var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed;
var self = this;
// ------------- optional ------------- //
// backpaces a certain string faster
// ------------------------------------ //
// if (self.arrayPos == 1){
// self.backDelay = 50;
// }
// else{ self.backDelay = 500; }
// contain typing function in a timeout humanize'd delay
self.timeout = setTimeout(function() {
// check for an escape character before a pause value
// format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
// single ^ are removed from string
var charPause = 0;
var substr = curString.substr(curStrPos);
if (substr.charAt(0) === '^') {
var skip = 1; // skip atleast 1
if (/^\^\d+/.test(substr)) {
substr = /\d+/.exec(substr)[0];
skip += substr.length;
charPause = parseInt(substr);
}
// strip out the escape character and pause value so they're not printed
curString = curString.substring(0, curStrPos) + curString.substring(curStrPos + skip);
}
if (self.contentType === 'html') {
// skip over html tags while typing
if (curString.substr(curStrPos).charAt(0) === '<') {
var tag = '';
while (curString.substr(curStrPos).charAt(0) !== '>') {
tag += curString.substr(curStrPos).charAt(0);
curStrPos++;
}
curStrPos++;
tag += '>';
}
}
// timeout for any pause after a character
self.timeout = setTimeout(function() {
if (curStrPos === curString.length) {
// fires callback function
self.options.onStringTyped(self.arrayPos);
// is this the final string
if (self.arrayPos === self.strings.length - 1) {
// animation that occurs on the last typed string
self.options.callback();
self.curLoop++;
// quit if we wont loop back
if (self.loop === false || self.curLoop === self.loopCount)
return;
}
self.timeout = setTimeout(function() {
self.backspace(curString, curStrPos);
}, self.backDelay);
} else {
/* call before functions if applicable */
if (curStrPos === 0)
self.options.preStringTyped(self.arrayPos);
// start typing each new char into existing string
// curString: arg, self.el.html: original text inside element
var nextString = self.elContent + curString.substr(0, curStrPos + 1);
if (self.attr) {
self.el.attr(self.attr, nextString);
} else {
if (self.contentType === 'html') {
self.el.html(nextString);
} else {
self.el.text(nextString);
}
}
// add characters one by one
curStrPos++;
// loop the function
self.typewrite(curString, curStrPos);
}
// end of character pause
}, charPause);
// humanized value for typing
}, humanize);
}
,
backspace: function(curString, curStrPos) {
// exit when stopped
if (this.stop === true) {
return;
}
// varying values for setTimeout during typing
// can't be global since number changes each time loop is executed
var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed;
var self = this;
self.timeout = setTimeout(function() {
// ----- this part is optional ----- //
// check string array position
// on the first string, only delete one word
// the stopNum actually represents the amount of chars to
// keep in the current string. In my case it's 14.
// if (self.arrayPos == 1){
// self.stopNum = 14;
// }
//every other time, delete the whole typed string
// else{
// self.stopNum = 0;
// }
if (self.contentType === 'html') {
// skip over html tags while backspacing
if (curString.substr(curStrPos).charAt(0) === '>') {
var tag = '';
while (curString.substr(curStrPos).charAt(0) !== '<') {
tag -= curString.substr(curStrPos).charAt(0);
curStrPos--;
}
curStrPos--;
tag += '<';
}
}
// ----- continue important stuff ----- //
// replace text with base text + typed characters
var nextString = self.elContent + curString.substr(0, curStrPos);
if (self.attr) {
self.el.attr(self.attr, nextString);
} else {
if (self.contentType === 'html') {
self.el.html(nextString);
} else {
self.el.text(nextString);
}
}
// if the number (id of character in current string) is
// less than the stop number, keep going
if (curStrPos > self.stopNum) {
// subtract characters one by one
curStrPos--;
// loop the function
self.backspace(curString, curStrPos);
}
// if the stop number has been reached, increase
// array position to next string
else if (curStrPos <= self.stopNum) {
self.arrayPos++;
if (self.arrayPos === self.strings.length) {
self.arrayPos = 0;
self.init();
} else
self.typewrite(self.strings[self.arrayPos], curStrPos);
}
// humanized value for typing
}, humanize);
}
// Start & Stop currently not working
// , stop: function() {
// var self = this;
// self.stop = true;
// clearInterval(self.timeout);
// }
// , start: function() {
// var self = this;
// if(self.stop === false)
// return;
// this.stop = false;
// this.init();
// }
// Reset and rebuild the element
,
reset: function() {
var self = this;
clearInterval(self.timeout);
var id = this.el.attr('id');
this.el.after('<span id="' + id + '"/>')
this.el.remove();
this.cursor.remove();
// Send the callback
self.options.resetCallback();
}
};
$.fn.typed = function(option) {
return this.each(function() {
var $this = $(this),
data = $this.data('typed'),
options = typeof option == 'object' && option;
if (!data) $this.data('typed', (data = new Typed(this, options)));
if (typeof option == 'string') data[option]();
});
};
$.fn.typed.defaults = {
strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
// typing speed
typeSpeed: 0,
// time before typing starts
startDelay: 0,
// backspacing speed
backSpeed: 0,
// time before backspacing
backDelay: 500,
// loop
loop: false,
// false = infinite
loopCount: false,
// show cursor
showCursor: true,
// character for cursor
cursorChar: "|",
// attribute to type (null == text)
attr: null,
// either html or text
contentType: 'html',
// call when done callback function
callback: function() {},
// starting callback function before each string
preStringTyped: function() {},
//callback for every typed string
onStringTyped: function() {},
// callback for reset
resetCallback: function() {}
};
}(window.jQuery);</script>
<script >$(function() {
// H1 only
// $('h1').fontFlex(36, 48, 120);
$("#typing-text").typed({
strings: [
"Project Services.", "Information Security.",
"Systems Development.",
"Consulting Services.",
"Network & Infrastructure.",
"Support & Operations.",
"Architecture & IT Strategy.",
"User Experience Design."
],
typeSpeed: 100,
backDelay: 2000,
// loop
loop: true,
});
});
var canvas = document.getElementById('nodes')
, context = canvas.getContext('2d')
, pool = []
, maxPoolSize = 500
, distanceThreshold = 90
, lastTimestamp = 0
, nodeConnections = []
;
canvas.width = window.innerWidth;
canvas.height = 500;
maxPoolSize = ( canvas.width * canvas.height ) / 6000
function Boid(x,y) {
this.id = Boid.lastId++;
this.position = [x, y];
this.size = 10;
this.color = "red";
this.velocity = [25-Math.random()*30, 25-Math.random()*80];
};
Boid.lastId = 0;
Boid.prototype = {
update: function(dt) {
for (var i = 0; i < maxPoolSize; i++) {
var boid = pool[i]
, distance = this.distanceTo(boid)
;
if(distance < distanceThreshold) {
cohesion = []
}
};
this.position[0] += this.velocity[0] * dt;
this.position[1] += this.velocity[1] * dt;
if(this.position[0] > canvas.width) {
this.position[0] = 0;
// this.velocity[0] *= -1;
}
if(this.position[1] > canvas.height) {
this.position[1] = 0;
// this.velocity[1] *= -1;
}
if(this.position[0] < 0) {
this.position[0] = canvas.width;
// this.velocity[0] *= -1;
}
if(this.position[1] < 0) {
this.position[1] = canvas.height;
// this.velocity[1] *= -1;
};
},
distanceTo: function(boid) {
var diff = vDiff(this.position, boid.position);
return Math.abs(vLength(diff));
},
isConnectedTo: function(boid) {
return nodeConnections[boid.id] == this.id
|| nodeConnections[this.id] == boid.id;
},
connectTo: function(boid) {
nodeConnections[this.id] = boid.id;
nodeConnections[boid.id] = this.id;
},
draw: function() {
var pos = [round(this.position[0]), round(this.position[1])]
, connections = 0;
context.globalAlpha = 0.1;
for (var i = 0; i < maxPoolSize; i++) {
var boid = pool[i]
, distance = this.distanceTo(boid)
, opacity = 1-( distance/distanceThreshold )
;
if(distance <= distanceThreshold) {
connections++;
if(!this.isConnectedTo( boid )){
this.connectTo(boid);
context.beginPath();
context.moveTo( pos[0], pos[1]);
context.lineTo(round( boid.position[0] ), round( boid.position[1] ));
context.stroke();
}
}
};
context.globalAlpha = 0.5;
context.beginPath();
context.arc(
pos[0],
pos[1],
this.size*( connections/5 ),
0, Math.PI*2
);
context.fill();
}
};
function vDiff(a, b) {
return [ a[0] - b[0], a[1] - b[1] ];
}
function vLength(a) {
return Math.sqrt( ( a[0]*a[0] ) + (a[1]*a[1]) );
}
function round(i) { return 0.5 + i | 0 }
function draw(timestamp) {
var dt = ( timestamp - (lastTimestamp || timestamp) ) / 1000;
lastTimestamp = timestamp;
context.clearRect(0,0,canvas.width, canvas.height);
for (var i = 0; i < maxPoolSize; i++) {
var boid = pool[i];
boid.update(dt);
boid.draw();
}
window.requestAnimFrame(draw);
}
window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ window.setTimeout(callback, 1000 / 60); }; })();
for (var i = 0; i < maxPoolSize; i++) {
pool.push(
new Boid(Math.random()*canvas.width, Math.random()*canvas.height)
);
}
document.body.appendChild(canvas);
window.requestAnimFrame(draw);
//# sourceURL=pen.js
</script>
</body></html>