This commit is contained in:
Martti Malmi 2015-04-28 14:37:34 +03:00
parent ab51e16176
commit 98ae1b7310
32 changed files with 10578 additions and 219 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
illusions/black-cat.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
illusions/construction.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
illusions/life.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 106 KiB

BIN
illusions/purple-cat.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
illusions/stars.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 KiB

View File

@ -1,219 +1,158 @@
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fi" xml:lang="fi">
<!--
. . IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
.IMMMMMMMMMMMMMM8I . ... . =MMMM
:MMMMMMMMMZ . 7MMMMZ . 7MD . IMMD .
MMMMM. . . . .~ .M, . MMM .
MMMM, N. .IDMMMO777ZNMMMMMO =MM . M:. NMM.
. ZMMM . . :7NMMDI= . MM IM MMM
MMM IMM77IDMMM, . M8 ..MM M ,N MMM
M8 M M . M ,O . 7. MM
.M8 D ,. ... M 7 MM
MM. 7 = . ~MMMMMN, . 7MM
MMM .. N. MMMMMMMMMMMMMMMO. MMM
.MMM MMMMMMMMM+. ZMMMZ $MMMMMMMMMMM.. MMM
MMMD. . ..ZMMM78MMMMMMMMM MMM. .. DMMMMMMMMMMM8MM MM7 . OMMMM .
MMM MM:. . MMMMMMMMMMMMMMMMM IMM MMMMMMO .DMMMMM.. . . +O MMM.
.MMM ?D OMMMMM .,MMMMM+ MM MMMMMMMM. ?.MM..
MMM M :M. .7M8 MM . MMMN .. =MMMMM. . :MMM :.MMM.
MMM. 8. MMMMMMMMMZ. MM MMMMMMMMMMMM~ M MM. MM$
.MMOM M . .. MMMMMM$ . MMM . MM .MM MM
NMMM M 8M O88I MMMM 7~ . . .:MMMMMM MM MM
MMM $ . MM . MMM~ ~MMMMMMM MMMMM=.7MMMM MM . MM
NM7I M MMM: MMMMM MM MMMMMM . MMMZMMM.MM. 8 MM
MM MM .+MMMM =M M,MMD MMMMMMM $MM DMMMMMM.. ZMM. .MM .8..MMM.
MM? :M MMMMMM .. . . MM . . . MMM .MMMMMMMI=MM MMMM M N MMM
.MM MMMMMMMMM 8MMMM .ZMMMMMM? . MMM. ,MMMMMM . =. MMM
MMM. MMMM MMMMMMM8 . MM . :MMMMMMMMM NMMMMMMMMMMM .MMM.
.MM IMMM= MM ?MMMMMMMMMMMMMMMMMMMMMMM8 . MM . MMMMMMM . MMN 8 MM8
MM 7MMM MM .MM $MMMMM7 .MM.. .MM. MMMMMMMMMMD. MM~ MMM
7M ..=MMMMMMM?. MMI MMM MM . ?MMMMMMMMMM MM .MMI . MMM.
M= MMMMMMMMMMMMMMN~ .8M= MM 7MMMMMMMMMMMM, MM8MMM .,MM
M= MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM8 MMMM . MM.
=M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM+ 8MM MMM$ MM
.8M. MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MM . =MMMM. 7MM.
MM MM.MM MM.ZMMMM7=MMMM . MM ZMM MMMMM MMM.
MM MMZMM ~MM MMM ..~MM MM MMMMMMM . $MM$
MM ~MMM, MMM MM=. MM MM MMMMMMZ .M7 .MM ~MMM
,MM MMMMMMMMD. MM MM MMO~.7MMMMMMMM=.. NM.. MM DMMM
MMI . =MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM~. .M?. ,MM =MMMM
MM. D. . .. . . . .M= . ZMD . MMMM
MM. M M . .8MMMMMMMMMMMMM. MZ MM? . =MMMM
MM. I .MM ... .MM= .MM. ZMMMM
MM ,N . ,+777- -, ... ?MM MMMMM
MM. MMO. .. . . . 7MO . ?MMMM
MMZ .. .==~=. . . MMMM.
MM . . MMMM
MMM .. MMMMMMMMMM
.MMM7 ZMMMMMMMMN:
DMMMMMMMMMMMMMMMMMMMMMMMM? . .
. 7MMMMMMMMMMMMZ. . ..
-->
<head>
<title>Martti Malmi</title>
<link rel="shortcut icon" href="favicon.ico" />
<style type="text/css">
body {
text-align: center;
padding: 0px 0px 50px 0px;
margin:0px;
font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
}
div.main {
text-align: left;
margin: 30px auto;
background-color: #FFFFFF;
border-right: 0px solid #EEE;
border-left: 0px solid #EEE;
max-width: 800px;
padding: 0 5px;
}
a { color: #A22; text-decoration: none; }
a:hover { color: #A22; text-decoration: underline; }
img { border: 0px; }
#pic img { float: left; margin-right: 25px; }
#content { clear: both; padding-top: 20px; border-bottom: 1px solid #EEE; }
#header { color: #555; padding: 32px 0px; font-size: 18px; border-top: 1px solid #EEE; border-bottom: 1px solid #EEE; }
#header li { margin: 0px 0px 10px 0px; }
h1 { font-size: 36px; margin: 50px 0px 20px 0px; }
h2 {
margin:0px;
float: left;
color: #000;
font-size: 24px;
}
ul { list-style-type: none; }
li { margin: 0px 0px 18px 0px; }
.clear { clear:both; }
.block { clear:both; margin-bottom: 60px; }
.block ul { margin-left: 160px; }
.block ul b { margin-right: 5px; }
.block ul img { margin: 10px 0px;}
@media (max-width: 799px) {
#header { text-align:center; padding: 10px 0px; }
#header ul { margin:0; padding:0;}
#pic img { float:none; max-width:20%; margin:0; }
h2 { float:none; margin-left:5px; }
.block ul { margin-left:0px; }
img { max-width: 90%; }
h2 img{max-width:100%;}
h1 { margin: 20px 0 }
}
</style>
</head>
<body>
<div class="main">
<div id="header">
<div id="pic"><img alt="Lily!" src="lily.png"/></div>
<h1><img alt="Martti Malmi" src="title9.png" /></h1>
<ul>
<li>Software developer, digital culture enthusiast</li>
<li><a href="mailto:martti.malmi@aalto.fi">martti.malmi@aalto.fi</a> (<a href="mmalmi.pgp">PGP</a>)</li>
<li><a href="https://github.com/mmalmi">GitHub</a>
<li><a href="http://fi.linkedin.com/pub/martti-malmi/11/25/102"><img alt="LinkedIn Profile" src="linkedin3.png"/></a></li>
</ul>
<div class="clear"></div>
</div>
<div id="content">
<div class="block">
<h2><img alt="Me" src="me.png"/></h2>
<ul>
<li>Born in Rovaniemi, Finland, 1988 A.D.</li>
<li>I like playing guitar and keyboards, LAN parties, FPS and RTS games, indoor climbing, latino dances, imageboards, funny Youtube videos and bad action movies.</li>
<li>I also like Japan! Check out my 2011 travel blog <a href="http://morzenjapan.blogspot.com">Mårzen in Japan</a> (in Finnish).</li>
<li>I'm interested in topics such as music, languages, cultural evolution, Internet memes, economics and society. As for technology, I'm more interested in its human implications than technical intricacies.</li>
<li>Open-minded <a href="http://en.wikipedia.org/wiki/INTP">INTP</a> personality.</li>
<li><img src="fillari2-small.jpg" alt="Travelling in Fukuoka, Japan"/></li>
</ul>
</div>
<div class="block">
<h2><img alt="Education" src="education.png"/></h2>
<ul>
<li><b>2003</b> Finnish National Board of Education: Award from improving IT usage in educational institute (Mankkaa school).</li>
<li><b>2007</b> Ylioppilastutkinto (The Finnish Matriculation Examination), Olari high school.</li>
<li><b>2007 - 2009</b> Computer science studies at Helsinki University of Technology. Mostly programming courses.</li>
<li><b>2011</b> 9 weeks of Japanese studies at <a href="http://www.genkijacs.com/">GenkiJACS</a>, Fukuoka, Japan.</li>
</ul>
</div>
<div class="block">
<h2><img alt="Experience" src="experience.png"/></h2>
<ul>
<li><b>2004</b> Verkkokauppa.com, junior high school traineeship. 2 weeks of mostly warehouse work, but my friend and I also spent a day coding a PHP script that parsed warehouse receipts and searched product codes for the listed items. The script saved a lot of manual work so they rewarded us with gift cards.</li>
<li><b>2007 - 2010</b> Various part time jobs at warehouses and construction sites.</li>
<li><b>2009 - 2011</b> Developer of the P2P virtual currency <a
href="http://www.bitcoin.org/">Bitcoin</a>. I was the first person to join the project and had the privilege to work with the infamous man of mystery, <a href="http://en.wikipedia.org/wiki/Satoshi_Nakamoto#Creator">Satoshi Nakamoto</a>. My tasks included community building, project organization, web design, web app development, server administration, C++ programming and documentation in English. Check out my interviews by <a href="http://www.businessinsider.com/bitcoins-martti-malmi-not-worried-about-liberty-reserve-2013-5">Business Insider</a>, <a href="http://www.iltasanomat.fi/digi/art-1288496063056.html">Ilta-Sanomat</a> (in Finnish) and <a href="http://www.talouselama.fi/uutiset/bitcoin+mullistaa+maksuliikennetta/a729735">Tietoviikko</a> (in Finnish).</li>
<li><b>8.3. - 30.6.2010</b> Siemens, trainee at the corporate communications department. Compilation of the company website content using a CMS. The work included presentation logic planning, illustration using Adobe Photoshop, proof-reading, co-working with product managers, some CMS user support and a lot of ctrl+c &amp; ctrl+v.</li>
<li><b>9.9.2010 - 24.8.2011</b> <a href="http://www.whitevector.com/">Whitevector</a>, software developer. Worked in a small agile team that developed and maintained a social media monitoring and analysing product. Technologies used included Java (Eclipse IDE), Lucene, PostgreSQL and Ruby on Rails among others.</li>
<li><b>5.6.-31.7.2012</b> <a href="https://www.kuvaverkko.fi">Kuvaverkko</a>, Billing system upgrade project. PHP & MySQL development.</li>
<li><b>8.8.2012 -</b> <a href="http://sc5.fi">SC5</a>, Front & back-end web development.</li>
</ul>
</div>
<div class="block">
<h2><img alt="Skills" src="skills.png"/></h2>
<ul>
<li>I'm good at writing grammatically correct English and Finnish and expressing things clearly. I can communicate basic things in Swedish and Japanese.</li>
<li>I have an eye for aesthetics in web sites and user interfaces. I can create layouts using Photoshop, CSS and HTML. I have played around a little with Qt, wxWidgets and Swing.</li>
<li>I have worked with Java, C++, Eclipse, SVN, Apache, SQL, RoR, Django, PHP, HTML5, JSON, XML and Javascript (JQuery, Mootools).</li>
<li>I have maintained hobby Linux servers since I was 14 and production servers since 2009.</li>
<li>I understand not only code, but also user experience and business aspects. In addition to thinking about <i>what</i> and <i>how</i> you do, it's good to know <i>why</i> you do things.</li>
<li>I'm good at speed typing!<br/>
<a href="http://speedtest.10fastfingers.com"><img src="1_wpm_score_DK.png" alt="Typing Test Score" /></a>
</li>
</ul>
</div>
<div class="block">
<h2><img alt="Old stuff" src="work_samples.png"/></h2>
<ul>
<li><b>2007</b> Saving Princess Adeleine (<a href="adventure.jar">jar</a>/<a
href="adventure.exe">exe</a>), a simple
text-adventure game I made for a programming course. It was chosen as one
of the model solutions for the exercise. You can find a "cheater's
map" of the game world <a href="cheatermap.GIF">here</a>.</li>
<li><b>2008</b> <a href="tetris.html">Tetris</a>, a Java-applet.</li>
<li><b>2009</b> Mökki (<a href="moekki1.1.jar">jar</a>/<a href="samples/Moekki.html">source code</a>). A game where you
place sticks on a grid, and get a point and a new turn for each triangle you
complete. Can be played against the computer or another human player. Made
as a project work for the programming course T-106.1240 Ohjelmoinnin
jatkokurssi T1.</li>
<li><b>2010</b> Inverted Index (<a href="samples/InvertedIndex.html">source code</a>), a standalone Java program made as a work sample for a job application.</li>
<li><b>2012</b> <a href="http://www.flowdock.com">Flowdock</a> plugin for <a href="http://www.redmine.org">Redmine</a> (<a href="samples/RedmineFlowdockPlugin.html">source code</a>). Posts newly created issues and issue status updates from Redmine to Flowdock using the Flowdock API.</li>
<!-- <li><b>2012</b> <a href="https://eurobtc.com">EuroBTC</a> (<a href="samples/eurobtc.html">source code</a>), a service that lets you buy and sell bitcoins for cash in the snail mail. Written in PHP.</li> -->
<li><b>2012</b> <a href="samples/html5tetris.html">Neon Shade Tetris</a> (<a href="http://github.com/mmalmi/neonshadetetris">GitHub</a>), a JavaScript/HTML5 tetris game.</li>
<li><b>2012</b> <a href="gamewheel">Gamewheel</a> (<a href="http://github.com/mmalmi/gamewheel">GitHub</a>), wheel of fortune for choosing the next game at LAN parties.</li>
</ul>
</div>
</div>
</div>
<div id="footer"><img alt="" src="lily-small3.png"/></div>
</body>
</html>
<!--
. . IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
.IMMMMMMMMMMMMMM8I . ... . =MMMM
:MMMMMMMMMZ . 7MMMMZ . 7MD . IMMD .
MMMMM. . . . .~ .M, . MMM .
MMMM, N. .IDMMMO777ZNMMMMMO =MM . M:. NMM.
. ZMMM . . :7NMMDI= . MM IM MMM
MMM IMM77IDMMM, . M8 ..MM M ,N MMM
M8 M M . M ,O . 7. MM
.M8 D ,. ... M 7 MM
MM. 7 = . ~MMMMMN, . 7MM
MMM .. N. MMMMMMMMMMMMMMMO. MMM
.MMM MMMMMMMMM+. ZMMMZ $MMMMMMMMMMM.. MMM
MMMD. . ..ZMMM78MMMMMMMMM MMM. .. DMMMMMMMMMMM8MM MM7 . OMMMM .
MMM MM:. . MMMMMMMMMMMMMMMMM IMM MMMMMMO .DMMMMM.. . . +O MMM.
.MMM ?D OMMMMM .,MMMMM+ MM MMMMMMMM. ?.MM..
MMM M :M. .7M8 MM . MMMN .. =MMMMM. . :MMM :.MMM.
MMM. 8. MMMMMMMMMZ. MM MMMMMMMMMMMM~ M MM. MM$
.MMOM M . .. MMMMMM$ . MMM . MM .MM MM
NMMM M 8M O88I MMMM 7~ . . .:MMMMMM MM MM
MMM $ . MM . MMM~ ~MMMMMMM MMMMM=.7MMMM MM . MM
NM7I M MMM: MMMMM MM MMMMMM . MMMZMMM.MM. 8 MM
MM MM .+MMMM =M M,MMD MMMMMMM $MM DMMMMMM.. ZMM. .MM .8..MMM.
MM? :M MMMMMM .. . . MM . . . MMM .MMMMMMMI=MM MMMM M N MMM
.MM MMMMMMMMM 8MMMM .ZMMMMMM? . MMM. ,MMMMMM . =. MMM
MMM. MMMM MMMMMMM8 . MM . :MMMMMMMMM NMMMMMMMMMMM .MMM.
.MM IMMM= MM ?MMMMMMMMMMMMMMMMMMMMMMM8 . MM . MMMMMMM . MMN 8 MM8
MM 7MMM MM .MM $MMMMM7 .MM.. .MM. MMMMMMMMMMD. MM~ MMM
7M ..=MMMMMMM?. MMI MMM MM . ?MMMMMMMMMM MM .MMI . MMM.
M= MMMMMMMMMMMMMMN~ .8M= MM 7MMMMMMMMMMMM, MM8MMM .,MM
M= MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM8 MMMM . MM.
=M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM+ 8MM MMM$ MM
.8M. MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MM . =MMMM. 7MM.
MM MM.MM MM.ZMMMM7=MMMM . MM ZMM MMMMM MMM.
MM MMZMM ~MM MMM ..~MM MM MMMMMMM . $MM$
MM ~MMM, MMM MM=. MM MM MMMMMMZ .M7 .MM ~MMM
,MM MMMMMMMMD. MM MM MMO~.7MMMMMMMM=.. NM.. MM DMMM
MMI . =MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM~. .M?. ,MM =MMMM
MM. D. . .. . . . .M= . ZMD . MMMM
MM. M M . .8MMMMMMMMMMMMM. MZ MM? . =MMMM
MM. I .MM ... .MM= .MM. ZMMMM
MM ,N . ,+777- -, ... ?MM MMMMM
MM. MMO. .. . . . 7MO . ?MMMM
MMZ .. .==~=. . . MMMM.
MM . . MMMM
MMM .. MMMMMMMMMM
.MMM7 ZMMMMMMMMN:
DMMMMMMMMMMMMMMMMMMMMMMMM? . .
. 7MMMMMMMMMMMMZ. . ..
-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title>siri.us</title>
<link rel="stylesheet" type="text/css" href="per.css">
<link href='http://fonts.googleapis.com/css?family=Lato|Uncial+Antiqua|Slabo+27px' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="icon" type="image/x-icon" href="illusions/purple-cat.ico" />
<script type="text/javascript" src="sorcery/instafeed.min.js"></script>
<script type="text/javascript" src="sorcery/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var $root = $('html, body');
$('a').click(function() {
var href = $.attr(this, 'href');
$root.animate({
scrollTop: $(href).offset().top
}, 500, function () {
window.location.hash = href;
});
return false;
});
});
</script>
</head>
<body>
<header>
<ul>
<li><a href="#cover"><span class="fa fa-star"></span></a></li>
<!--<li><a href="#design">Design</a></li>-->
<li><a href="#photography">Photography</a></li>
<li><a href="#writing">Writing</a></li>
</ul>
</header>
<section id="cover">
<div class="content layer" data-depth="0.00">
<h1>Sirius Business</h1>
<div id="contact">
<ul>
<li><a href="https://twitter.com/marttimalmi"><span class="fa fa-twitter"></span></a></li>
<li><a href="https://www.facebook.com/mmalmi"><span class="fa fa-facebook"></span></a></li>
<li><a href="https://www.linkedin.com/in/marttimalmi"><span class="fa fa-linkedin"></span></a></li>
<li><a href="https://instagram.com/mmalmi"><span class="fa fa-instagram"></span></a></li>
<li><a href="mailto:sirius@iki.fi"><span class="fa fa-at"></span></a></li>
<li><a href="https://github.com/mmalmi"><span class="fa fa-github"></span></a></li>
</ul>
</div>
</div>
</section>
<section id="photography">
<h1>Photography <small>&mdash; AFK screenshots</small></h1>
<div id="instafeed"></div>
</section>
<!--<section id="design">
<h1>Design <small>is the meaning of life</small></h1>
<div></div>
</section> -->
<section id="writing">
<h1>Writing <small>is a art</small></h1>
<div>
<a class="twitter-timeline" href="https://twitter.com/marttimalmi" data-widget-id="592795935392030721">Twiittejä käyttäjältä @marttimalmi</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<p>
<a href="http://speedtest.10fastfingers.com"><img src="illusions/1_wpm_score_DK.png" alt="Typing Test Score"></a>
</p>
<p>
<a href="http://siriusbisnes.blogspot.fi">Blog: Sirius Business (in Finnish)</a>
</p>
</section>
<footer>
<!--<p>
"Man who <span class="spoiler">puts dick in peanut butter</span> is fucking nuts." &mdash; Confucius
</p>-->
<p>
<img src="illusions/construction.gif">
</p>
</footer>
<script type="text/javascript">
var userFeed = new Instafeed({
get: 'user',
userId: 313386739,
accessToken: '313386739.9038401.550f95a9937643cc95fb5ec141e583cb'
});
userFeed.run();
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

