Snippets Collections
function htmlToImage(html, { x = 0, y = 0, width = 300, height = 400 }) {
  let canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  var ctx = canvas.getContext("2d");
  return new Promise((res) => {
    var xml = toXML(html);
    xml = xml.replace(/\#/g, "%23");
    var data = `data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"><foreignObject width="100%" height="100%">${xml}</foreignObject></svg>`;

    var img = new Image();
    img.onload = function () {
      ctx.drawImage(img, x, y, width, height);
      res(canvas.toDataURL());
    };
    img.src = data;
  });
  function toXML(html) {
    var doc = document.implementation.createHTMLDocument("");
    doc.write(html);
    doc.documentElement.setAttribute("xmlns", doc.documentElement.namespaceURI);
    html = new XMLSerializer().serializeToString(doc.body);
    return html;
  }
}
async function manipulate(videoTrack, fn) {
  let canvas = document.createElement("canvas");
  let running = true;
  const ctx = canvas.getContext("2d");
  let video = document.createElement("video");
  video.setAttribute("autoplay", true);
  video.setAttribute("muted", true);
  video.srcObject = createStream(videoTrack);
  videoTrack.addEventListener("ended", () => {
    running = false;
  });
  await new Promise((res) => video.addEventListener("play", res));
  function animate() {
    const { width, height } = videoTrack.getSettings();
    Object.assign(canvas, {
      width,
      height,
    });
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    // Recursively loop
    const frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const length = frame.data.length;
    let data = frame.data;
    for (let i = 0; i < length; i += 4) {
      let o = fn({
        red: data[i],
        g: data[i + 1],
        green: data[i + 1],
        blue: data[i + 2],
        alpha: data[i + 3],
      });
      data[i] = o.red;
      data[i + 1] = o.green;
      data[i + 2] = o.blue;
      data[i + 3] = o.alpha;
    }
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.putImageData(frame, 0, 0);
    if (running) {
      requestAnimationFrame(animate);
    }
  }
  requestAnimationFrame(animate);
  let track = get("video", canvas.captureStream(30));
  track.addEventListener("ended", () => {
    running = false;
  })
}
/**
 * Generates a data URL of the current favicon with a number added on top.
 * @param {Object} options
 * @param {String} [options.type = "image/png"] The mime type of the image to return.
 * @param {String} [options.text = ""] The text to display on the favicon, if left blank will simply show a dot on the favicon.
 * @param {String} [options.background = "white"] A CSS color for the background of the notification badge.
 * @param {String} [options.color = "white"] A CSS color for the color of the text on the notification badge.
 * @param {Number} [options.size = 10] The size of the notification badge. The badge generated will be size * 2 pixels in width and height, then added on top of the current favicon.
 * @param {String} [options.pos = "bottom-right"] The position of the badge, either "bottom-right", "top-right", "bottom-left" or "top-left"
 * @param {String} [options.font = "Monospace"] The font to use
 * @param {String} [options.iconUrl] The URL of the base icon, if not provided will be the current favicon.
 * @returns {Promise.<string>} Returns a promise that resolves into the data URL of the icon generated.
 * @example
 *   getIcon({
 *     text: "1",
 *     pos: "top-right",
 *   }).then((data_url) => {
 *     document.querySelector("link[rel='icon']").href = data_url;
 *   });
 */
async function getIcon({
    type = "image/png",
    text = "",
    background = "white",
    color = "black",
    size = 10,
    pos = "bottom-right",
    font = "Monospace",
    iconUrl
}) {
    const icon = iconUrl || document.querySelector("link[rel='icon']")?.href;
    let data = await getData(icon);
    let canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    let img = await loadedImg(data);
    let notif_img = await loadedImg(getNotifData(text, size));
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
    let x = 0;
    let y = 0;
    let sections = pos.trim().toLowerCase().split("-");
    sections[0] === "bottom" && (y = canvas.height - size * 2);
    sections[1] == "right" && (x = canvas.width - size * 2);
    ctx.drawImage(notif_img, x, y);
    return canvas.toDataURL(type);

    function loadedImg(src) {
        return new Promise((res) => {
            let img = new Image();
            img.src = src;
            img.onload = () => res(img);
        });
    }

    function getNotifData(text, size) {
        const _canvas = document.createElement("canvas");
        _canvas.width = size * 2;
        _canvas.height = size * 2;
        let c = _canvas.getContext("2d");
        const inset = size;
        c.beginPath();
        c.fillStyle = background;
        c.arc(inset, inset, size, 0, 2 * Math.PI);
        c.fill();
        c.font = `${size * 1.5}px ${font}`;
        c.fillStyle = color;
        c.textBaseline = "top";
        c.fillText(text, inset / 2, inset / 2);
        return _canvas.toDataURL("image/png");
    }

    function getData(url) {
        return new Promise(async (res, reject) => {
            let blob = await fetch(url).then((r) => r.blob());
            let dataUrl = await new Promise((resolve) => {
                let reader = new FileReader();
                reader.onload = () => resolve(reader.result);
                reader.readAsDataURL(blob);
            });
            res(dataUrl);
        });
    }
}
function matrix({
	selector = "canvas",
	el = null,
	color = "#0e0",
	font = "15pt monospace",
	fps = 40,
	size = 20,
	width = null,
	height = null,
	getChar = () => String.fromCharCode(Math.random() * 128),
} = {}) {
	const canvas = el || document.querySelector(selector);
	if (window.MATRIX_INTERVAL) {
		clearInterval(window.MATRIX_INTERVAL);
	}
	const ctx = canvas.getContext("2d");
	const w = (canvas.width = width || canvas.parentElement.offsetWidth);
	const h = (canvas.height = width || canvas.parentElement.offsetHeight);
	const cols = Math.floor(w / size) + 1;
	const ypos = Array(cols).fill(0);

	// Clear it
	ctx.clearRect(0, 0, w, h);
	ctx.fillStyle = "#000";
	ctx.fillRect(0, 0, w, h);

	function _matrix() {
		ctx.fillStyle = "#0001";
		ctx.fillRect(0, 0, w, h);
		ctx.font = font;
		ypos.forEach((y, ind) => {
			const x = ind * size;
			// This is what gets passed to the functions
			let args = {
				x,
				y,
				width: w,
				height: h
			};
			const text = getChar(args);
			let col;
			if (typeof color === "function") {
				col = color(args);
			} else {
				col = color;
			}
			ctx.fillStyle = col;
			ctx.fillText(text, x, y);
			if (y > 100 + Math.random() * 10000) ypos[ind] = 0;
			else ypos[ind] = y + size;
		});
	}

	window.MATRIX_INTERVAL = setInterval(_matrix, 1000 / fps);
}

matrix({
	selector: "canvas",
	color: ({
		x,
		y,
		width,
		height
	}) => {
		// Nice diagonal gradient:
		// y / height = percentage down, toString(16) = hex char
		return `#${Math.floor((y / height) * 16).toString(16)}f${Math.floor(
			(x / width) * 16
		).toString(16)}`;
	},
	font: "8px monospace",
	fps: 20,
	size: 8,
	width: window.innerWidth,
	height: window.innerHeight,
});
star

Thu Dec 16 2021 22:58:19 GMT+0000 (UTC) https://gist.github.com/Explosion-Scratch/f37d65e14c5b05457181f349d95d7bd6

#javascript #canvas #html
star

Thu Dec 16 2021 22:57:17 GMT+0000 (UTC) https://gist.github.com/Explosion-Scratch/6ac01eb902296276347ed6755ea2a478

#javascript #canvas
star

Thu Dec 16 2021 22:56:50 GMT+0000 (UTC) https://gist.github.com/Explosion-Scratch/4c787653703cc9b3d418f19fe621d38d

#javascript #canvas
star

Thu Dec 16 2021 22:54:54 GMT+0000 (UTC) https://gist.github.com/Explosion-Scratch/4015441b00889335a43ee415d0092494

#canvas #javascript

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension