Skip to content

Instantly share code, notes, and snippets.

@veltman
veltman / README.md
Created September 2, 2017 12:31
SVG animation to video

Converting an SVG animation to a video with the MediaRecorder API and a hidden canvas.

Drawing frames from img elements can introduce an extra delay, so this version generates all the frames upfront and then renders them in a loop with requestAnimationFrame().

See also: Canvas animation to video

@veltman
veltman / README.md
Last active February 17, 2026 14:05
Stippling #2

Another attempt at stippling with a more basic relaxation approach but using multiple dot sizes to add texture.

  1. Position starting points with rejection sampling, using the grayscale image as the density function.
  2. Use Lloyd's algorithm to get a relaxed Voronoi diagram from the starting points.
  3. Size the dots based on the darkness of the pixel at their position, then shrink them as much as necessary to avoid collisions - this could be done all at once but it seems to produce some splotchy artifacts, so instead they're shrunk a little bit at a time.

The heavy computation is done in a web worker to avoid locking up the page, and takes about 15-20 seconds to complete.

See also: Voronoi relaxation, Stippling, Philippe Rivière's CCPD Snowden

@veltman
veltman / README.md
Last active December 19, 2025 13:35
Responsive SVG with sticky text

Keeping text size sticky while making an SVG responsive with viewBox.

  1. Set the SVG's viewBox to its original width and height, and its width to 100%, so it fills its container.
  2. On resize, find out the SVG's new width.
  3. Update the SVG's height to preserve the aspect ratio.
  4. Use transform to scale up the text by the inverse. For example, if the new width is 2/3 of the original, make the text 3/2 scale.

Instead of keeping the text size fixed, you could constrain it to some other range so that it shrinks but more slowly than the rest of the SVG. For example:

var textScaleFactor = d3.scale.linear()

@veltman
veltman / README.md
Last active December 5, 2025 01:53
Old atlas style #3
@veltman
veltman / README.md
Last active November 25, 2025 11:25
Departures board
@veltman
veltman / README.md
Last active April 3, 2025 15:41
Sunburst to icicle #2

Transitioning between a sunburst and an icicle chart while preserving the chart dimensions by interpolating the difference in perimeter between the inner section and outer section until the difference is near zero.

Chrome currently has a rendering bug once the arcs' radii get really extreme, so this stops at about an 8-pixel difference.

@veltman
veltman / README.md
Last active January 18, 2025 16:17
Redistricting

Old vs. new proposed North Carolina congressional districts, data via WRAL.

Polygons were pre-processed for gentler animation as follows:

  1. For each district, find the difference n in the number of vertices between the old and new district.
  2. Add n vertices to whichever one has fewer, evenly spaced along the existing polyline, so the old and new shape each have the same number of vertices (not great for performance).
  3. For each pair of old/new district, wind the old district around to minimize the sum of the squared distances between point index i in the old district and point index i in the new district.
@veltman
veltman / premorph.js
Last active January 18, 2025 16:17
Morph pre-processing
var oldDistricts = require("./old-raw.geo.json"),
newDistricts = require("./new-raw.geo.json"),
_ = require("underscore"),
turf = require("turf"),
fs = require("fs");
// Clean up GeoJSON, sort districts in order
prep(oldDistricts);
prep(newDistricts);
@veltman
veltman / README.md
Last active October 5, 2024 15:25
Pencil/watercolor map style

Trying for a pencil/watercolor sort of effect. Each state is blurred and clipped to itself to create a stroke that bleeds inward. Turbulence and displacement filters muss the borders a little, and some line interpolation rounds the corners.

Chrome, Firefox, and Safari each apply the filters very differently!

See also: Pencil sketch, Colorized atlas style

US TopoJSON via Mike Bostock

@veltman
veltman / README.md
Last active September 22, 2024 09:20
Gif rendering - SVG to GIF

Testing in-browser gif generation from an SVG with gif.js. Works in recent Chrome/Safari/Firefox.

Process:

  1. Create a standard SVG line chart.
  2. Step through in-between frames of the line chart: for each one, update the SVG, render to an image, add the image element to a stack of gif frames.
  3. Render frames together in the background using gif.js web workers.
  4. When rendering's complete, add the blob URL as an image and start the SVG on an infinite loop with d3.timer (gratuitous).

See also: Gif Globe, Gif New Jersey