Strange game. The only way to win is not to play.
xxxxxxxxxx
<html>
<head>
<title>Strange Game</title>
<meta charset="utf-8" />
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-geo-projection.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="d3.sketchy.js"></script>
<script src="cheapMarky.js"></script>
</head>
<style>
body {
background: black;
}
svg {
height: 1000px;
width: 1280px;
border: none;
}
.countries {
fill: $443636;
stroke: none;
}
</style>
<body>
<div id="viz">
<svg>
</svg>
</div>
<div id="controls" />
</body>
<footer>
<script>
var colorScale = d3.scaleOrdinal().range(["#f8a313", "#a5c4c5", "#bab218", "#f0d976", "#e8381b", "#ee791e"]);
var filter = d3.select("svg").append("defs").append("filter").attr("id", "gooeyCodeFilter");
filter.append("feGaussianBlur").attr("id", "gaussblurrer").attr("in", "SourceGraphic").attr("stdDeviation", 4).attr("color-interpolation-filters", "sRGB").attr("result", "blur");
filter.append("feColorMatrix").attr("in", "blur").attr("mode", "matrix").attr("values", "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 34 -7").attr("result", "gooey");
var svg = d3.select("svg");
d3.select("svg").append("g").attr("class", "bg")
d3.select("svg").append("g").attr("class", "fill")
.style("filter", "url(#gooeyCodeFilter)")
d3.select("svg").append("g").attr("class", "border")
d3.select("svg").append("g").attr("class", "explosions")
.style("filter", "url(#gooeyCodeFilter)")
var sketchy = d3sketchy();
var projection = d3.geoArmadillo()
.scale(300)
.translate([600, 360])
.parallel(20)
.rotate([-12, 0])
.precision(.1);
var geoPath = d3.geoPath().projection(projection);
var line = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
var numSides = 6
var sources
var countries
var sideHash
d3.json("simpleworld.json", createMap);
var powers = ["USA", "RUS", "CHN", "ISR", "IND", "PAK", "GBR", "FRA"]
function createMap(world) {
countries = topojson.feature(world, world.objects.world);
renderMap(countries, projection)
}
function renderMap(countries, projection) {
sideHash = {}
countries.features = countries.features.filter(function (d) {return d.id !== "ATA"})
countries.features.forEach(function (d) {
sideHash[d.id] = parseInt(Math.random() * numSides)
})
sources = countries.features.filter(function (p) {return powers.indexOf(p.id) !== -1})
d3.select("g.bg")
.selectAll("path")
.data(countries.features)
.enter()
.append("path")
.attr("d", geoPath)
.attr("class", "countries")
.each(function (d, i) {
d.centroid = geoPath.centroid(d)
var originalNode = this;
d.geometry.coordinates.forEach(function (p) {
if (p.length < 2) {
p = p[0];
}
var projectedArea = [];
p.forEach(function (coordinate) {
var proj = projection(coordinate);
projectedArea.push({x: proj[0], y: proj[1]});
})
sketchy.pathStroke({svg: d3.select("g.border"), path:projectedArea, density:3, sketch:2, stroke: colorScale(sideHash[d.id]), strokeWidth: "2px"});
})
})
d3.select("g.fill").selectAll("path")
.attr("stroke-dasharray", function () {return "0," + this.getTotalLength()})
.transition()
.delay(function (d,i) {return i * 10})
.transition()
.duration(500)
.attrTween("stroke-dasharray", tweenDash);
d3.select("g.border").selectAll("path")
.style("fill", "none")
.attr("stroke-dasharray", function () {return "0," + this.getTotalLength()})
.transition()
.delay(function (d,i) {return i * 10})
.transition()
.duration(500)
.attrTween("stroke-dasharray", tweenDash);
nuke()
}
function nuke() {
d3.select("svg")
.selectAll("path.nukelines")
.data(d3.range(100))
.enter()
.append("path")
.attr("class", "nukelines")
.each(function (d,i) {
var p1 = parseInt(Math.random() * sources.length)
var targets = countries.features.filter(function (p) {return sideHash[p.id] !== sideHash[sources[p1].id]})
var p2 = parseInt(Math.random() * targets.length)
var x1 = sources[p1].centroid[0] + (Math.random() * 30) - 15
var y1 = sources[p1].centroid[1]
var x2 = targets[p2].centroid[0] + (Math.random() * 50) - 25
var y2 = targets[p2].centroid[1] + (Math.random() * 50) - 25
var delay = i < 10 ? 2000 + i * 150 : 3500 + i * 10
d3.select(this)
.attr("d", "M" + x1 + "," + y1 + " S" + ((x1 + x2)/2) + "," + ((y1 + y2)/2 - 200) + " " + x2 + "," + y2)
.style("fill", "none")
.style("stroke", d3.rgb(colorScale(sideHash[sources[p1].id])).brighter(.25))
.style("stroke-width", 1)
.style("stroke-dasharray", "0 " + this.getTotalLength())
.transition()
.delay(delay)
.transition()
.duration(1000)
.style("stroke-dasharray", this.getTotalLength() + " 0")
createExplosion(x2, y2, delay + 500, d3.rgb(colorScale(sideHash[sources[p1].id])).brighter(.5))
})
setTimeout(function(){ d3.selectAll("g.blast").remove(); d3.selectAll("path.nukelines").remove(); nuke() }, 8000);
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) { return i(t); };
}
function cheapSketchy(path) {
var length = path.getTotalLength();
var drawCode = "";
var x = 0;
var step = 2.5;
while (x < length / 2) {
var start = path.getPointAtLength(x);
var end = path.getPointAtLength(length - x);
drawCode += " M" + (start.x + (Math.random() * step - step/2)) + " " + (start.y + (Math.random() * step - step/2)) + "L" + (end.x + (Math.random() * step - step/2)) + " " + (end.y + (Math.random() * step - step/2));
x += step + (Math.random() * step);
}
return drawCode;
}
function createExplosion(x, y, delay, color) {
var explosionG = d3.select("g.explosions")
.append("g")
.attr("class", "blast")
.attr("transform", "translate(" + x + "," + y + ")" )
.style("filter", "url(#gooeyCodeFilter)")
explosionG
.append("path")
.style("fill", "none")
.style("stroke", "none")
.attr("d", circlePath(20))
explosionG
.each(function (d,i) {
var artCircles = cheapPopArtsy(d3.select(this).select("path").node())
d3.select(this)
.selectAll("circle")
.data(artCircles)
.enter()
.append("circle")
.attr("r", 0)
.style("fill", color)
})
var artBarTransition = explosionG
.transition()
.delay(delay)
artBarTransition
.selectAll("circle")
.transition()
.delay(function (d) {return Math.abs(d[0] + d[1])})
.transition()
.duration(100)
.attr("r", function () {return Math.random() * 5})
.attr("cx", function (d) {return d[0]})
.attr("cy", function (d) {return d[1]})
}
</script>
</footer>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-geo-projection.v1.min.js
https://d3js.org/topojson.v1.min.js