BIN
lily.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

BIN
me.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

148
per.css Normal file
View File

@ -0,0 +1,148 @@
html, body {
margin: 0;
padding: 0;
}
body {
font-family: 'Lato';
color: #ffffff;
text-align: center;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
transition: all 0.5s ease;
}
header {
z-index: 1;
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.5);
}
h1 {
margin: 0;
padding: 1em 0;
cursor: default;
}
p {
margin: 3em 0;
}
header ul {
list-style: none;
}
header li {
display: inline-block;
text-transform: uppercase;
margin-right: 40px;
}
section h1 {
font-size: 3em;
text-transform: uppercase;
letter-spacing: 10;
}
h1 small {
color: #aaa;
}
#wrapper {
position: relative;
}
#scroller {
position: absolute;
}
section {
background-color: black;
min-height: 100%;
padding: 0 20px;
padding-bottom: 20px;
}
#cover h1 {
font-size: 2em;
text-transform: uppercase;
letter-spacing: 20;
}
@media (max-width: 767px) {
#cover h1 {
font-size: 1em;
}
}
#cover {
font-size: 3em;
letter-spacing: 20;
//text-shadow: 0 0 1px black;
background: url(illusions/life.jpg) no-repeat center center;
background-size: cover;
height: 100%;
}
#cover .content {
position: relative;
top: 50%;
transform: translateY(-50%);
padding: 20px;
}
#cover ul {
list-style: none;
}
#cover li {
display: inline-block;
}
#writing {
background-color: #ffffff;
color: #333333;
}
#writing a {
color: #333333;
}
#writing a:hover {
color: #999999;
text-decoration: underline;
}
footer {
padding: 150px 20px;
background: #fff url(illusions/london-skyline.svg) repeat-x center 0;
//background-size: cover;
}
a {
color: #ffffff;
text-decoration: none;
}
a:hover {
color: #C262D3;
}
h1 {
}
.spoiler {
transition: background 3s ease;
background: #ffffff;
color: #ffffff;
}
.spoiler:hover {
background: none;
color: inherit;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

2
sorcery/instafeed.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1584
sorcery/iscroll-infinite.js Normal file

File diff suppressed because it is too large Load Diff

944
sorcery/iscroll-lite.js Normal file
View File

@ -0,0 +1,944 @@
/*! iScroll v5.1.3 ~ (c) 2008-2014 Matteo Spinelli ~ http://cubiq.org/license */
(function (window, document, Math) {
var rAF = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) { window.setTimeout(callback, 1000 / 60); };
var utils = (function () {
var me = {};
var _elementStyle = document.createElement('div').style;
var _vendor = (function () {
var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
transform,
i = 0,
l = vendors.length;
for ( ; i < l; i++ ) {
transform = vendors[i] + 'ransform';
if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
}
return false;
})();
function _prefixStyle (style) {
if ( _vendor === false ) return false;
if ( _vendor === '' ) return style;
return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
}
me.getTime = Date.now || function getTime () { return new Date().getTime(); };
me.extend = function (target, obj) {
for ( var i in obj ) {
target[i] = obj[i];
}
};
me.addEvent = function (el, type, fn, capture) {
el.addEventListener(type, fn, !!capture);
};
me.removeEvent = function (el, type, fn, capture) {
el.removeEventListener(type, fn, !!capture);
};
me.prefixPointerEvent = function (pointerEvent) {
return window.MSPointerEvent ?
'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10):
pointerEvent;
};
me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
var distance = current - start,
speed = Math.abs(distance) / time,
destination,
duration;
deceleration = deceleration === undefined ? 0.0006 : deceleration;
destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
duration = speed / deceleration;
if ( destination < lowerMargin ) {
destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
distance = Math.abs(destination - current);
duration = distance / speed;
} else if ( destination > 0 ) {
destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
distance = Math.abs(current) + destination;
duration = distance / speed;
}
return {
destination: Math.round(destination),
duration: duration
};
};
var _transform = _prefixStyle('transform');
me.extend(me, {
hasTransform: _transform !== false,
hasPerspective: _prefixStyle('perspective') in _elementStyle,
hasTouch: 'ontouchstart' in window,
hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed
hasTransition: _prefixStyle('transition') in _elementStyle
});
// This should find all Android browsers lower than build 535.19 (both stock browser and webview)
me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion));
me.extend(me.style = {}, {
transform: _transform,
transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
transitionDuration: _prefixStyle('transitionDuration'),
transitionDelay: _prefixStyle('transitionDelay'),
transformOrigin: _prefixStyle('transformOrigin')
});
me.hasClass = function (e, c) {
var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
return re.test(e.className);
};
me.addClass = function (e, c) {
if ( me.hasClass(e, c) ) {
return;
}
var newclass = e.className.split(' ');
newclass.push(c);
e.className = newclass.join(' ');
};
me.removeClass = function (e, c) {
if ( !me.hasClass(e, c) ) {
return;
}
var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
e.className = e.className.replace(re, ' ');
};
me.offset = function (el) {
var left = -el.offsetLeft,
top = -el.offsetTop;
// jshint -W084
while (el = el.offsetParent) {
left -= el.offsetLeft;
top -= el.offsetTop;
}
// jshint +W084
return {
left: left,
top: top
};
};
me.preventDefaultException = function (el, exceptions) {
for ( var i in exceptions ) {
if ( exceptions[i].test(el[i]) ) {
return true;
}
}
return false;
};
me.extend(me.eventType = {}, {
touchstart: 1,
touchmove: 1,
touchend: 1,
mousedown: 2,
mousemove: 2,
mouseup: 2,
pointerdown: 3,
pointermove: 3,
pointerup: 3,
MSPointerDown: 3,
MSPointerMove: 3,
MSPointerUp: 3
});
me.extend(me.ease = {}, {
quadratic: {
style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
fn: function (k) {
return k * ( 2 - k );
}
},
circular: {
style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
fn: function (k) {
return Math.sqrt( 1 - ( --k * k ) );
}
},
back: {
style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
fn: function (k) {
var b = 4;
return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
}
},
bounce: {
style: '',
fn: function (k) {
if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
return 7.5625 * k * k;
} else if ( k < ( 2 / 2.75 ) ) {
return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
} else if ( k < ( 2.5 / 2.75 ) ) {
return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
} else {
return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
}
}
},
elastic: {
style: '',
fn: function (k) {
var f = 0.22,
e = 0.4;
if ( k === 0 ) { return 0; }
if ( k == 1 ) { return 1; }
return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
}
}
});
me.tap = function (e, eventName) {
var ev = document.createEvent('Event');
ev.initEvent(eventName, true, true);
ev.pageX = e.pageX;
ev.pageY = e.pageY;
e.target.dispatchEvent(ev);
};
me.click = function (e) {
var target = e.target,
ev;
if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
ev = document.createEvent('MouseEvents');
ev.initMouseEvent('click', true, true, e.view, 1,
target.screenX, target.screenY, target.clientX, target.clientY,
e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
0, null);
ev._constructed = true;
target.dispatchEvent(ev);
}
};
return me;
})();
function IScroll (el, options) {
this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
this.scroller = this.wrapper.children[0];
this.scrollerStyle = this.scroller.style; // cache style for better performance
this.options = {
// INSERT POINT: OPTIONS
startX: 0,
startY: 0,
scrollY: true,
directionLockThreshold: 5,
momentum: true,
bounce: true,
bounceTime: 600,
bounceEasing: '',
preventDefault: true,
preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
HWCompositing: true,
useTransition: true,
useTransform: true
};
for ( var i in options ) {
this.options[i] = options[i];
}
// Normalize options
this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
this.options.useTransition = utils.hasTransition && this.options.useTransition;
this.options.useTransform = utils.hasTransform && this.options.useTransform;
this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
// If you want eventPassthrough I have to lock one of the axes
this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
// With eventPassthrough we also need lockDirection mechanism
this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
if ( this.options.tap === true ) {
this.options.tap = 'tap';
}
// INSERT POINT: NORMALIZATION
// Some defaults
this.x = 0;
this.y = 0;
this.directionX = 0;
this.directionY = 0;
this._events = {};
// INSERT POINT: DEFAULTS
this._init();
this.refresh();
this.scrollTo(this.options.startX, this.options.startY);
this.enable();
}
IScroll.prototype = {
version: '5.1.3',
_init: function () {
this._initEvents();
// INSERT POINT: _init
},
destroy: function () {
this._initEvents(true);
this._execEvent('destroy');
},
_transitionEnd: function (e) {
if ( e.target != this.scroller || !this.isInTransition ) {
return;
}
this._transitionTime();
if ( !this.resetPosition(this.options.bounceTime) ) {
this.isInTransition = false;
this._execEvent('scrollEnd');
}
},
_start: function (e) {
// React to left mouse button only
if ( utils.eventType[e.type] != 1 ) {
if ( e.button !== 0 ) {
return;
}
}
if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
return;
}
if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
e.preventDefault();
}
var point = e.touches ? e.touches[0] : e,
pos;
this.initiated = utils.eventType[e.type];
this.moved = false;
this.distX = 0;
this.distY = 0;
this.directionX = 0;
this.directionY = 0;
this.directionLocked = 0;
this._transitionTime();
this.startTime = utils.getTime();
if ( this.options.useTransition && this.isInTransition ) {
this.isInTransition = false;
pos = this.getComputedPosition();
this._translate(Math.round(pos.x), Math.round(pos.y));
this._execEvent('scrollEnd');
} else if ( !this.options.useTransition && this.isAnimating ) {
this.isAnimating = false;
this._execEvent('scrollEnd');
}
this.startX = this.x;
this.startY = this.y;
this.absStartX = this.x;
this.absStartY = this.y;
this.pointX = point.pageX;
this.pointY = point.pageY;
this._execEvent('beforeScrollStart');
},
_move: function (e) {
if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
return;
}
if ( this.options.preventDefault ) { // increases performance on Android? TODO: check!
e.preventDefault();
}
var point = e.touches ? e.touches[0] : e,
deltaX = point.pageX - this.pointX,
deltaY = point.pageY - this.pointY,
timestamp = utils.getTime(),
newX, newY,
absDistX, absDistY;
this.pointX = point.pageX;
this.pointY = point.pageY;
this.distX += deltaX;
this.distY += deltaY;
absDistX = Math.abs(this.distX);
absDistY = Math.abs(this.distY);
// We need to move at least 10 pixels for the scrolling to initiate
if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
return;
}
// If you are scrolling in one direction lock the other
if ( !this.directionLocked && !this.options.freeScroll ) {
if ( absDistX > absDistY + this.options.directionLockThreshold ) {
this.directionLocked = 'h'; // lock horizontally
} else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
this.directionLocked = 'v'; // lock vertically
} else {
this.directionLocked = 'n'; // no lock
}
}
if ( this.directionLocked == 'h' ) {
if ( this.options.eventPassthrough == 'vertical' ) {
e.preventDefault();
} else if ( this.options.eventPassthrough == 'horizontal' ) {
this.initiated = false;
return;
}
deltaY = 0;
} else if ( this.directionLocked == 'v' ) {
if ( this.options.eventPassthrough == 'horizontal' ) {
e.preventDefault();
} else if ( this.options.eventPassthrough == 'vertical' ) {
this.initiated = false;
return;
}
deltaX = 0;
}
deltaX = this.hasHorizontalScroll ? deltaX : 0;
deltaY = this.hasVerticalScroll ? deltaY : 0;
newX = this.x + deltaX;
newY = this.y + deltaY;
// Slow down if outside of the boundaries
if ( newX > 0 || newX < this.maxScrollX ) {
newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
}
if ( newY > 0 || newY < this.maxScrollY ) {
newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
}
this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
if ( !this.moved ) {
this._execEvent('scrollStart');
}
this.moved = true;
this._translate(newX, newY);
/* REPLACE START: _move */
if ( timestamp - this.startTime > 300 ) {
this.startTime = timestamp;
this.startX = this.x;
this.startY = this.y;
}
/* REPLACE END: _move */
},
_end: function (e) {
if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
return;
}
if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
e.preventDefault();
}
var point = e.changedTouches ? e.changedTouches[0] : e,
momentumX,
momentumY,
duration = utils.getTime() - this.startTime,
newX = Math.round(this.x),
newY = Math.round(this.y),
distanceX = Math.abs(newX - this.startX),
distanceY = Math.abs(newY - this.startY),
time = 0,
easing = '';
this.isInTransition = 0;
this.initiated = 0;
this.endTime = utils.getTime();
// reset if we are outside of the boundaries
if ( this.resetPosition(this.options.bounceTime) ) {
return;
}
this.scrollTo(newX, newY); // ensures that the last position is rounded
// we scrolled less than 10 pixels
if ( !this.moved ) {
if ( this.options.tap ) {
utils.tap(e, this.options.tap);
}
if ( this.options.click ) {
utils.click(e);
}
this._execEvent('scrollCancel');
return;
}
if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
this._execEvent('flick');
return;
}
// start momentum animation if needed
if ( this.options.momentum && duration < 300 ) {
momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 };
momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 };
newX = momentumX.destination;
newY = momentumY.destination;
time = Math.max(momentumX.duration, momentumY.duration);
this.isInTransition = 1;
}
// INSERT POINT: _end
if ( newX != this.x || newY != this.y ) {
// change easing function when scroller goes out of the boundaries
if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
easing = utils.ease.quadratic;
}
this.scrollTo(newX, newY, time, easing);
return;
}
this._execEvent('scrollEnd');
},
_resize: function () {
var that = this;
clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(function () {
that.refresh();
}, this.options.resizePolling);
},
resetPosition: function (time) {
var x = this.x,
y = this.y;
time = time || 0;
if ( !this.hasHorizontalScroll || this.x > 0 ) {
x = 0;
} else if ( this.x < this.maxScrollX ) {
x = this.maxScrollX;
}
if ( !this.hasVerticalScroll || this.y > 0 ) {
y = 0;
} else if ( this.y < this.maxScrollY ) {
y = this.maxScrollY;
}
if ( x == this.x && y == this.y ) {
return false;
}
this.scrollTo(x, y, time, this.options.bounceEasing);
return true;
},
disable: function () {
this.enabled = false;
},
enable: function () {
this.enabled = true;
},
refresh: function () {
var rf = this.wrapper.offsetHeight; // Force reflow
this.wrapperWidth = this.wrapper.clientWidth;
this.wrapperHeight = this.wrapper.clientHeight;
/* REPLACE START: refresh */
this.scrollerWidth = this.scroller.offsetWidth;
this.scrollerHeight = this.scroller.offsetHeight;
this.maxScrollX = this.wrapperWidth - this.scrollerWidth;
this.maxScrollY = this.wrapperHeight - this.scrollerHeight;
/* REPLACE END: refresh */
this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
if ( !this.hasHorizontalScroll ) {
this.maxScrollX = 0;
this.scrollerWidth = this.wrapperWidth;
}
if ( !this.hasVerticalScroll ) {
this.maxScrollY = 0;
this.scrollerHeight = this.wrapperHeight;
}
this.endTime = 0;
this.directionX = 0;
this.directionY = 0;
this.wrapperOffset = utils.offset(this.wrapper);
this._execEvent('refresh');
this.resetPosition();
// INSERT POINT: _refresh
},
on: function (type, fn) {
if ( !this._events[type] ) {
this._events[type] = [];
}
this._events[type].push(fn);
},
off: function (type, fn) {
if ( !this._events[type] ) {
return;
}
var index = this._events[type].indexOf(fn);
if ( index > -1 ) {
this._events[type].splice(index, 1);
}
},
_execEvent: function (type) {
if ( !this._events[type] ) {
return;
}
var i = 0,
l = this._events[type].length;
if ( !l ) {
return;
}
for ( ; i < l; i++ ) {
this._events[type][i].apply(this, [].slice.call(arguments, 1));
}
},
scrollBy: function (x, y, time, easing) {
x = this.x + x;
y = this.y + y;
time = time || 0;
this.scrollTo(x, y, time, easing);
},
scrollTo: function (x, y, time, easing) {
easing = easing || utils.ease.circular;
this.isInTransition = this.options.useTransition && time > 0;
if ( !time || (this.options.useTransition && easing.style) ) {
this._transitionTimingFunction(easing.style);
this._transitionTime(time);
this._translate(x, y);
} else {
this._animate(x, y, time, easing.fn);
}
},
scrollToElement: function (el, time, offsetX, offsetY, easing) {
el = el.nodeType ? el : this.scroller.querySelector(el);
if ( !el ) {
return;
}
var pos = utils.offset(el);
pos.left -= this.wrapperOffset.left;
pos.top -= this.wrapperOffset.top;
// if offsetX/Y are true we center the element to the screen
if ( offsetX === true ) {
offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2);
}
if ( offsetY === true ) {
offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2);
}
pos.left -= offsetX || 0;
pos.top -= offsetY || 0;
pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top;
time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
this.scrollTo(pos.left, pos.top, time, easing);
},
_transitionTime: function (time) {
time = time || 0;
this.scrollerStyle[utils.style.transitionDuration] = time + 'ms';
if ( !time && utils.isBadAndroid ) {
this.scrollerStyle[utils.style.transitionDuration] = '0.001s';
}
// INSERT POINT: _transitionTime
},
_transitionTimingFunction: function (easing) {
this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
// INSERT POINT: _transitionTimingFunction
},
_translate: function (x, y) {
if ( this.options.useTransform ) {
/* REPLACE START: _translate */
this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
/* REPLACE END: _translate */
} else {
x = Math.round(x);
y = Math.round(y);
this.scrollerStyle.left = x + 'px';
this.scrollerStyle.top = y + 'px';
}
this.x = x;
this.y = y;
// INSERT POINT: _translate
},
_initEvents: function (remove) {
var eventType = remove ? utils.removeEvent : utils.addEvent,
target = this.options.bindToWrapper ? this.wrapper : window;
eventType(window, 'orientationchange', this);
eventType(window, 'resize', this);
if ( this.options.click ) {
eventType(this.wrapper, 'click', this, true);
}
if ( !this.options.disableMouse ) {
eventType(this.wrapper, 'mousedown', this);
eventType(target, 'mousemove', this);
eventType(target, 'mousecancel', this);
eventType(target, 'mouseup', this);
}
if ( utils.hasPointer && !this.options.disablePointer ) {
eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
eventType(target, utils.prefixPointerEvent('pointermove'), this);
eventType(target, utils.prefixPointerEvent('pointercancel'), this);
eventType(target, utils.prefixPointerEvent('pointerup'), this);
}
if ( utils.hasTouch && !this.options.disableTouch ) {
eventType(this.wrapper, 'touchstart', this);
eventType(target, 'touchmove', this);
eventType(target, 'touchcancel', this);
eventType(target, 'touchend', this);
}
eventType(this.scroller, 'transitionend', this);
eventType(this.scroller, 'webkitTransitionEnd', this);
eventType(this.scroller, 'oTransitionEnd', this);
eventType(this.scroller, 'MSTransitionEnd', this);
},
getComputedPosition: function () {
var matrix = window.getComputedStyle(this.scroller, null),
x, y;
if ( this.options.useTransform ) {
matrix = matrix[utils.style.transform].split(')')[0].split(', ');
x = +(matrix[12] || matrix[4]);
y = +(matrix[13] || matrix[5]);
} else {
x = +matrix.left.replace(/[^-\d.]/g, '');
y = +matrix.top.replace(/[^-\d.]/g, '');
}
return { x: x, y: y };
},
_animate: function (destX, destY, duration, easingFn) {
var that = this,
startX = this.x,
startY = this.y,
startTime = utils.getTime(),
destTime = startTime + duration;
function step () {
var now = utils.getTime(),
newX, newY,
easing;
if ( now >= destTime ) {
that.isAnimating = false;
that._translate(destX, destY);
if ( !that.resetPosition(that.options.bounceTime) ) {
that._execEvent('scrollEnd');
}
return;
}
now = ( now - startTime ) / duration;
easing = easingFn(now);
newX = ( destX - startX ) * easing + startX;
newY = ( destY - startY ) * easing + startY;
that._translate(newX, newY);
if ( that.isAnimating ) {
rAF(step);
}
}
this.isAnimating = true;
step();
},
handleEvent: function (e) {
switch ( e.type ) {
case 'touchstart':
case 'pointerdown':
case 'MSPointerDown':
case 'mousedown':
this._start(e);
break;
case 'touchmove':
case 'pointermove':
case 'MSPointerMove':
case 'mousemove':
this._move(e);
break;
case 'touchend':
case 'pointerup':
case 'MSPointerUp':
case 'mouseup':
case 'touchcancel':
case 'pointercancel':
case 'MSPointerCancel':
case 'mousecancel':
this._end(e);
break;
case 'orientationchange':
case 'resize':
this._resize();
break;
case 'transitionend':
case 'webkitTransitionEnd':
case 'oTransitionEnd':
case 'MSTransitionEnd':
this._transitionEnd(e);
break;
case 'wheel':
case 'DOMMouseScroll':
case 'mousewheel':
this._wheel(e);
break;
case 'keydown':
this._key(e);
break;
case 'click':
if ( !e._constructed ) {
e.preventDefault();
e.stopPropagation();
}
break;
}
}
};
IScroll.utils = utils;
if ( typeof module != 'undefined' && module.exports ) {
module.exports = IScroll;
} else {
window.IScroll = IScroll;
}
})(window, document, Math);

