Skip to content

Instantly share code, notes, and snippets.

View thomaswilburn's full-sized avatar
🦝

Thomas Wilburn thomaswilburn

🦝
View GitHub Profile
@thomaswilburn
thomaswilburn / zip-it.md
Last active April 18, 2024 11:56
Exploring generators and iteration through zip()

Win zip()

I don't often use zip(), but by coincidence this week I ran into it a few times, using both Python and JavaScript. In the former, it's a built-in, but in the latter it's typically provided by a library like D3. And it struck me as kind of a fun warm-up challenge. How would you write this function in modern JavaScript?

Well, let's see how D3 does it. Oh, it's a wrapper around transpose(), here we go...

import min from "./min.js";

function length(d) {
@thomaswilburn
thomaswilburn / index.js
Created December 5, 2023 21:04
Classy signals
var tracking = [];
var pending = new Set();
function anticipate(fn) {
pending.add(fn);
requestAnimationFrame(() => {
for (var p of pending) p();
pending.clear();
});
}
@thomaswilburn
thomaswilburn / pigeon.js
Last active March 28, 2024 21:53
Convert CSS to nested CSS
import { parse } from "https://deno.land/x/css@0.3.0/mod.ts";
var file = Deno.args[0];
var input = await Deno.readTextFile(file);
var parsed = parse(input, { value: true });
var root = {
rules: [],
@thomaswilburn
thomaswilburn / import-ants.js
Last active February 20, 2024 21:34
Async imports for CSS files
var links = document.querySelectorAll(`link[rel="stylesheet"][media="async"], link[rel="async-styles"]`);
for (var link of links) {
var resolved = new URL(link.href, window.location);
var processed = await getSheet(resolved.toString());
var style = document.createElement("style");
var constructed = new CSSStyleSheet();
var output = serializeCSS(processed);
constructed.replaceSync(output);
// console.log(output);
@thomaswilburn
thomaswilburn / writeup.md
Last active January 16, 2024 03:33
Creating a document minimap with SVG

One of my favorite no-so-secret weapons for data visualization on the web is the SVG viewBox attribute. I've written about it before: in my textbook, I have a whole chapter on art direction with viewBox, and I also talk about it in the section on rendering SVG from JS.

Essentially, the viewBox attribute lets you set up the... view box. SVG works on a 2d coordinate system that can (but doesn't have to) match the CSS positioning grid for an element. You can use the attribute to tell the SVG to set an offset for the rendering canvas, to zoom in or out, or to crop the image to keep an area in view while still fitting in an arbitrary aspect ratio (similar to how object-fit and object-position work in CSS, but more granular).

But on a recent project, I also had a chance to use viewBox as a literal view box: for a [Votebeat story](https://arizona.votebeat.org/2022/10/18/23410059/ma

@thomaswilburn
thomaswilburn / blanks.html
Last active December 15, 2023 01:07
Fill In The Blanks
<!doctype html>
<style>
.card {
display: grid;
grid-template-columns: 1fr 2fr;
& img {
max-height: 200px;
}
}
@thomaswilburn
thomaswilburn / defaultdict.js
Created December 12, 2023 22:35
Defaultdict but make it JavaScript
const TARGET = Symbol("proxy target");
function defaultdict(missing) {
var dict = {};
var instantiate = missing;
if (missing instanceof Function) {
if (missing.constructor) {
instantiate = () => new missing();
}
} else if (missing instanceof Object) {
@thomaswilburn
thomaswilburn / index.js
Created December 11, 2023 17:50
ReactiveStore
var proxyRegistry = new WeakMap();
function observe(root, callback) {
var handler = {
get(target, property, rec) {
var value = target[property];
if (value instanceof Object && !(value instanceof Function)) {
if (proxyRegistry.has(value)) {
return proxyRegistry.get(value);
}
@thomaswilburn
thomaswilburn / index.html
Created December 3, 2023 03:39
Benchmark Lit iteration vs. replaceChildren
<!doctype html>
<ul id="ul"></ul>
<script type="module">
import { html, render } from "https://unpkg.com/lit-html";
import { repeat } from "https://unpkg.com/lit-html/directives/repeat.js";
import { map } from "https://unpkg.com/lit-html/directives/map.js";
function replacer(container, data, factory, update = () => {}) {
@thomaswilburn
thomaswilburn / datapatcher.js
Last active November 30, 2023 18:56
Update DW graphics from a Google Sheet
// run with deno run --allow-all datapatcher.js {SHEET_ID} {SHEET_TAB (optional)}
import { login, google } from "https://raw.githubusercontent.com/Chalkbeat/deno-google-login/main/index.js";
import * as flags from "https://deno.land/std@0.208.0/flags/mod.ts";
var args = flags.parse(Deno.args);
var spreadsheetId = args.sheet || args._[0];