Skip to content

Instantly share code, notes, and snippets.

View rpggio's full-sized avatar

Ryan P Smith rpggio

View GitHub Profile
@rpggio
rpggio / README.md
Last active August 29, 2015 13:58 — forked from mbostock/.block
Hex grid example

Click and drag above to paint red hexagons. A black outline will appear around contiguous clusters of red hexagons. This outline is constructed using topojson.mesh, part of the TopoJSON client API. A filter is specified so that the mesh only contains boundaries that separate filled hexagons from empty hexagons.

The hexagon grid itself is represented as TopoJSON, but is constructed on-the-fly in the browser. Since TopoJSON requires quantized coordinates, the hexagon grid is represented as integers, with each hexagon of dimensions 3×2. Then a custom projection is used to transform these irregular integer hexagons to normal hexagons of the desired size.

@rpggio
rpggio / PaperJSViewZoom.ts
Last active December 25, 2019 11:23
An implementation of pan and zoom in Paper.js, based on http://matthiasberth.com/articles/stable-zoom-and-pan-in-paperjs/. Requires jquery-mousewheel to capture wheel events.
class ViewZoom {
project: paper.Project;
factor = 1.25;
private _minZoom: number;
private _maxZoom: number;
private mouseNativeStart: paper.Point;
private viewCenterStart: paper.Point;
Verifying my Blockstack ID is secured with the address 1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh https://explorer.blockstack.org/address/1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh
Verifying my Blockstack ID is secured with the address 1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh https://explorer.blockstack.org/address/1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh
Verifying my Blockstack ID is secured with the address 1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh https://explorer.blockstack.org/address/1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh
Verifying my Blockstack ID is secured with the address 1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh https://explorer.blockstack.org/address/1EbxrkJezeMR8LqeKVVBGoSfzA6MbrwfRh
@rpggio
rpggio / GoogleDocFrame.tsx
Last active June 21, 2024 09:32
Automatic retry for iframe loading (workaround for Google Doc Viewer 204 issue)
function GoogleDocFrame({ url }: { url: string }) {
const frameRef = useRef<HTMLIFrameElement>(null)
const viewerUrl = `https://docs.google.com/viewer?embedded=true&url=${url}`
let cancel: () => void | undefined
useEffect(() => {
cancel = setFrameSrcWithRetry(frameRef.current!, viewerUrl, true)
// unmount
return () => {
if (cancel) {
@rpggio
rpggio / ComplexKeyedMap.ts
Created October 27, 2020 02:39
Generic Map with complex key, in TypeScript
export function ComplexKeyedMap<K, V>(
formatter: StringFormatter<K>,
entries?: readonly (readonly [K, V])[] | null
): Map<K, V> {
const map = new Map<string, V>(
entries?.map(([k, v]) => [formatter.asString(k), v])
)
function* getEntries() {
@rpggio
rpggio / ReactiveMap.ts
Created October 27, 2020 02:56
Reactive Map that can be subscribed, such as by React hooks
export function ReactiveMap<K, V>(map: Map<K, V>): ReactiveMap<K, V> {
const subscribers = new Set<Subscriber<MapState<K, V>>>()
function notify() {
const state: MapState<K, V> = [Array.from(map.entries()), map]
subscribers.forEach(subscriber => subscriber(state))
}
function unsubscribe(subscriber: Subscriber<MapState<K, V>>) {
@rpggio
rpggio / store.ts
Last active November 5, 2020 22:14
Basic reactive store
import type { Reactive, Subscriber, Store } from './types'
export function Store<S>(initial: S): Store<S> {
let current = initial
const subscribers = new Set<Subscriber<S>>()
function subscribe(subscriber: Subscriber<S>) {
subscribers.add(subscriber)
return () => unsubscribe(subscriber as VoidFunction)
}