2038
sorcery/iscroll-probe.js Normal file

File diff suppressed because it is too large Load Diff

2195
sorcery/iscroll-zoom.js Normal file

File diff suppressed because it is too large Load Diff

2011
sorcery/iscroll.js Normal file

File diff suppressed because it is too large Load Diff

4
sorcery/jquery-1.11.2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

564
sorcery/jquery.parallax.js Normal file
View File

@ -0,0 +1,564 @@
//============================================================
//
// The MIT License
//
// Copyright (C) 2014 Matthew Wagerfield - @wagerfield
//
// 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.
//
//============================================================
/**
* jQuery || Zepto Parallax Plugin
* @author Matthew Wagerfield - @wagerfield
* @description Creates a parallax effect between an array of layers,
* driving the motion from the gyroscope output of a smartdevice.
* If no gyroscope is available, the cursor position is used.
*/
;(function($, window, document, undefined) {
// Strict Mode
'use strict';
// Constants
var NAME = 'parallax';
var MAGIC_NUMBER = 30;
var DEFAULTS = {
relativeInput: false,
clipRelativeInput: false,
calibrationThreshold: 100,
calibrationDelay: 500,
supportDelay: 500,
calibrateX: false,
calibrateY: true,
invertX: true,
invertY: true,
limitX: false,
limitY: false,
scalarX: 10.0,
scalarY: 10.0,
frictionX: 0.1,
frictionY: 0.1,
originX: 0.5,
originY: 0.5
};
function Plugin(element, options) {
// DOM Context
this.element = element;
// Selections
this.$context = $(element).data('api', this);
this.$layers = this.$context.find('.layer');
// Data Extraction
var data = {
calibrateX: this.$context.data('calibrate-x') || null,
calibrateY: this.$context.data('calibrate-y') || null,
invertX: this.$context.data('invert-x') || null,
invertY: this.$context.data('invert-y') || null,
limitX: parseFloat(this.$context.data('limit-x')) || null,
limitY: parseFloat(this.$context.data('limit-y')) || null,
scalarX: parseFloat(this.$context.data('scalar-x')) || null,
scalarY: parseFloat(this.$context.data('scalar-y')) || null,
frictionX: parseFloat(this.$context.data('friction-x')) || null,
frictionY: parseFloat(this.$context.data('friction-y')) || null,
originX: parseFloat(this.$context.data('origin-x')) || null,
originY: parseFloat(this.$context.data('origin-y')) || null
};
// Delete Null Data Values
for (var key in data) {
if (data[key] === null) delete data[key];
}
// Compose Settings Object
$.extend(this, DEFAULTS, options, data);
// States
this.calibrationTimer = null;
this.calibrationFlag = true;
this.enabled = false;
this.depths = [];
this.raf = null;
// Element Bounds
this.bounds = null;
this.ex = 0;
this.ey = 0;
this.ew = 0;
this.eh = 0;
// Element Center
this.ecx = 0;
this.ecy = 0;
// Element Range
this.erx = 0;
this.ery = 0;
// Calibration
this.cx = 0;
this.cy = 0;
// Input
this.ix = 0;
this.iy = 0;
// Motion
this.mx = 0;
this.my = 0;
// Velocity
this.vx = 0;
this.vy = 0;
// Callbacks
this.onMouseMove = this.onMouseMove.bind(this);
this.onDeviceOrientation = this.onDeviceOrientation.bind(this);
this.onOrientationTimer = this.onOrientationTimer.bind(this);
this.onCalibrationTimer = this.onCalibrationTimer.bind(this);
this.onAnimationFrame = this.onAnimationFrame.bind(this);
this.onWindowResize = this.onWindowResize.bind(this);
// Initialise
this.initialise();
}
Plugin.prototype.transformSupport = function(value) {
var element = document.createElement('div');
var propertySupport = false;
var propertyValue = null;
var featureSupport = false;
var cssProperty = null;
var jsProperty = null;
for (var i = 0, l = this.vendors.length; i < l; i++) {
if (this.vendors[i] !== null) {
cssProperty = this.vendors[i][0] + 'transform';
jsProperty = this.vendors[i][1] + 'Transform';
} else {
cssProperty = 'transform';
jsProperty = 'transform';
}
if (element.style[jsProperty] !== undefined) {
propertySupport = true;
break;
}
}
switch(value) {
case '2D':
featureSupport = propertySupport;
break;
case '3D':
if (propertySupport) {
var body = document.body || document.createElement('body');
var documentElement = document.documentElement;
var documentOverflow = documentElement.style.overflow;
if (!document.body) {
documentElement.style.overflow = 'hidden';
documentElement.appendChild(body);
body.style.overflow = 'hidden';
body.style.background = '';
}
body.appendChild(element);
element.style[jsProperty] = 'translate3d(1px,1px,1px)';
propertyValue = window.getComputedStyle(element).getPropertyValue(cssProperty);
featureSupport = propertyValue !== undefined && propertyValue.length > 0 && propertyValue !== "none";
documentElement.style.overflow = documentOverflow;
body.removeChild(element);
}
break;
}
return featureSupport;
};
Plugin.prototype.ww = null;
Plugin.prototype.wh = null;
Plugin.prototype.wcx = null;
Plugin.prototype.wcy = null;
Plugin.prototype.wrx = null;
Plugin.prototype.wry = null;
Plugin.prototype.portrait = null;
Plugin.prototype.desktop = !navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|mobi|tablet|opera mini|nexus 7)/i);
Plugin.prototype.vendors = [null,['-webkit-','webkit'],['-moz-','Moz'],['-o-','O'],['-ms-','ms']];
Plugin.prototype.motionSupport = !!window.DeviceMotionEvent;
Plugin.prototype.orientationSupport = !!window.DeviceOrientationEvent;
Plugin.prototype.orientationStatus = 0;
Plugin.prototype.transform2DSupport = Plugin.prototype.transformSupport('2D');
Plugin.prototype.transform3DSupport = Plugin.prototype.transformSupport('3D');
Plugin.prototype.propertyCache = {};
Plugin.prototype.initialise = function() {
// Configure Styles
if (this.$context.css('position') === 'static') {
this.$context.css({
position:'relative'
});
}
// Hardware Accelerate Context
this.accelerate(this.$context);
// Setup
this.updateLayers();
this.updateDimensions();
this.enable();
this.queueCalibration(this.calibrationDelay);
};
Plugin.prototype.updateLayers = function() {
// Cache Layer Elements
this.$layers = this.$context.find('.layer');
this.depths = [];
// Configure Layer Styles
this.$layers.css({
position:'absolute',
display:'block',
left: 0,
top: 0
});
this.$layers.first().css({
position:'relative'
});
// Hardware Accelerate Layers
this.accelerate(this.$layers);
// Cache Depths
this.$layers.each($.proxy(function(index, element) {
this.depths.push($(element).data('depth') || 0);
}, this));
};
Plugin.prototype.updateDimensions = function() {
this.ww = window.innerWidth;
this.wh = window.innerHeight;
this.wcx = this.ww * this.originX;
this.wcy = this.wh * this.originY;
this.wrx = Math.max(this.wcx, this.ww - this.wcx);
this.wry = Math.max(this.wcy, this.wh - this.wcy);
};
Plugin.prototype.updateBounds = function() {
this.bounds = this.element.getBoundingClientRect();
this.ex = this.bounds.left;
this.ey = this.bounds.top;
this.ew = this.bounds.width;
this.eh = this.bounds.height;
this.ecx = this.ew * this.originX;
this.ecy = this.eh * this.originY;
this.erx = Math.max(this.ecx, this.ew - this.ecx);
this.ery = Math.max(this.ecy, this.eh - this.ecy);
};
Plugin.prototype.queueCalibration = function(delay) {
clearTimeout(this.calibrationTimer);
this.calibrationTimer = setTimeout(this.onCalibrationTimer, delay);
};
Plugin.prototype.enable = function() {
if (!this.enabled) {
this.enabled = true;
if (this.orientationSupport) {
this.portrait = null;
window.addEventListener('deviceorientation', this.onDeviceOrientation);
setTimeout(this.onOrientationTimer, this.supportDelay);
} else {
this.cx = 0;
this.cy = 0;
this.portrait = false;
window.addEventListener('mousemove', this.onMouseMove);
}
window.addEventListener('resize', this.onWindowResize);
this.raf = requestAnimationFrame(this.onAnimationFrame);
}
};
Plugin.prototype.disable = function() {
if (this.enabled) {
this.enabled = false;
if (this.orientationSupport) {
window.removeEventListener('deviceorientation', this.onDeviceOrientation);
} else {
window.removeEventListener('mousemove', this.onMouseMove);
}
window.removeEventListener('resize', this.onWindowResize);
cancelAnimationFrame(this.raf);
}
};
Plugin.prototype.calibrate = function(x, y) {
this.calibrateX = x === undefined ? this.calibrateX : x;
this.calibrateY = y === undefined ? this.calibrateY : y;
};
Plugin.prototype.invert = function(x, y) {
this.invertX = x === undefined ? this.invertX : x;
this.invertY = y === undefined ? this.invertY : y;
};
Plugin.prototype.friction = function(x, y) {
this.frictionX = x === undefined ? this.frictionX : x;
this.frictionY = y === undefined ? this.frictionY : y;
};
Plugin.prototype.scalar = function(x, y) {
this.scalarX = x === undefined ? this.scalarX : x;
this.scalarY = y === undefined ? this.scalarY : y;
};
Plugin.prototype.limit = function(x, y) {
this.limitX = x === undefined ? this.limitX : x;
this.limitY = y === undefined ? this.limitY : y;
};
Plugin.prototype.origin = function(x, y) {
this.originX = x === undefined ? this.originX : x;
this.originY = y === undefined ? this.originY : y;
};
Plugin.prototype.clamp = function(value, min, max) {
value = Math.max(value, min);
value = Math.min(value, max);
return value;
};
Plugin.prototype.css = function(element, property, value) {
var jsProperty = this.propertyCache[property];
if (!jsProperty) {
for (var i = 0, l = this.vendors.length; i < l; i++) {
if (this.vendors[i] !== null) {
jsProperty = $.camelCase(this.vendors[i][1] + '-' + property);
} else {
jsProperty = property;
}
if (element.style[jsProperty] !== undefined) {
this.propertyCache[property] = jsProperty;
break;
}
}
}
element.style[jsProperty] = value;
};
Plugin.prototype.accelerate = function($element) {
for (var i = 0, l = $element.length; i < l; i++) {
var element = $element[i];
this.css(element, 'transform', 'translate3d(0,0,0)');
this.css(element, 'transform-style', 'preserve-3d');
this.css(element, 'backface-visibility', 'hidden');
}
};
Plugin.prototype.setPosition = function(element, x, y) {
x += 'px';
y += 'px';
if (this.transform3DSupport) {
this.css(element, 'transform', 'translate3d('+x+','+y+',0)');
} else if (this.transform2DSupport) {
this.css(element, 'transform', 'translate('+x+','+y+')');
} else {
element.style.left = x;
element.style.top = y;
}
};
Plugin.prototype.onOrientationTimer = function(event) {
if (this.orientationSupport && this.orientationStatus === 0) {
this.disable();
this.orientationSupport = false;
this.enable();
}
};
Plugin.prototype.onCalibrationTimer = function(event) {
this.calibrationFlag = true;
};
Plugin.prototype.onWindowResize = function(event) {
this.updateDimensions();
};
Plugin.prototype.onAnimationFrame = function() {
this.updateBounds();
var dx = this.ix - this.cx;
var dy = this.iy - this.cy;
if ((Math.abs(dx) > this.calibrationThreshold) || (Math.abs(dy) > this.calibrationThreshold)) {
this.queueCalibration(0);
}
if (this.portrait) {
this.mx = this.calibrateX ? dy : this.iy;
this.my = this.calibrateY ? dx : this.ix;
} else {
this.mx = this.calibrateX ? dx : this.ix;
this.my = this.calibrateY ? dy : this.iy;
}
this.mx *= this.ew * (this.scalarX / 100);
this.my *= this.eh * (this.scalarY / 100);
if (!isNaN(parseFloat(this.limitX))) {
this.mx = this.clamp(this.mx, -this.limitX, this.limitX);
}
if (!isNaN(parseFloat(this.limitY))) {
this.my = this.clamp(this.my, -this.limitY, this.limitY);
}
this.vx += (this.mx - this.vx) * this.frictionX;
this.vy += (this.my - this.vy) * this.frictionY;
for (var i = 0, l = this.$layers.length; i < l; i++) {
var depth = this.depths[i];
var layer = this.$layers[i];
var xOffset = this.vx * depth * (this.invertX ? -1 : 1);
var yOffset = this.vy * depth * (this.invertY ? -1 : 1);
this.setPosition(layer, xOffset, yOffset);
}
this.raf = requestAnimationFrame(this.onAnimationFrame);
};
Plugin.prototype.onDeviceOrientation = function(event) {
// Validate environment and event properties.
if (!this.desktop && event.beta !== null && event.gamma !== null) {
// Set orientation status.
this.orientationStatus = 1;
// Extract Rotation
var x = (event.beta || 0) / MAGIC_NUMBER; // -90 :: 90
var y = (event.gamma || 0) / MAGIC_NUMBER; // -180 :: 180
// Detect Orientation Change
var portrait = window.innerHeight > window.innerWidth;
if (this.portrait !== portrait) {
this.portrait = portrait;
this.calibrationFlag = true;
}
// Set Calibration
if (this.calibrationFlag) {
this.calibrationFlag = false;
this.cx = x;
this.cy = y;
}
// Set Input
this.ix = x;
this.iy = y;
}
};
Plugin.prototype.onMouseMove = function(event) {
// Cache mouse coordinates.
var clientX = event.clientX;
var clientY = event.clientY;
// Calculate Mouse Input
if (!this.orientationSupport && this.relativeInput) {
// Clip mouse coordinates inside element bounds.
if (this.clipRelativeInput) {
clientX = Math.max(clientX, this.ex);
clientX = Math.min(clientX, this.ex + this.ew);
clientY = Math.max(clientY, this.ey);
clientY = Math.min(clientY, this.ey + this.eh);
}
// Calculate input relative to the element.
this.ix = (clientX - this.ex - this.ecx) / this.erx;
this.iy = (clientY - this.ey - this.ecy) / this.ery;
} else {
// Calculate input relative to the window.
this.ix = (clientX - this.wcx) / this.wrx;
this.iy = (clientY - this.wcy) / this.wry;
}
};
var API = {
enable: Plugin.prototype.enable,
disable: Plugin.prototype.disable,
updateLayers: Plugin.prototype.updateLayers,
calibrate: Plugin.prototype.calibrate,
friction: Plugin.prototype.friction,
invert: Plugin.prototype.invert,
scalar: Plugin.prototype.scalar,
limit: Plugin.prototype.limit,
origin: Plugin.prototype.origin
};
$.fn[NAME] = function (value) {
var args = arguments;
return this.each(function () {
var $this = $(this);
var plugin = $this.data(NAME);
if (!plugin) {
plugin = new Plugin(this, value);
$this.data(NAME, plugin);
}
if (API[value]) {
plugin[value].apply(plugin, Array.prototype.slice.call(args, 1));
}
});
};
})(window.jQuery || window.Zepto, window, document);
/**
* Request Animation Frame Polyfill.
* @author Tino Zijdel
* @author Paul Irish
* @see https://gist.github.com/paulirish/1579671
*/
;(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', '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);
};
}
}());

