diff --git a/src/components/FavIcon.js b/src/components/FavIcon.js new file mode 100644 index 00000000..1ea4c906 --- /dev/null +++ b/src/components/FavIcon.js @@ -0,0 +1,59 @@ +import React, { useEffect, useState, forwardRef, useRef } from 'react'; + +function useInterval(callback, delay) { + const savedCallback = useRef(); + + // Remember the latest callback. + useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + // Set up the interval. + useEffect(() => { + function tick() { + savedCallback.current(); + } + if (delay !== null) { + const id = setInterval(tick, delay); + return () => clearInterval(id); + } + }, [delay]); +} + +function useWickedFavIcon() { + const letters = [...'/USES!💩']; + const [index, setIndex] = useState(0); + const canvasRef = useRef(0); + useInterval(() => { + setIndex(index >= letters.length - 1 ? 0 : index + 1); + const letter = letters[index]; + const canvas = canvasRef.current; + const ctx = canvas.getContext('2d'); + ctx.fillStyle = '#203447'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = '#ffc600'; + ctx.font = `310px monospace`; + ctx.fillText(letter, 10, canvas.height - 10); + const data = canvas.toDataURL('image/png'); + + const link = document.querySelector("link[rel*='icon']"); + link.type = 'image/x-icon'; + link.href = data; + }, 350); + return { letter: letters[index], index, canvasRef }; +} + +export default function FavIcon() { + const { letter, index, canvasRef } = useWickedFavIcon(); + return ( +
+ +
+ ); +} diff --git a/src/components/header.js b/src/components/header.js index 89e862fd..3b80b1b7 100644 --- a/src/components/header.js +++ b/src/components/header.js @@ -1,26 +1,29 @@ +import React, { useEffect, useState, useRef } from 'react'; import { Link } from 'gatsby'; import PropTypes from 'prop-types'; -import React from 'react'; import Helmet from 'react-helmet'; import styled from 'styled-components'; +import FavIcon from './FavIcon'; -const Header = ({ siteTitle }) => ( - - - {siteTitle} - -
-

- /uses -

-

- A list of /uses pages detailing developer setups, gear, - software and configs. -

-
-
-); - +function Header({ siteTitle }) { + return ( + + + + {siteTitle} + +
+

+ /uses +

+

+ A list of /uses pages detailing developer setups, gear, + software and configs. +

+
+
+ ); +} Header.propTypes = { siteTitle: PropTypes.string, };