Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active October 26, 2022 18:53
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 HarryStevens/2d51280d0f268f8e9dda1b9f72bbc798 to your computer and use it in GitHub Desktop.
Save HarryStevens/2d51280d0f268f8e9dda1b9f72bbc798 to your computer and use it in GitHub Desktop.
Isometric Grid Transition
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
svg {
display: table;
margin: 0 auto;
}
line {
stroke-width: 4px;
}
path {
fill: none;
}
.cell {
stroke: #eee;
}
.outline {
stroke: #000;
stroke-width: 2px;
}
</style>
</head>
<body>
<script type="module">
import { cross, range } from "https://cdn.skypack.dev/d3-array@3";
import { geoEquirectangular, geoPath } from "https://cdn.skypack.dev/d3-geo@3";
import { randomUniform } from "https://cdn.skypack.dev/d3-random@3";
import { interpolateSinebow } from "https://cdn.skypack.dev/d3-scale-chromatic@3";
import { select } from "https://cdn.skypack.dev/d3-selection@3";
import { interval } from "https://cdn.skypack.dev/d3-timer@3";
import { transition } from "https://cdn.skypack.dev/d3-transition@3";
const { cos, PI, round, sin } = Math;
const i = 0.4;
const r = range(-1, 1, i);
const cells = {
type: "FeatureCollection",
features: cross(r, r)
.map(([lon, lat]) => ({
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[lon, lat],
[lon, lat + i],
[lon + i, lat + i],
[lon + i, lat],
[lon, lat]
]
]
}
}))
};
const x = n => round(cos(n));
const y = n => round(sin(n));
const random = randomUniform(-1, 1);
const data = Array.from({ length: 250 }).map(d => ([random(), random()]));
const square = [ range(1, PI * 2.5, PI * 0.25).map(n => [x(n), y(n)]) ];
const margin = {left: 1, right: 1, top: 30, bottom: 1};
const size = 400;
const projection = geoEquirectangular()
.reflectY(true)
.fitSize([size, size], cells);
const path = geoPath(projection);
const svg = select("body").append("svg")
.attr("width", size + margin.left + margin.right)
.attr("height", size + margin.top + margin.bottom);
const g = svg.append("g")
.attr("transform", `translate(${[margin.left, margin.top]})`);
const cell = g.selectAll(".cell")
.data(cells.features)
.join("path")
.attr("class", "cell")
.attr("d", path);
const outline = g.append("path")
.attr("class", "outline")
.datum({
type: "Polygon",
coordinates: square
})
.attr("d", path);
const line = g.selectAll("line")
.data(data)
.join("line")
.attr("stroke", (d, i, e) => interpolateSinebow(i / e.length))
.attr("y2", -margin.top + 1)
.attr("transform", d => `translate(${projection(d)})`);
let rotation = [0, 0, 0];
draw(rotation);
interval(() => {
rotation = rotation[0] ? [0, 0, 0] : [30, -60, 0];
draw(rotation)
}, 2e3);
function draw(rotation){
projection
.rotate(rotation)
.fitSize([size, size], cells);
cell
.transition()
.duration(1e3)
.attr("d", path);
outline
.transition()
.duration(1e3)
.attr("d", path);
line
.transition()
.duration(1e3)
.attr("transform", d => `translate(${projection(d)})`);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment