Add draft of Future is Here presentation
BIN
future-here-nyccamp/1024px-Dionysus_i2c_dac.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 401 KiB |
BIN
future-here-nyccamp/1413479953ewaste2.jpg
Normal file
After Width: | Height: | Size: 869 KiB |
26
future-here-nyccamp/LICENSE
Normal file
|
@ -0,0 +1,26 @@
|
|||
Copyright (c) 2012, Michael Bostock
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* The name Michael Bostock may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
BIN
future-here-nyccamp/NetNeutralityFreakOut.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
future-here-nyccamp/Prometheus_800.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
14
future-here-nyccamp/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# The Future is Here
|
||||
|
||||
What's your [software/business/platform] got to do with it?
|
||||
|
||||
Slides for a presentation at NYCcamp, but don't expect much entertainment without me there.
|
||||
|
||||
View <a href="http://mlncn.github.io/future-here-nyccamp/">index.html</a> in a browser.
|
||||
|
||||
# Built on stack.js
|
||||
|
||||
Stack.js is a presentation library with intuitive, scroll-based navigation.
|
||||
|
||||
https://mbostock.github.io/stack/
|
||||
https://github.com/mbostock/stack
|
BIN
future-here-nyccamp/bizarro-stats.jpg
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
future-here-nyccamp/building-disturbing-prospect-park.jpg
Executable file
After Width: | Height: | Size: 1.2 MiB |
BIN
future-here-nyccamp/coal-smokestacks-flickr-2471730096.jpg
Normal file
After Width: | Height: | Size: 898 KiB |
After Width: | Height: | Size: 82 KiB |
9294
future-here-nyccamp/d3.v3.js
vendored
Normal file
5
future-here-nyccamp/d3.v3.min.js
vendored
Normal file
BIN
future-here-nyccamp/gradeneuron_treeoflife4.png
Normal file
After Width: | Height: | Size: 48 KiB |
284
future-here-nyccamp/index.html
Normal file
|
@ -0,0 +1,284 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>The Future is Here. What's Drupal got to do with it?</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<style>
|
||||
|
||||
@import url(http://fonts.googleapis.com/css?family=Ubuntu:500|Quattrocento+Sans:400,700,400italic);
|
||||
|
||||
section {
|
||||
background-color: white;
|
||||
color: black;
|
||||
padding: 2em;
|
||||
font-family: "Quattrocento Sans", Helvetica, Verdana, sans-serif;
|
||||
font-weight: 400;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
section.reverse {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
section p {
|
||||
font-size: 1em;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
section strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-family: Ubuntu, Arial, sans-serif;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.big li {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
cite {
|
||||
font-size: .8em;
|
||||
color: #666;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #99CCFF;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section class="reverse" style="padding-top: 2em">
|
||||
<h1>The Future is Here</h1>
|
||||
<h2>What's Drupal got to do with it?</h2>
|
||||
<br />
|
||||
<h4><a href="https://etherpad.mozilla.org/future-here-nyccamp">etherpad.mozilla.org/future-here-nyccamp</a></h4>
|
||||
<br />
|
||||
<h4><a href="https://mlncn.withknown.com/">@mlncn</a><br />
|
||||
<a href="http://agaric.com/">agaric.com</a></h4>
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(sky.jpg);">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(solar-for-cell-towers-flickr-15247791918.jpg);">
|
||||
<h2>The future is already here—</h2>
|
||||
<cite><a href="https://www.flickr.com/photos/robinzblog/">Robin Capper</a>, Cell phone towers powered by solar panels, Nepal</cite>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(prison-west-virginia-flickr-2678338123.jpg);">
|
||||
<h2 style="margin-top: 10em">it’s just not very evenly distributed.</h2>
|
||||
<cite><a href="https://www.flickr.com/photos/littlesister/">IndyDina</a>, "Moundsville Penitentiary, West Virginia"</cite>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(solar-on-thatch-flickr-10145544156.jpg);">
|
||||
<cite><a href="https://www.flickr.com/photos/divatusaid/">Azuri Technologies</a>, <a href="http://www.usaid.gov/div/portfolio/azuri">Rwanda pay-as-you-go</a></cite>
|
||||
</section>
|
||||
|
||||
|
||||
<section style="background-image:url(1413479953ewaste2.jpg);">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(building-disturbing-prospect-park.jpg);">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(140605-bp-oil-spill-rig-1321_29ac02f087e8f1e6d66c32b28ee5e801.jpg);">
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Companies with valuations based largely on your data</h2>
|
||||
<ul>
|
||||
<li>Acxiom ($1.3B)</li>
|
||||
<li>Uber ($41B)</li>
|
||||
<li>Palantir Technologies ($10B)</li>
|
||||
<li>Yelp ($1.47B)</li>
|
||||
<li>Facebook ($255B)</li>
|
||||
<li>Google ($403B)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(waze-com-2015-07-15.png); background-size:contain;">
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(coal-smokestacks-flickr-2471730096.jpg);">
|
||||
<cite><a href="https://www.flickr.com/photos/11441121@N04/">peggydavis66</a>, "Coal power plant"</cite>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(solar-rainbow-flickr_12861896715.jpg);">
|
||||
<cite><a href="https://www.flickr.com/photos/jurvetson/">Steve Jurvetson</a>, "Solar Rainbow greeting me as I awoke on my birthday"</cite>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<ul class="big">
|
||||
<li>We are the network. We effect (create, cause, bring into being) the value.</li>
|
||||
<li>Open platforms have disadvantages to closed: in making up-front investment (one entity controlling a platform can capture the value more easily), can be easier to make a good user experience</li>
|
||||
<li>Open platforms have advantages over closed: more companies can try their ideas, more different needs can be served (long tail).</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(NetNeutralityFreakOut.png); background-size:contain; background-position: center; background-repeat: no-repeat;">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(gradeneuron_treeoflife4.png);">
|
||||
</section>
|
||||
|
||||
<section style="padding-top:6em">
|
||||
<ul class="big">
|
||||
<li>Share data</li>
|
||||
<li>???</li>
|
||||
<li>Profit</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(content_seattle536403_585014608182994_1431750072_n.jpg); padding-top: 8em">
|
||||
<h1 style="margin-top:4.5em"><a href="http://www.gardeneuron.net/">Gardeneuron.net</a></h1>
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(gradeneuron_treeoflife4.png); background-size: contain; background-position: center; background-repeat: no-repeat;">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(restaurant-project-screenshot.png);">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(roomify-screenshot.png);">
|
||||
</section>
|
||||
|
||||
<section style="background-image:url(indiewebcamp_logo_1600px.png);">
|
||||
</section>
|
||||
|
||||
<section class="reverse" style="padding:6em 13em;">
|
||||
<h4><a href="https://etherpad.mozilla.org/future-here-nyccamp">etherpad.mozilla.org/future-here-nyccamp</a></h4>
|
||||
<h4><a href="http://mlncn.withknown.com/" rel="author">benjamin melançon</a></h4>
|
||||
<h5><a href="mailto:ben@agaric.com">ben@agaric.com</a></h5>
|
||||
<h5><a href="https://twitter.com/mlncn">@mlncn</a></h5>
|
||||
</section>
|
||||
|
||||
<section id="lorenz" style="text-align:center;padding-top:0;">
|
||||
<canvas></canvas>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1><img src="klout.png" /></h1>
|
||||
</section>
|
||||
|
||||
<section style="background-image: url(bizarro-stats.jpg); background-size:contain; background-position: center; background-repeat: no-repeat;">
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>Distributed data and processing</p>
|
||||
Bitcoin minus mining equals the future we deserve.
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<li>This results in viable business models for free data.</li>
|
||||
</section>
|
||||
|
||||
<script src="d3.v3.min.js"></script>
|
||||
<script src="stack.v1.js"></script>
|
||||
<script>
|
||||
|
||||
var mystack = stack()
|
||||
.on("activate", activate)
|
||||
.on("deactivate", deactivate);
|
||||
|
||||
var section = d3.selectAll("section"),
|
||||
lorenz = d3.select("#lorenz"),
|
||||
lorenzIndex = section[0].indexOf(lorenz.node());
|
||||
|
||||
function activate(d, i) {
|
||||
if (i === lorenzIndex) startLorenz();
|
||||
}
|
||||
|
||||
function deactivate(d, i) {
|
||||
if (i === lorenzIndex) stopLorenz();
|
||||
}
|
||||
|
||||
var lorenzInterval;
|
||||
|
||||
function startLorenz() {
|
||||
var δτ = 0.003,
|
||||
ρ = 28,
|
||||
σ = 10,
|
||||
β = 8 / 3,
|
||||
x = .5,
|
||||
y = .5,
|
||||
z = 10,
|
||||
n = 30;
|
||||
|
||||
var width = 1280,
|
||||
height = 720;
|
||||
|
||||
var canvas = d3.select("canvas")
|
||||
.style("position", "absolute")
|
||||
.style("top", 0)
|
||||
.style("left", 0)
|
||||
.style("width", "100%")
|
||||
.style("height", "100%")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
var color = d3.scale.linear()
|
||||
.domain([0, 20, 30, 50])
|
||||
.range(["yellow", "orange", "brown", "purple"])
|
||||
.interpolate(d3.interpolateHcl);
|
||||
|
||||
var context = canvas.node().getContext("2d");
|
||||
|
||||
context.lineWidth = .2;
|
||||
context.fillStyle = "rgba(0,0,0,.03)";
|
||||
|
||||
d3.timer(function() {
|
||||
context.save();
|
||||
context.globalCompositeOperation = "lighter";
|
||||
context.translate(width / 2, height / 2);
|
||||
context.scale(12, 14);
|
||||
context.rotate(30);
|
||||
for (var i = 0; i < n; ++i) {
|
||||
context.strokeStyle = color(z);
|
||||
context.beginPath();
|
||||
context.moveTo(x, y);
|
||||
x += δτ * σ * (y - x);
|
||||
y += δτ * (x * (ρ - z) - y);
|
||||
z += δτ * (x * y - β * z);
|
||||
context.lineTo(x, y);
|
||||
context.stroke();
|
||||
}
|
||||
context.restore();
|
||||
return !lorenzInterval;
|
||||
});
|
||||
|
||||
lorenzInterval = setInterval(function() {
|
||||
context.fillRect(0, 0, width, height);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function stopLorenz() {
|
||||
lorenzInterval = clearInterval(lorenzInterval);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
BIN
future-here-nyccamp/indiewebcamp_logo_1600px.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
future-here-nyccamp/klout.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
future-here-nyccamp/prison-west-virginia-flickr-2678338123.jpg
Normal file
After Width: | Height: | Size: 668 KiB |
BIN
future-here-nyccamp/restaurants-project-screenshot.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
future-here-nyccamp/roomify-screenshot.png
Normal file
After Width: | Height: | Size: 266 KiB |
BIN
future-here-nyccamp/sky.jpg
Normal file
After Width: | Height: | Size: 290 KiB |
BIN
future-here-nyccamp/skyfireenergy-2011-tesla-solar-panels.jpg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
future-here-nyccamp/solar-for-cell-towers-flickr-15247791918.jpg
Normal file
After Width: | Height: | Size: 1 MiB |
BIN
future-here-nyccamp/solar-on-thatch-flickr-10145544156.jpg
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
future-here-nyccamp/solar-parkside-ave.jpg
Executable file
After Width: | Height: | Size: 2.9 MiB |
BIN
future-here-nyccamp/solar-rainbow-flickr_12861896715.jpg
Normal file
After Width: | Height: | Size: 643 KiB |
55
future-here-nyccamp/stack.v0.css
Normal file
|
@ -0,0 +1,55 @@
|
|||
body {
|
||||
background: #929292;
|
||||
font-family: "Helvetica Neue";
|
||||
margin: auto;
|
||||
width: 1280px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #6baed6;
|
||||
}
|
||||
|
||||
a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.stack {
|
||||
background: #222 url(cartographer.png);
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-o-box-sizing: border-box;
|
||||
display: none;
|
||||
font-size: 48px;
|
||||
height: 800px;
|
||||
padding: 160px 80px;
|
||||
width: 1280px;
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
.active {
|
||||
box-shadow: 0px 4px 8px rgba(0,0,0,.5);
|
||||
display: block;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.grey {
|
||||
color: #969696;
|
||||
}
|
||||
|
||||
@media
|
||||
screen and (max-device-width: 1024px) {
|
||||
body {
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
.stack {
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: block;
|
||||
}
|
||||
}
|
219
future-here-nyccamp/stack.v0.js
Normal file
|
@ -0,0 +1,219 @@
|
|||
var stack = (function() {
|
||||
var stack = {},
|
||||
event = d3.dispatch("activate", "deactivate"),
|
||||
section = d3.selectAll("section"),
|
||||
self = d3.select(window),
|
||||
body = document.body,
|
||||
root = document.documentElement,
|
||||
timeout,
|
||||
duration = 250,
|
||||
ease = "cubic-in-out",
|
||||
screenY,
|
||||
size,
|
||||
yActual,
|
||||
yFloor,
|
||||
yTarget,
|
||||
yActive = -1,
|
||||
yMax,
|
||||
yOffset,
|
||||
n = section[0].length;
|
||||
|
||||
// Invert the z-index so the earliest slides are on top.
|
||||
section.classed("stack", true).style("z-index", function(d, i) { return n - i; });
|
||||
|
||||
// Detect the slide height (by showing an active slide).
|
||||
section.classed("active", true);
|
||||
size = section.node().getBoundingClientRect().height;
|
||||
section.classed("active", false);
|
||||
|
||||
// Sets the stack position.
|
||||
stack.position = function(y1) {
|
||||
var y0 = body.scrollTop / size;
|
||||
if (arguments.length < 1) return y0;
|
||||
|
||||
// clamp and round
|
||||
if (y1 >= n) y1 = n - 1;
|
||||
else if (y1 < 0) y1 = Math.max(0, n + y1);
|
||||
y1 = Math.floor(y1);
|
||||
|
||||
if (y0 - y1) {
|
||||
self.on("scroll.stack", null);
|
||||
leap(y1);
|
||||
d3.select(body).transition()
|
||||
.duration(duration)
|
||||
.ease(ease)
|
||||
.tween("scrollTop", tween(yTarget = y1))
|
||||
.each("end", function() { yTarget = null; self.on("scroll.stack", scroll); });
|
||||
}
|
||||
|
||||
location.replace("#" + y1);
|
||||
|
||||
return stack;
|
||||
};
|
||||
|
||||
// Don't do anything fancy for iOS.
|
||||
if (section.style("display") == "block") return;
|
||||
|
||||
self
|
||||
.on("keydown.stack", keydown)
|
||||
.on("resize.stack", resize)
|
||||
.on("scroll.stack", scroll)
|
||||
.on("mousemove.stack", snap)
|
||||
.on("hashchange.stack", hashchange);
|
||||
|
||||
resize();
|
||||
hashchange();
|
||||
scroll();
|
||||
|
||||
// if scrolling up, jump to edge of previous slide
|
||||
function leap(yNew) {
|
||||
if ((yActual < n - 1) && (yActual == yFloor) && (yNew < yActual)) {
|
||||
yActual -= .5 - yOffset / size / 2;
|
||||
scrollTo(0, yActual * size);
|
||||
reactivate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function reactivate() {
|
||||
var yNewActive = Math.floor(yActual) + (yActual % 1 ? .5 : 0);
|
||||
if (yNewActive !== yActive) {
|
||||
var yNewActives = {};
|
||||
yNewActives[Math.floor(yNewActive)] = 1;
|
||||
yNewActives[Math.ceil(yNewActive)] = 1;
|
||||
if (yActive >= 0) {
|
||||
var yOldActives = {};
|
||||
yOldActives[Math.floor(yActive)] = 1;
|
||||
yOldActives[Math.ceil(yActive)] = 1;
|
||||
for (var i in yOldActives) {
|
||||
if (i in yNewActives) delete yNewActives[i];
|
||||
else event.deactivate.call(section[0][+i], +i);
|
||||
}
|
||||
}
|
||||
for (var i in yNewActives) {
|
||||
event.activate.call(section[0][+i], +i);
|
||||
}
|
||||
yActive = yNewActive;
|
||||
}
|
||||
}
|
||||
|
||||
function resize() {
|
||||
yOffset = (window.innerHeight - size) / 2;
|
||||
yMax = 1 + yOffset / size;
|
||||
|
||||
d3.select(body)
|
||||
.style("margin-top", yOffset + "px")
|
||||
.style("margin-bottom", yOffset + "px")
|
||||
.style("height", (n - .5) * size + yOffset + "px");
|
||||
}
|
||||
|
||||
function hashchange() {
|
||||
var hash = +location.hash.slice(1);
|
||||
if (!isNaN(hash) && hash !== yFloor) stack.position(hash);
|
||||
}
|
||||
|
||||
function keydown() {
|
||||
var delta;
|
||||
switch (d3.event.keyCode) {
|
||||
case 39: // right arrow
|
||||
if (d3.event.metaKey) return;
|
||||
case 40: // down arrow
|
||||
case 34: // page down
|
||||
delta = d3.event.metaKey ? Infinity : 1; break;
|
||||
case 37: // left arrow
|
||||
if (d3.event.metaKey) return;
|
||||
case 38: // up arrow
|
||||
case 33: // page up
|
||||
delta = d3.event.metaKey ? -Infinity : -1; break;
|
||||
case 32: // space
|
||||
delta = d3.event.shiftKey ? -1 : 1;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
if (timeout) timeout = clearTimeout(timeout);
|
||||
if (yTarget == null) yTarget = (delta > 0 ? Math.floor : Math.ceil)(yActual == yFloor ? yFloor : yActual + (.5 - yOffset / size / 2));
|
||||
stack.position(yTarget = Math.max(0, Math.min(n - 1, yTarget + delta)));
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
|
||||
function scroll() {
|
||||
// Detect whether to scroll with documentElement or body.
|
||||
if (body !== root && root.scrollTop) body = root;
|
||||
|
||||
var yNew = Math.max(0, body.scrollTop / size);
|
||||
if (yNew >= n - 1.51 + yOffset / size) yNew = n - 1;
|
||||
|
||||
// if scrolling up, jump to edge of previous slide
|
||||
if (leap(yNew)) return;
|
||||
|
||||
var yNewFloor = Math.max(0, Math.floor(yActual = yNew)),
|
||||
yError = Math.min(yMax, (yActual % 1) * 2);
|
||||
|
||||
if (yFloor != yNewFloor) {
|
||||
location.replace("#" + yNewFloor);
|
||||
yFloor = yNewFloor;
|
||||
}
|
||||
|
||||
section
|
||||
.classed("active", false);
|
||||
|
||||
d3.select(section[0][yFloor])
|
||||
.style("-webkit-transform", yError ? "translate3d(0," + (-yError * size) + "px,0)" : null)
|
||||
.style("-o-transform", yError ? "translate(0," + (-yError * size) + "px)" : null)
|
||||
.style("-moz-transform", yError ? "translate(0," + (-yError * size) + "px)" : null)
|
||||
.style("transform", yError ? "translate(0," + (-yError * size) + "px)" : null)
|
||||
.classed("active", yError != yMax);
|
||||
|
||||
d3.select(section[0][yFloor + 1])
|
||||
.style("-webkit-transform", yError ? "translate3d(0,0,0)" : null)
|
||||
.style("-o-transform", yError ? "translate(0,0)" : null)
|
||||
.style("-moz-transform", yError ? "translate(0,0)" : null)
|
||||
.style("transform", yError ? "translate(0,0)" : null)
|
||||
.classed("active", yError > 0);
|
||||
|
||||
reactivate();
|
||||
}
|
||||
|
||||
function snap() {
|
||||
var y = d3.event.clientY;
|
||||
if (y === screenY) return; // ignore move on scroll
|
||||
screenY = y;
|
||||
|
||||
if (yTarget != null) return; // don't snap if already snapping
|
||||
|
||||
var y0 = stack.position(),
|
||||
y1 = Math.max(0, Math.round(y0 + .25));
|
||||
|
||||
// if we're before the first slide, or after the last slide, do nothing
|
||||
if (y0 <= 0 || y0 >= n - 1.51 + yOffset / size) return;
|
||||
|
||||
// if the previous slide is not visible, immediate jump
|
||||
if (y1 > y0 && y1 - y0 < .5 - yOffset / size) scrollTo(0, y1 * size);
|
||||
|
||||
// else transition
|
||||
else if (y1 !== y0) stack.position(y1);
|
||||
}
|
||||
|
||||
function tween(y) {
|
||||
return function() {
|
||||
var i = d3.interpolateNumber(this.scrollTop, y * size);
|
||||
return function(t) { scrollTo(0, i(t)); scroll(); };
|
||||
};
|
||||
}
|
||||
|
||||
stack.duration = function(_) {
|
||||
if (!arguments.length) return duration;
|
||||
duration = _;
|
||||
return stack;
|
||||
};
|
||||
|
||||
stack.ease = function(_) {
|
||||
if (!arguments.length) return ease;
|
||||
ease = _;
|
||||
return stack;
|
||||
};
|
||||
|
||||
d3.rebind(stack, event, "on");
|
||||
|
||||
return stack;
|
||||
})();
|
1
future-here-nyccamp/stack.v0.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
var stack=function(){function t(t){return K-1>d&&d==f&&d>t?(d-=.5-m/u/2,scrollTo(0,d*u),e(),!0):void 0}function e(){var t=Math.floor(d)+(d%1?.5:0);if(t!==T){var e={};if(e[Math.floor(t)]=1,e[Math.ceil(t)]=1,T>=0){var n={};n[Math.floor(T)]=1,n[Math.ceil(T)]=1;for(var a in n)a in e?delete e[a]:y.deactivate.call(k[0][+a],+a)}for(var a in e)y.activate.call(k[0][+a],+a);T=t}}function n(){m=(window.innerHeight-u)/2,v=1+m/u,d3.select(g).style("margin-top",m+"px").style("margin-bottom",m+"px").style("height",(K-.5)*u+m+"px")}function a(){var t=+location.hash.slice(1);isNaN(t)||t===f||p.position(t)}function l(){var t;switch(d3.event.keyCode){case 39:if(d3.event.metaKey)return;case 40:case 34:t=d3.event.metaKey?1/0:1;break;case 37:if(d3.event.metaKey)return;case 38:case 33:t=d3.event.metaKey?-1/0:-1;break;case 32:t=d3.event.shiftKey?-1:1;break;default:return}c&&(c=clearTimeout(c)),null==h&&(h=(t>0?Math.floor:Math.ceil)(d==f?f:d+(.5-m/u/2))),p.position(h=Math.max(0,Math.min(K-1,h+t))),d3.event.preventDefault()}function o(){g!==x&&x.scrollTop&&(g=x);var n=Math.max(0,g.scrollTop/u);if(n>=K-1.51+m/u&&(n=K-1),!t(n)){var a=Math.max(0,Math.floor(d=n)),l=Math.min(v,2*(d%1));f!=a&&(location.replace("#"+a),f=a),k.classed("active",!1),d3.select(k[0][f]).style("-webkit-transform",l?"translate3d(0,"+-l*u+"px,0)":null).style("-o-transform",l?"translate(0,"+-l*u+"px)":null).style("-moz-transform",l?"translate(0,"+-l*u+"px)":null).style("transform",l?"translate(0,"+-l*u+"px)":null).classed("active",l!=v),d3.select(k[0][f+1]).style("-webkit-transform",l?"translate3d(0,0,0)":null).style("-o-transform",l?"translate(0,0)":null).style("-moz-transform",l?"translate(0,0)":null).style("transform",l?"translate(0,0)":null).classed("active",l>0),e()}}function r(){var t=d3.event.clientY;if(t!==i&&(i=t,null==h)){var e=p.position(),n=Math.max(0,Math.round(e+.25));0>=e||e>=K-1.51+m/u||(n>e&&.5-m/u>n-e?scrollTo(0,n*u):n!==e&&p.position(n))}}function s(t){return function(){var e=d3.interpolateNumber(this.scrollTop,t*u);return function(t){scrollTo(0,e(t)),o()}}}var c,i,u,d,f,h,v,m,p={},y=d3.dispatch("activate","deactivate"),k=d3.selectAll("section"),M=d3.select(window),g=document.body,x=document.documentElement,b=250,w="cubic-in-out",T=-1,K=k[0].length;return k.classed("stack",!0).style("z-index",function(t,e){return K-e}),k.classed("active",!0),u=k.node().getBoundingClientRect().height,k.classed("active",!1),p.position=function(e){var n=g.scrollTop/u;return arguments.length<1?n:(e>=K?e=K-1:0>e&&(e=Math.max(0,K+e)),e=Math.floor(e),n-e&&(M.on("scroll.stack",null),t(e),d3.select(g).transition().duration(b).ease(w).tween("scrollTop",s(h=e)).each("end",function(){h=null,M.on("scroll.stack",o)})),location.replace("#"+e),p)},k.style("display")!="block"?(M.on("keydown.stack",l).on("resize.stack",n).on("scroll.stack",o).on("mousemove.stack",r).on("hashchange.stack",a),n(),a(),o(),p.duration=function(t){return arguments.length?(b=t,p):b},p.ease=function(t){return arguments.length?(w=t,p):w},d3.rebind(p,y,"on"),p):void 0}();
|
231
future-here-nyccamp/stack.v1.js
Normal file
|
@ -0,0 +1,231 @@
|
|||
function stack() {
|
||||
var stack = {},
|
||||
size = [1280, 720],
|
||||
fontSize = 32,
|
||||
sectionHeight,
|
||||
windowHeight,
|
||||
dispatch = d3.dispatch("scroll", "activate", "deactivate"),
|
||||
touchy = "ontouchstart" in document,
|
||||
resize = touchy ? resizeTouchy : resizeNoTouchy,
|
||||
i = NaN,
|
||||
y = 0,
|
||||
yt,
|
||||
scrollRatio = 1 / 6;
|
||||
|
||||
var section = d3.selectAll("section")
|
||||
.style("box-sizing", "border-box")
|
||||
.each(initialize);
|
||||
|
||||
var n = section.size();
|
||||
|
||||
var body = d3.select("body")
|
||||
.style("margin", 0)
|
||||
.style("padding", 0)
|
||||
.style("background", "#333");
|
||||
|
||||
if (touchy) {
|
||||
section
|
||||
.style("position", "relative");
|
||||
|
||||
d3.select(window)
|
||||
.on("resize.stack", resize)
|
||||
.each(resize);
|
||||
} else {
|
||||
var background = d3.select("body").insert("div", "section")
|
||||
.style("background", "#000")
|
||||
.style("box-shadow", "0 8px 16px rgba(0,0,0,.3)")
|
||||
.style("padding", "1px 0")
|
||||
.style("margin-top", "-1px")
|
||||
.style("z-index", 0);
|
||||
|
||||
section
|
||||
.style("display", "none")
|
||||
.style("opacity", 0)
|
||||
.style("z-index", 0);
|
||||
|
||||
var sectionAndBackground = d3.selectAll(section[0].concat(background.node()))
|
||||
.style("position", "fixed")
|
||||
.style("left", 0)
|
||||
.style("top", 0)
|
||||
.style("width", "100%");
|
||||
|
||||
var indicator = d3.select("body").append("div")
|
||||
.attr("class", "indicator")
|
||||
.selectAll("div")
|
||||
.data(d3.range(section.size()))
|
||||
.enter().append("div")
|
||||
.style("position", "absolute")
|
||||
.style("z-index", 10)
|
||||
.style("left", 0)
|
||||
.style("width", "3px")
|
||||
.style("background", "linear-gradient(to top,black,white)");
|
||||
|
||||
var sectionPrevious = d3.select(null),
|
||||
sectionCurrent = d3.select(section[0][0]),
|
||||
sectionNext = d3.select(section[0][1]);
|
||||
|
||||
d3.select(window)
|
||||
.on("resize.stack", resize)
|
||||
.on("scroll.stack", reposition)
|
||||
.on("keydown.stack", keydown)
|
||||
.each(resize);
|
||||
|
||||
d3.timer(function() {
|
||||
reposition();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function dispatchEvent(event, i) {
|
||||
var target = section[0][i], sourceEvent = event.sourceEvent = d3.event;
|
||||
try {
|
||||
d3.event = event;
|
||||
dispatch[event.type].call(target, target.__data__, i);
|
||||
} finally {
|
||||
d3.event = sourceEvent;
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(d, i) {
|
||||
this.__stack__ = {index: i, active: false};
|
||||
}
|
||||
|
||||
function activate() {
|
||||
if (!this.__stack__.active) {
|
||||
this.__stack__.active = true;
|
||||
dispatchEvent({type: "activate"}, this.__stack__.index);
|
||||
}
|
||||
}
|
||||
|
||||
function deactivate() {
|
||||
if (this.__stack__.active) {
|
||||
this.__stack__.active = false;
|
||||
dispatchEvent({type: "deactivate"}, this.__stack__.index);
|
||||
}
|
||||
}
|
||||
|
||||
function resizeTouchy() {
|
||||
var marginBottom = 20;
|
||||
|
||||
sectionHeight = size[1] / size[0] * innerWidth;
|
||||
windowHeight = innerHeight;
|
||||
|
||||
section
|
||||
.style("height", sectionHeight + "px")
|
||||
.style("box-shadow", "0 4px 4px rgba(0,0,0,.3)")
|
||||
.filter(function(d, i) { return i < n - 1; })
|
||||
.style("margin-bottom", marginBottom + "px");
|
||||
|
||||
body
|
||||
.style("font-size", innerWidth / size[0] * fontSize + "px");
|
||||
}
|
||||
|
||||
function resizeNoTouchy() {
|
||||
if (sectionHeight) var y0 = y;
|
||||
|
||||
sectionHeight = size[1] / size[0] * innerWidth;
|
||||
windowHeight = innerHeight;
|
||||
|
||||
sectionAndBackground
|
||||
.style("top", (windowHeight - sectionHeight) / 2 + "px")
|
||||
.style("height", sectionHeight + "px");
|
||||
|
||||
indicator
|
||||
.style("top", function(i) { return (i + (1 - scrollRatio) / 2) * windowHeight + "px"; })
|
||||
.style("height", windowHeight * scrollRatio + "px");
|
||||
|
||||
body
|
||||
.style("font-size", innerWidth / size[0] * fontSize + "px")
|
||||
.style("height", windowHeight * n + "px");
|
||||
|
||||
// Preserve the current scroll position on resize.
|
||||
if (!isNaN(y0)) scrollTo(0, (y = y0) * windowHeight);
|
||||
}
|
||||
|
||||
function reposition() {
|
||||
var y1 = pageYOffset / windowHeight,
|
||||
i1 = Math.max(0, Math.min(n - 1, Math.floor(y1 + (1 + scrollRatio) / 2)));
|
||||
|
||||
if (i !== i1) {
|
||||
if (i1 === i + 1) { // advance one
|
||||
sectionPrevious.interrupt().style("display", "none").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionPrevious = sectionCurrent.interrupt().style("opacity", 1).style("z-index", 1);
|
||||
sectionPrevious.transition().each("end", deactivate);
|
||||
sectionCurrent = sectionNext.interrupt().style("opacity", 0).style("z-index", 2).each(activate);
|
||||
sectionCurrent.transition().style("opacity", 1);
|
||||
sectionNext = d3.select(section[0][i1 + 1]).interrupt().style("display", "block").style("opacity", 0).style("z-index", 0);
|
||||
} else if (i1 === i - 1) { // rewind one
|
||||
sectionNext.interrupt().style("display", "none").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionNext = sectionCurrent.interrupt().style("opacity", 1).style("z-index", 1);
|
||||
sectionNext.transition().each("end", deactivate);
|
||||
sectionCurrent = sectionPrevious.interrupt().style("opacity", 0).style("z-index", 2).each(activate);
|
||||
sectionCurrent.transition().style("opacity", 1);
|
||||
sectionPrevious = d3.select(section[0][i1 - 1]).interrupt().style("display", "block").style("opacity", 0).style("z-index", 0);
|
||||
} else { // skip
|
||||
sectionPrevious.interrupt().style("display", "none").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionCurrent.interrupt().style("display", "none").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionNext.interrupt().style("display", "none").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionPrevious = d3.select(section[0][i1 - 1]).interrupt().style("display", "block").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
sectionCurrent = d3.select(section[0][i1]).interrupt().style("display", "block").style("opacity", 1).style("z-index", 2).each(activate);
|
||||
sectionNext = d3.select(section[0][i1 + 1]).interrupt().style("display", "block").style("opacity", 0).style("z-index", 0).each(deactivate);
|
||||
}
|
||||
i = i1;
|
||||
}
|
||||
|
||||
dispatchEvent({type: "scroll", offset: y = y1}, i);
|
||||
}
|
||||
|
||||
function keydown() {
|
||||
var delta;
|
||||
switch (d3.event.keyCode) {
|
||||
case 39: // right arrow
|
||||
if (d3.event.metaKey) return;
|
||||
case 40: // down arrow
|
||||
case 34: // page down
|
||||
delta = d3.event.metaKey ? Infinity : 1; break;
|
||||
case 37: // left arrow
|
||||
if (d3.event.metaKey) return;
|
||||
case 38: // up arrow
|
||||
case 33: // page up
|
||||
delta = d3.event.metaKey ? -Infinity : -1; break;
|
||||
case 32: // space
|
||||
delta = d3.event.shiftKey ? -1 : 1;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
var y0 = isNaN(yt) ? y : yt;
|
||||
|
||||
yt = Math.max(0, Math.min(n - 1, (delta > 0
|
||||
? Math.floor(y0 + (1 + scrollRatio) / 2)
|
||||
: Math.ceil(y0 - (1 - scrollRatio) / 2)) + delta));
|
||||
|
||||
d3.select(document.documentElement)
|
||||
.interrupt()
|
||||
.transition()
|
||||
.duration(500)
|
||||
.tween("scroll", function() {
|
||||
var i = d3.interpolateNumber(pageYOffset, yt * windowHeight);
|
||||
return function(t) { scrollTo(0, i(t)); };
|
||||
})
|
||||
.each("end", function() { yt = NaN; });
|
||||
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
|
||||
stack.size = function(_) {
|
||||
return arguments.length ? (size = [+_[0], +_[1]], resize(), stack) : size;
|
||||
};
|
||||
|
||||
stack.scrollRatio = function(_) {
|
||||
return arguments.length ? (scrollRatio = +_, resize(), stack) : scrollRatio;
|
||||
};
|
||||
|
||||
stack.fontSize = function(_) {
|
||||
return arguments.length ? (fontSize = +_, resize(), stack) : fontSize;
|
||||
};
|
||||
|
||||
d3.rebind(stack, dispatch, "on");
|
||||
|
||||
return stack;
|
||||
}
|
1
future-here-nyccamp/stack.v1.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
function stack(){function e(e,t){var n=b[0][t],i=e.sourceEvent=d3.event;try{d3.event=e,h[e.type].call(n,n.__data__,t)}finally{d3.event=i}}function t(e,t){this.__stack__={index:t,active:!1}}function n(){this.__stack__.active||(this.__stack__.active=!0,e({type:"activate"},this.__stack__.index))}function i(){this.__stack__.active&&(this.__stack__.active=!1,e({type:"deactivate"},this.__stack__.index))}function s(){var e=20;o=p[1]/p[0]*innerWidth,r=innerHeight,b.style("height",o+"px").style("box-shadow","0 4px 4px rgba(0,0,0,.3)").filter(function(e,t){return k-1>t}).style("margin-bottom",e+"px"),z.style("font-size",innerWidth/p[0]*u+"px")}function l(){if(o)var e=_;o=p[1]/p[0]*innerWidth,r=innerHeight,w.style("top",(r-o)/2+"px").style("height",o+"px"),M.style("top",function(e){return(e+(1-g)/2)*r+"px"}).style("height",r*g+"px"),z.style("font-size",innerWidth/p[0]*u+"px").style("height",r*k+"px"),isNaN(e)||scrollTo(0,(_=e)*r)}function a(){var t=pageYOffset/r,s=Math.max(0,Math.min(k-1,Math.floor(t+(1+g)/2)));v!==s&&(s===v+1?(K.interrupt().style("display","none").style("opacity",0).style("z-index",0).each(i),K=N.interrupt().style("opacity",1).style("z-index",1),K.transition().each("end",i),N=W.interrupt().style("opacity",0).style("z-index",2).each(n),N.transition().style("opacity",1),W=d3.select(b[0][s+1]).interrupt().style("display","block").style("opacity",0).style("z-index",0)):s===v-1?(W.interrupt().style("display","none").style("opacity",0).style("z-index",0).each(i),W=N.interrupt().style("opacity",1).style("z-index",1),W.transition().each("end",i),N=K.interrupt().style("opacity",0).style("z-index",2).each(n),N.transition().style("opacity",1),K=d3.select(b[0][s-1]).interrupt().style("display","block").style("opacity",0).style("z-index",0)):(K.interrupt().style("display","none").style("opacity",0).style("z-index",0).each(i),N.interrupt().style("display","none").style("opacity",0).style("z-index",0).each(i),W.interrupt().style("display","none").style("opacity",0).style("z-index",0).each(i),K=d3.select(b[0][s-1]).interrupt().style("display","block").style("opacity",0).style("z-index",0).each(i),N=d3.select(b[0][s]).interrupt().style("display","block").style("opacity",1).style("z-index",2).each(n),W=d3.select(b[0][s+1]).interrupt().style("display","block").style("opacity",0).style("z-index",0).each(i)),v=s),e({type:"scroll",offset:_=t},v)}function c(){var e;switch(d3.event.keyCode){case 39:if(d3.event.metaKey)return;case 40:case 34:e=d3.event.metaKey?1/0:1;break;case 37:if(d3.event.metaKey)return;case 38:case 33:e=d3.event.metaKey?-1/0:-1;break;case 32:e=d3.event.shiftKey?-1:1;break;default:return}var t=isNaN(y)?_:y;y=Math.max(0,Math.min(k-1,(e>0?Math.floor(t+(1+g)/2):Math.ceil(t-(1-g)/2))+e)),d3.select(document.documentElement).interrupt().transition().duration(500).tween("scroll",function(){var e=d3.interpolateNumber(pageYOffset,y*r);return function(t){scrollTo(0,e(t))}}).each("end",function(){y=0/0}),d3.event.preventDefault()}var o,r,y,d={},p=[1280,720],u=32,h=d3.dispatch("scroll","activate","deactivate"),x="ontouchstart"in document,f=x?s:l,v=0/0,_=0,g=1/6,b=d3.selectAll("section").style("box-sizing","border-box").style("line-height","1.35em").each(t),k=b.size(),z=d3.select("body").style("margin",0).style("padding",0).style("background","#333");if(x)b.style("position","relative"),d3.select(window).on("resize.stack",f).each(f);else{var m=d3.select("body").insert("div","section").style("background","#000").style("box-shadow","0 8px 16px rgba(0,0,0,.3)").style("padding","1px 0").style("margin-top","-1px").style("z-index",0);b.style("display","none").style("opacity",0).style("z-index",0);var w=d3.selectAll(b[0].concat(m.node())).style("position","fixed").style("left",0).style("top",0).style("width","100%"),M=d3.select("body").append("div").attr("class","indicator").selectAll("div").data(d3.range(b.size())).enter().append("div").style("position","absolute").style("z-index",10).style("left",0).style("width","3px").style("background","linear-gradient(to top,black,white)"),K=d3.select(null),N=d3.select(b[0][0]),W=d3.select(b[0][1]);d3.select(window).on("resize.stack",f).on("scroll.stack",a).on("keydown.stack",c).each(f),d3.timer(function(){return a(),!0})}return d.size=function(e){return arguments.length?(p=[+e[0],+e[1]],f(),d):p},d.scrollRatio=function(e){return arguments.length?(g=+e,f(),d):g},d.fontSize=function(e){return arguments.length?(u=+e,f(),d):u},d3.rebind(d,h,"on"),d}
|
BIN
future-here-nyccamp/waze-com-2015-07-15.png
Normal file
After Width: | Height: | Size: 265 KiB |