1
sorcery/jquery.parallax.min.js vendored Normal file

File diff suppressed because one or more lines are too long

561
sorcery/parallax.js Normal file
View File

@ -0,0 +1,561 @@
//============================================================
//
// The MIT License
//
// Copyright (C) 2014 Matthew Wagerfield - @wagerfield
//
// 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.
//
//============================================================
/**
* Parallax.js
* @author Matthew Wagerfield - @wagerfield
* @description Creates a parallax effect between an array of layers,
* driving the motion from the gyroscope output of a smartdevice.
* If no gyroscope is available, the cursor position is used.
*/
;(function(window, document, undefined) {
// Strict Mode
'use strict';
// Constants
var NAME = 'Parallax';
var MAGIC_NUMBER = 30;
var DEFAULTS = {
relativeInput: false,
clipRelativeInput: false,
calibrationThreshold: 100,
calibrationDelay: 500,
supportDelay: 500,
calibrateX: false,
calibrateY: true,
invertX: true,
invertY: true,
limitX: false,
limitY: false,
scalarX: 10.0,
scalarY: 10.0,
frictionX: 0.1,
frictionY: 0.1,
originX: 0.5,
originY: 0.5
};
function Parallax(element, options) {
// DOM Context
this.element = element;
this.layers = element.getElementsByClassName('layer');
// Data Extraction
var data = {
calibrateX: this.data(this.element, 'calibrate-x'),
calibrateY: this.data(this.element, 'calibrate-y'),
invertX: this.data(this.element, 'invert-x'),
invertY: this.data(this.element, 'invert-y'),
limitX: this.data(this.element, 'limit-x'),
limitY: this.data(this.element, 'limit-y'),
scalarX: this.data(this.element, 'scalar-x'),
scalarY: this.data(this.element, 'scalar-y'),
frictionX: this.data(this.element, 'friction-x'),
frictionY: this.data(this.element, 'friction-y'),
originX: this.data(this.element, 'origin-x'),
originY: this.data(this.element, 'origin-y')
};
// Delete Null Data Values
for (var key in data) {
if (data[key] === null) delete data[key];
}
// Compose Settings Object
this.extend(this, DEFAULTS, options, data);
// States
this.calibrationTimer = null;
this.calibrationFlag = true;
this.enabled = false;
this.depths = [];
this.raf = null;
// Element Bounds
this.bounds = null;
this.ex = 0;
this.ey = 0;
this.ew = 0;
this.eh = 0;
// Element Center
this.ecx = 0;
this.ecy = 0;
// Element Range
this.erx = 0;
this.ery = 0;
// Calibration
this.cx = 0;
this.cy = 0;
// Input
this.ix = 0;
this.iy = 0;
// Motion
this.mx = 0;
this.my = 0;
// Velocity
this.vx = 0;
this.vy = 0;
// Callbacks
this.onMouseMove = this.onMouseMove.bind(this);
this.onDeviceOrientation = this.onDeviceOrientation.bind(this);
this.onOrientationTimer = this.onOrientationTimer.bind(this);
this.onCalibrationTimer = this.onCalibrationTimer.bind(this);
this.onAnimationFrame = this.onAnimationFrame.bind(this);
this.onWindowResize = this.onWindowResize.bind(this);
// Initialise
this.initialise();
}
Parallax.prototype.extend = function() {
if (arguments.length > 1) {
var master = arguments[0];
for (var i = 1, l = arguments.length; i < l; i++) {
var object = arguments[i];
for (var key in object) {
master[key] = object[key];
}
}
}
};
Parallax.prototype.data = function(element, name) {
return this.deserialize(element.getAttribute('data-'+name));
};
Parallax.prototype.deserialize = function(value) {
if (value === "true") {
return true;
} else if (value === "false") {
return false;
} else if (value === "null") {
return null;
} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
return parseFloat(value);
} else {
return value;
}
};
Parallax.prototype.camelCase = function(value) {
return value.replace(/-+(.)?/g, function(match, character){
return character ? character.toUpperCase() : '';
});
};
Parallax.prototype.transformSupport = function(value) {
var element = document.createElement('div');
var propertySupport = false;
var propertyValue = null;
var featureSupport = false;
var cssProperty = null;
var jsProperty = null;
for (var i = 0, l = this.vendors.length; i < l; i++) {
if (this.vendors[i] !== null) {
cssProperty = this.vendors[i][0] + 'transform';
jsProperty = this.vendors[i][1] + 'Transform';
} else {
cssProperty = 'transform';
jsProperty = 'transform';
}
if (element.style[jsProperty] !== undefined) {
propertySupport = true;
break;
}
}
switch(value) {
case '2D':
featureSupport = propertySupport;
break;
case '3D':
if (propertySupport) {
var body = document.body || document.createElement('body');
var documentElement = document.documentElement;
var documentOverflow = documentElement.style.overflow;
if (!document.body) {
documentElement.style.overflow = 'hidden';
documentElement.appendChild(body);
body.style.overflow = 'hidden';
body.style.background = '';
}
body.appendChild(element);
element.style[jsProperty] = 'translate3d(1px,1px,1px)';
propertyValue = window.getComputedStyle(element).getPropertyValue(cssProperty);
featureSupport = propertyValue !== undefined && propertyValue.length > 0 && propertyValue !== "none";
documentElement.style.overflow = documentOverflow;
body.removeChild(element);
}
break;
}
return featureSupport;
};
Parallax.prototype.ww = null;
Parallax.prototype.wh = null;
Parallax.prototype.wcx = null;
Parallax.prototype.wcy = null;
Parallax.prototype.wrx = null;
Parallax.prototype.wry = null;
Parallax.prototype.portrait = null;
Parallax.prototype.desktop = !navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|BB10|mobi|tablet|opera mini|nexus 7)/i);
Parallax.prototype.vendors = [null,['-webkit-','webkit'],['-moz-','Moz'],['-o-','O'],['-ms-','ms']];
Parallax.prototype.motionSupport = !!window.DeviceMotionEvent;
Parallax.prototype.orientationSupport = !!window.DeviceOrientationEvent;
Parallax.prototype.orientationStatus = 0;
Parallax.prototype.transform2DSupport = Parallax.prototype.transformSupport('2D');
Parallax.prototype.transform3DSupport = Parallax.prototype.transformSupport('3D');
Parallax.prototype.propertyCache = {};
Parallax.prototype.initialise = function() {
// Configure Context Styles
if (this.transform3DSupport) this.accelerate(this.element);
var style = window.getComputedStyle(this.element);
if (style.getPropertyValue('position') === 'static') {
this.element.style.position = 'relative';
}
// Setup
this.updateLayers();
this.updateDimensions();
this.enable();
this.queueCalibration(this.calibrationDelay);
};
Parallax.prototype.updateLayers = function() {
// Cache Layer Elements
this.layers = this.element.getElementsByClassName('layer');
this.depths = [];
// Configure Layer Styles
for (var i = 0, l = this.layers.length; i < l; i++) {
var layer = this.layers[i];
if (this.transform3DSupport) this.accelerate(layer);
layer.style.position = i ? 'absolute' : 'relative';
layer.style.display = 'block';
layer.style.left = 0;
layer.style.top = 0;
// Cache Layer Depth
this.depths.push(this.data(layer, 'depth') || 0);
}
};
Parallax.prototype.updateDimensions = function() {
this.ww = window.innerWidth;
this.wh = window.innerHeight;
this.wcx = this.ww * this.originX;
this.wcy = this.wh * this.originY;
this.wrx = Math.max(this.wcx, this.ww - this.wcx);
this.wry = Math.max(this.wcy, this.wh - this.wcy);
};
Parallax.prototype.updateBounds = function() {
this.bounds = this.element.getBoundingClientRect();
this.ex = this.bounds.left;
this.ey = this.bounds.top;
this.ew = this.bounds.width;
this.eh = this.bounds.height;
this.ecx = this.ew * this.originX;
this.ecy = this.eh * this.originY;
this.erx = Math.max(this.ecx, this.ew - this.ecx);
this.ery = Math.max(this.ecy, this.eh - this.ecy);
};
Parallax.prototype.queueCalibration = function(delay) {
clearTimeout(this.calibrationTimer);
this.calibrationTimer = setTimeout(this.onCalibrationTimer, delay);
};
Parallax.prototype.enable = function() {
if (!this.enabled) {
this.enabled = true;
if (this.orientationSupport) {
this.portrait = null;
window.addEventListener('deviceorientation', this.onDeviceOrientation);
setTimeout(this.onOrientationTimer, this.supportDelay);
} else {
this.cx = 0;
this.cy = 0;
this.portrait = false;
window.addEventListener('mousemove', this.onMouseMove);
}
window.addEventListener('resize', this.onWindowResize);
this.raf = requestAnimationFrame(this.onAnimationFrame);
}
};
Parallax.prototype.disable = function() {
if (this.enabled) {
this.enabled = false;
if (this.orientationSupport) {
window.removeEventListener('deviceorientation', this.onDeviceOrientation);
} else {
window.removeEventListener('mousemove', this.onMouseMove);
}
window.removeEventListener('resize', this.onWindowResize);
cancelAnimationFrame(this.raf);
}
};
Parallax.prototype.calibrate = function(x, y) {
this.calibrateX = x === undefined ? this.calibrateX : x;
this.calibrateY = y === undefined ? this.calibrateY : y;
};
Parallax.prototype.invert = function(x, y) {
this.invertX = x === undefined ? this.invertX : x;
this.invertY = y === undefined ? this.invertY : y;
};
Parallax.prototype.friction = function(x, y) {
this.frictionX = x === undefined ? this.frictionX : x;
this.frictionY = y === undefined ? this.frictionY : y;
};
Parallax.prototype.scalar = function(x, y) {
this.scalarX = x === undefined ? this.scalarX : x;
this.scalarY = y === undefined ? this.scalarY : y;
};
Parallax.prototype.limit = function(x, y) {
this.limitX = x === undefined ? this.limitX : x;
this.limitY = y === undefined ? this.limitY : y;
};
Parallax.prototype.origin = function(x, y) {
this.originX = x === undefined ? this.originX : x;
this.originY = y === undefined ? this.originY : y;
};
Parallax.prototype.clamp = function(value, min, max) {
value = Math.max(value, min);
value = Math.min(value, max);
return value;
};
Parallax.prototype.css = function(element, property, value) {
var jsProperty = this.propertyCache[property];
if (!jsProperty) {
for (var i = 0, l = this.vendors.length; i < l; i++) {
if (this.vendors[i] !== null) {
jsProperty = this.camelCase(this.vendors[i][1] + '-' + property);
} else {
jsProperty = property;
}
if (element.style[jsProperty] !== undefined) {
this.propertyCache[property] = jsProperty;
break;
}
}
}
element.style[jsProperty] = value;
};
Parallax.prototype.accelerate = function(element) {
this.css(element, 'transform', 'translate3d(0,0,0)');
this.css(element, 'transform-style', 'preserve-3d');
this.css(element, 'backface-visibility', 'hidden');
};
Parallax.prototype.setPosition = function(element, x, y) {
x += 'px';
y += 'px';
if (this.transform3DSupport) {
this.css(element, 'transform', 'translate3d('+x+','+y+',0)');
} else if (this.transform2DSupport) {
this.css(element, 'transform', 'translate('+x+','+y+')');
} else {
element.style.left = x;
element.style.top = y;
}
};
Parallax.prototype.onOrientationTimer = function(event) {
if (this.orientationSupport && this.orientationStatus === 0) {
this.disable();
this.orientationSupport = false;
this.enable();
}
};
Parallax.prototype.onCalibrationTimer = function(event) {
this.calibrationFlag = true;
};
Parallax.prototype.onWindowResize = function(event) {
this.updateDimensions();
};
Parallax.prototype.onAnimationFrame = function() {
this.updateBounds();
var dx = this.ix - this.cx;
var dy = this.iy - this.cy;
if ((Math.abs(dx) > this.calibrationThreshold) || (Math.abs(dy) > this.calibrationThreshold)) {
this.queueCalibration(0);
}
if (this.portrait) {
this.mx = this.calibrateX ? dy : this.iy;
this.my = this.calibrateY ? dx : this.ix;
} else {
this.mx = this.calibrateX ? dx : this.ix;
this.my = this.calibrateY ? dy : this.iy;
}
this.mx *= this.ew * (this.scalarX / 100);
this.my *= this.eh * (this.scalarY / 100);
if (!isNaN(parseFloat(this.limitX))) {
this.mx = this.clamp(this.mx, -this.limitX, this.limitX);
}
if (!isNaN(parseFloat(this.limitY))) {
this.my = this.clamp(this.my, -this.limitY, this.limitY);
}
this.vx += (this.mx - this.vx) * this.frictionX;
this.vy += (this.my - this.vy) * this.frictionY;
for (var i = 0, l = this.layers.length; i < l; i++) {
var layer = this.layers[i];
var depth = this.depths[i];
var xOffset = this.vx * depth * (this.invertX ? -1 : 1);
var yOffset = this.vy * depth * (this.invertY ? -1 : 1);
this.setPosition(layer, xOffset, yOffset);
}
this.raf = requestAnimationFrame(this.onAnimationFrame);
};
Parallax.prototype.onDeviceOrientation = function(event) {
// Validate environment and event properties.
if (!this.desktop && event.beta !== null && event.gamma !== null) {
// Set orientation status.
this.orientationStatus = 1;
// Extract Rotation
var x = (event.beta || 0) / MAGIC_NUMBER; // -90 :: 90
var y = (event.gamma || 0) / MAGIC_NUMBER; // -180 :: 180
// Detect Orientation Change
var portrait = this.wh > this.ww;
if (this.portrait !== portrait) {
this.portrait = portrait;
this.calibrationFlag = true;
}
// Set Calibration
if (this.calibrationFlag) {
this.calibrationFlag = false;
this.cx = x;
this.cy = y;
}
// Set Input
this.ix = x;
this.iy = y;
}
};
Parallax.prototype.onMouseMove = function(event) {
// Cache mouse coordinates.
var clientX = event.clientX;
var clientY = event.clientY;
// Calculate Mouse Input
if (!this.orientationSupport && this.relativeInput) {
// Clip mouse coordinates inside element bounds.
if (this.clipRelativeInput) {
clientX = Math.max(clientX, this.ex);
clientX = Math.min(clientX, this.ex + this.ew);
clientY = Math.max(clientY, this.ey);
clientY = Math.min(clientY, this.ey + this.eh);
}
// Calculate input relative to the element.
this.ix = (clientX - this.ex - this.ecx) / this.erx;
this.iy = (clientY - this.ey - this.ecy) / this.ery;
} else {
// Calculate input relative to the window.
this.ix = (clientX - this.wcx) / this.wrx;
this.iy = (clientY - this.wcy) / this.wry;
}
};
// Expose Parallax
window[NAME] = Parallax;
})(window, document);
/**
* Request Animation Frame Polyfill.
* @author Tino Zijdel
* @author Paul Irish
* @see https://gist.github.com/paulirish/1579671
*/
;(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', '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);
};
}
}());

1
sorcery/parallax.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB