Skip to content

Instantly share code, notes, and snippets.

@tcgarvin
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcgarvin/6174df7cbdf860d22955 to your computer and use it in GitHub Desktop.
Save tcgarvin/6174df7cbdf860d22955 to your computer and use it in GitHub Desktop.
House of Cards Flag

I might be a little too excited for the next season.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
div {
position: absolute;
top: 1em;
left: 1em;
}
svg {
background-color: #121212;
}
rect.union {
fill: #0F2690;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<body>
<div>
<button id="veil">Veil</button>
<button id="unveil">Unveil</button>
<button id="rightway">Correct Display</button>
<button id="wrongway">Incorrect Display</button>
</div>
</body>
<script>
var red = "#AF1600";
var white = "#FFF";
var blue = "#0F2690";
var background = "#131313";
var flagRatio = 1.9;
var stripeDuration = 250; //ms
var stripeDelay = 80; //ms
var flipDuration = 500; //ms
var width = 960;
var height = 500;
var flagHeight = height/2;
var flagWidth = width/2;
if ((flagWidth / flagHeight) < flagRatio) {
flagHeight = flagWidth / 1.9;
} else {
flagWidth = flagHeight * 1.9;
}
var stripeHeight = flagHeight / 13;
var flagDatum = { upsideDown: true, backwards: true };
var stripeData = [];
for (var i = 0; i < 13; i++) { stripeData.push({}); }
function flagTransform(upsideUp,leftToRight) {
// If we want to see a commonly recognized american flag, we're looking for
// upsideup=true and leftToRight=true. (This is slightly confused by
// the fact that the natural orientation the code creates is false,false)
// This transform is broken into a translation and scaling. The scaling
// should be thought of as a vehicle for mirroring. (If we scale an axis
// to -1, that causes a mirroring over that axis)
var upperLeftCornerX = (width / 2) - (flagWidth / 2);
var upperLeftCornerY = (height / 2) - (flagHeight / 2);
var scaleX = upsideUp ? -1 : 1;
var scaleY = leftToRight ? -1 : 1;
// If we're flipping things around, that will change the position of the
// flag, so we have to account for that.
upperLeftCornerX += (scaleX == -1) ? flagWidth : 0;
upperLeftCornerY += (scaleY == -1) ? flagHeight : 0;
return "translate("+upperLeftCornerX+","+upperLeftCornerY+")scale("+scaleX+","+scaleY+")";
}
function flagTransformTween(d,i,a) {
var targetTransform = flagTransform(d.upsideUp, d.leftToRight);
return d3.interpolateString(a, targetTransform);
}
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var flag = svg.append("g")
.datum(flagDatum)
.attr("transform",flagTransform(false,false));
flag.selectAll("rect.stripe").data(stripeData)
.enter().append("rect")
.attr("x", 0)
.attr("y", function(d,i) { return i * stripeHeight; })
.attr("height", stripeHeight)
.attr("width", 0)
.classed("stripe",true)
.style("fill", function(d,i) { return (i % 2) ? white : red });
flag.append("rect")
.attr("x", flagWidth * 0.6)
.attr("y", 6 * stripeHeight)
.attr("width", 0)
.attr("height", 7 * stripeHeight)
.classed("union", true);
function unveil() {
flag.selectAll("rect.stripe")
.transition()
.delay(function(d,i) { return i * stripeDelay })
.duration(stripeDuration)
.ease("cubic-out")
.attr("width", function(d,i) { return (i < 6) ? flagWidth : (0.6 * flagWidth); });
flag.select("rect.union")
.transition()
.delay(13 * stripeDelay + stripeDuration)
.duration(stripeDuration)
.ease("cubic-out")
.attr("width", flagWidth * 0.4);
}
function veil() {
flag.selectAll("rect.stripe")
.transition()
.delay(0)
.duration(stripeDuration)
.ease("cubic-out")
.attr("width", 0);
flag.select("rect.union")
.transition()
.delay(0)
.duration(stripeDuration)
.ease("cubic-out")
.attr("width", 0);
}
function flipTo(upsideUp, leftToRight) {
flagDatum.upsideUp = upsideUp;
flagDatum.leftToRight = leftToRight;
flag
.transition()
.duration(flipDuration)
.attrTween("transform", flagTransformTween);
}
function toCorrectDisplay() { flipTo(true, true); }
function toHalfWay() { flipTo(true, false); }
function toHouseOfCards() { flipTo(false, false); }
window.setTimeout(unveil, 500);
d3.select('#veil').on('click', veil);
d3.select('#unveil').on('click', unveil);
d3.select('#rightway').on('click', function() {
if (!flagDatum.upsideUp || !flagDatum.leftToRight) {
toHalfWay();
window.setTimeout(toCorrectDisplay, flipDuration);
}
});
d3.select('#wrongway').on('click', function() {
if (flagDatum.upsideUp || flagDatum.leftToRight) {
toHalfWay();
window.setTimeout(toHouseOfCards, flipDuration);
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment