Skip to content

Instantly share code, notes, and snippets.

View JoostKiens's full-sized avatar

Joost Kiens JoostKiens

View GitHub Profile
@JoostKiens
JoostKiens / test2.json
Last active October 10, 2023 17:45
Flypath of Black-tailed godwit, last 2 years, from https://www.globalflywaynetwork.org/
[
{
"from": {
"pos": [
153.43916,
-29.50063
],
"time": "2021-10-03 07:26:23"
},
"to": {
@JoostKiens
JoostKiens / useScroll.jsx
Created June 13, 2019 16:14
React useScroll hook (window scrolling) returns scrollX & scrollY, with context provider
import React from 'react'
const ScrollContext = React.createContext(null)
export function useScroll() {
const scroll = React.useContext(ScrollContext)
if (!scroll)
throw new Error('Please make sure ScrollContextProvider is available')
return scroll
@JoostKiens
JoostKiens / useCookies.jsx
Created June 13, 2019 16:12
React useCookies hook with context provider
import React from 'react'
import Cookies from 'js-cookie'
const CookiesContext = React.createContext(null)
export function useCookies() {
const cookies = React.useContext(CookiesContext)
if (!cookies)
throw new Error('Please make sure CookiesContextProvider is available')
return cookies
@JoostKiens
JoostKiens / createUVWGrid.js
Created January 17, 2019 08:47
Create a 3D grid in uvw coordinates for THREE.js (pure function, no loops)
const createUVWGrid = ([cx, cy, cz]) => {
return times(cx).map(x => times(cy).map((y) => times(cz).map(z =>
new THREE.Vector3(
cx <= 1 ? 0.5 : x / (cx - 1),
cy <= 1 ? 0.5 : y / (cy - 1),
cz <= 1 ? 0.5 : z / (cz - 1)
)
))).flat(2)
}
function autoplayVideoSupported(muted = true, playsinline = true) {
const v = document.createElement('video')
v.muted = muted
playsinline && v.setAttribute('playsinline', 'playsinline')
v.setAttribute('width', 0)
v.setAttribute('height', 0)
v.style.opacity = 0
document.querySelector('body').appendChild(v)
return new Promise((resolve, reject) => {
v.play()
@JoostKiens
JoostKiens / preloadVideo.js
Last active October 9, 2018 08:15
Preload entire video using fetch, returns promise
// Preloads entire video, returns promise
// NOTE: if a video doesn't exist the fetch will resolve,
// but with a Blob type of `plain/text`
function preloadVideo(src) {
return new Promise((resolve, reject) => {
fetch(src)
.then(response => response.blob())
.then(blob =>
/^video\/\w*/.test(blob.type)
? resolve(URL.createObjectURL(blob))
@JoostKiens
JoostKiens / preventPullDownRefresh.js
Last active October 6, 2019 00:20
Prevent pull down refresh on Chrome browser on iOS
const target = window
let lastY = 0
target.addEventListener('touchmove', handleTouchMove)
function handleTouchMove(e) {
const { pageY } = e.changedTouches[0]
const scrollY = target.pageYOffset || target.scrollTop || 0
if (pageY > lastY && scrollY === 0) {
e.preventDefault()
@JoostKiens
JoostKiens / customSelectArrow.css
Last active August 23, 2017 12:47
Remove default browser select arrow, replace with background image
select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCAxNSAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPHBhdGggZD0iTTEyLjUgMi41bC00LjkgNS01LjEtNSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2U9IiMyMTFEMUUiIGZpbGw9Im5vbmUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPg0KPC9zdmc+');
background-position: calc(100% - 10px) center;
background-repeat: no-repeat;
padding-left: 10px;
padding-right: 20px; /* prevent text from going under background image */
text-overflow: ellipsis;
@JoostKiens
JoostKiens / convertSVGCircleToPathDescription.js
Created August 23, 2017 08:14
Convert SVG circle arguments to path description
function createPathDFromCircle(cx, cy, r) {
return `d="
M ${cx} ${cy}
m -${r}, 0
a ${r},${r} 0 1,0 ${(r * 2)},0
a ${r},${r} 0 1,0 ${-(r * 2)},0
"`
}
function createPathDFromCircleStartOnTop(cx, cy, r) {
@JoostKiens
JoostKiens / numberTransition.js
Created August 20, 2017 10:07
Transition numbers over time with easing
/*
Options
---
{
from: 1, // <Number> start number, default: 0
to: 100, // <Number> end number, required
duration: 1000, // <Number> total duration on transition, required
step: console.log, // <Function> function to execute on each update, receives current number as argument, required
ease: x => x, // <Function> custom easing function, default: linear
tick: fn => window.setTimeout(fn, 20) // <Function> ticker, default: requestAnimationFrame