add face light
This commit is contained in:
parent
293e7d46d8
commit
6cda2a5bc8
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright © 2020 Neale Pickett
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
The software is provided "as is", without warranty of any kind,
|
||||
express or implied, including but not limited to the warranties of
|
||||
merchantability, fitness for a particular purpose and
|
||||
noninfringement. In no event shall the authors or copyright holders
|
||||
be liable for any claim, damages or other liability, whether in an
|
||||
action of contract, tort or otherwise, arising from, out of or in
|
||||
connection with the software or the use or other dealings in the
|
||||
software.
|
|
@ -0,0 +1,7 @@
|
|||
This is a HTML5 doodad that lets you screencast with your face on top.
|
||||
|
||||
It saves videos locally as `.webm` files.
|
||||
|
||||
You can move your face around, zoom in to a region of the screen,
|
||||
I guess this is enough for my needs.
|
||||
Maybe it'll be enough for yours.
|
|
@ -0,0 +1,12 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
img.icon {
|
||||
max-height: 2em;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
function colorTemperatureToRGB(kelvin) {
|
||||
// https://gist.github.com/paulkaplan/5184275
|
||||
|
||||
let temp = kelvin / 100
|
||||
let red, green, blue
|
||||
|
||||
if (temp <= 66) {
|
||||
red = 255
|
||||
green = temp
|
||||
green = 99.4708025861 * Math.log(green) - 161.1195681661
|
||||
if (temp <= 19) {
|
||||
blue = 0
|
||||
} else {
|
||||
blue = temp-10
|
||||
blue = 138.5177312231 * Math.log(blue) - 305.0447927307
|
||||
}
|
||||
} else {
|
||||
red = temp - 60
|
||||
red = 329.698727446 * Math.pow(red, -0.1332047592)
|
||||
|
||||
green = temp - 60
|
||||
green = 288.1221695283 * Math.pow(green, -0.0755148492)
|
||||
|
||||
blue = 255
|
||||
}
|
||||
|
||||
return {
|
||||
r : clamp(red, 0, 255),
|
||||
g : clamp(green, 0, 255),
|
||||
b : clamp(blue, 0, 255),
|
||||
}
|
||||
}
|
||||
|
||||
function clamp(x, min, max) {
|
||||
if (x<min) {return min}
|
||||
if (x>max) {return max}
|
||||
return x
|
||||
}
|
||||
|
||||
function changeTemp(e) {
|
||||
let tempIn = document.querySelector("#temp")
|
||||
let tempOut = document.querySelector("#tempOut")
|
||||
let temp
|
||||
if (!e) {
|
||||
temp = localStorage.temp || 5500
|
||||
} else if (e.target) {
|
||||
temp = Number(e.target.value)
|
||||
} else {
|
||||
temp = e
|
||||
}
|
||||
|
||||
let color = colorTemperatureToRGB(temp)
|
||||
document.body.style.backgroundColor = "rgb(" + color.r + "," + color.g + "," + color.b + ")"
|
||||
tempOut.textContent = temp
|
||||
tempIn.value = temp
|
||||
localStorage.temp = temp
|
||||
}
|
||||
|
||||
function init() {
|
||||
document.querySelector("#temp").addEventListener("input", changeTemp)
|
||||
changeTemp()
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", init)
|
||||
} else {
|
||||
init()
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg height="300px" width="300px" fill="#000000" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0,-952.36218)">
|
||||
<path style="text-indent: 0px; text-transform: none; direction: ltr; baseline-shift: baseline; color: rgb(0, 0, 0); fill: rgb(255, 214, 170);" d="M 50 972.362 C 36.253 972.362 23 983.059 23 998.206 C 23 1007.637 26.736 1013.748 30.063 1018.456 C 33.39 1023.164 36 1026.353 36 1031.362 L 64 1031.362 C 64 1026.353 66.611 1023.164 69.938 1018.456 C 73.265 1013.748 77 1007.637 77 998.206 C 77 983.059 63.747 972.362 50 972.362 Z" fill-opacity="1" stroke="none" marker="none" visibility="visible" display="inline" overflow="visible" transform="matrix(1, 0, 0, 1, 0, -0.000012)"/>
|
||||
<path style="text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;color:#000000;enable-background:accumulate;" d="m 50,954.36216 c -1.6568,0 -3,1.3432 -3,3 l 0,8 c 0,1.65689 1.3432,3 3,3 1.6569,0 3,-1.34311 3,-3 l 0,-8 c 0,-1.6568 -1.3431,-3 -3,-3 z m -28.2812,11.71875 c -0.7679,0 -1.5392,0.2892 -2.125,0.875 -1.1715,1.1715 -1.1715,3.0786 0,4.25 l 5.6562,5.65625 c 1.1716,1.1716 3.0785,1.1715 4.25,0 1.1716,-1.1716 1.1716,-3.0784 0,-4.25 l -5.6562,-5.65625 c -0.5859,-0.5858 -1.3573,-0.875 -2.125,-0.875 z m 56.5624,0 c -0.7677,0 -1.5391,0.2892 -2.125,0.875 L 70.5,972.61216 c -1.1716,1.1716 -1.1716,3.0784 0,4.25 1.1715,1.1715 3.0784,1.1716 4.25,0 l 5.6562,-5.65625 c 1.1715,-1.1714 1.1715,-3.0785 0,-4.25 -0.5858,-0.5858 -1.3571,-0.875 -2.125,-0.875 z M 50,972.36216 c -13.7469,0 -27,10.69721 -27,25.84375 0,9.43059 3.7355,15.54199 7.0625,20.24999 3.327,4.7081 5.9375,7.8975 5.9375,12.9063 l 0,12 c 0,3.9425 3.2767,7 7,7 l 14,0 c 3.7233,0 7,-3.0575 7,-7 l 0,-12 c 0,-5.0088 2.6105,-8.1982 5.9375,-12.9063 C 73.2645,1013.7479 77,1007.6365 77,998.20591 77,983.05937 63.7469,972.36216 50,972.36216 z m 0,6 c 10.6435,0 21,8.22569 21,19.84375 0,7.93329 -2.7645,12.29119 -5.9375,16.78129 -2.7053,3.8283 -5.9202,7.8467 -6.8125,13.375 l -16.5,0 c -0.8923,-5.5283 -4.1072,-9.5467 -6.8125,-13.375 C 31.7645,1010.4971 29,1006.1392 29,998.20591 29,986.58785 39.3565,978.36216 50,978.36216 z m -4.7188,3 c -0.4269,-0.0154 -0.8833,0.0424 -1.3437,0.15625 -6.5086,2.45426 -11.381,8.18679 -12.625,15.1875 -0.2702,1.55449 0.883,3.23 2.4375,3.49999 1.5546,0.27 3.2302,-0.91409 3.5,-2.46879 0.8714,-4.90431 4.2667,-8.91082 8.8125,-10.62495 1.3034,-0.4846 2.1492,-1.97456 1.9063,-3.34375 -0.3606,-1.67919 -1.4068,-2.36015 -2.6876,-2.40625 z M 10,994.36211 c -1.6568,0 -3,1.3431 -3,3 0,1.6568 1.3432,2.99999 3,2.99999 l 8,0 c 1.6569,0 3,-1.34319 3,-2.99999 0,-1.6569 -1.3431,-3 -3,-3 l -8,0 z m 72,0 c -1.6569,0 -3,1.3432 -3,3 0,1.65689 1.3431,2.99999 3,2.99999 l 8,0 c 1.6568,0 3,-1.3431 3,-2.99999 0,-1.6568 -1.3432,-3 -3,-3 l -8,0 z m -40,40.00009 16,0 0,2 -16,0 0,-2 z m 0,8 16,0 0,1 c 0,0.6537 -0.5023,1 -1,1 l -14,0 c -0.4977,0 -1,-0.3463 -1,-1 l 0,-1 z" fill="#000000" fill-opacity="1" stroke="none" marker="none" visibility="visible" display="inline" overflow="visible"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Face Light</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="icon" href="app.svg">
|
||||
<link rel="stylesheet" href="app.css">
|
||||
<script src="app.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<img class="icon" src="app.svg">
|
||||
<input type="range" min=3200 max=6500 class="slider" id="temp">
|
||||
<span id="tempOut"></span>
|
||||
K
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "Face Light",
|
||||
"short_name": "Face Light",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#000",
|
||||
"theme_color": "#ffd6aa",
|
||||
"description": "Lights up your face.",
|
||||
"icons": [
|
||||
{
|
||||
"src": "app.svg",
|
||||
"sizes": "196x196"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// jshint asi:true
|
||||
|
||||
var cacheName = "v2";
|
||||
var content = [
|
||||
"index.html",
|
||||
"app.js",
|
||||
"app.png",
|
||||
]
|
||||
|
||||
|
||||
self.addEventListener("install", preCache)
|
||||
self.addEventListener("fetch", cachingFetch)
|
||||
self.addEventListener("activate", handleActivate)
|
||||
|
||||
function handleActivate(event){
|
||||
event.waitUntil(
|
||||
cleanup()
|
||||
)
|
||||
}
|
||||
|
||||
async function cleanup(event) {
|
||||
let cacheNames = await caches.keys()
|
||||
for (let name of cacheNames) {
|
||||
if (name != cacheName) {
|
||||
console.log("Deleting old cache", name)
|
||||
caches.delete(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function preCache(event) {
|
||||
event.waitUntil(
|
||||
caches.open(cacheName)
|
||||
.then(cache => cache.addAll(content))
|
||||
)
|
||||
}
|
||||
|
||||
// Go try to pull a newer version from the network,
|
||||
// but return what's in the cache for this request
|
||||
function cachingFetch(event) {
|
||||
fetch(event.request)
|
||||
.then(resp => {
|
||||
caches.open(cacheName)
|
||||
.then(cache => {
|
||||
cache.put(event.request, resp.clone())
|
||||
})
|
||||
})
|
||||
|
||||
event.respondWith(caches.match(event.request))
|
||||
}
|
|
@ -5,8 +5,12 @@ title: Toys
|
|||
Here is some various junk I've done. Maybe you'll find it amusing.
|
||||
Maybe you'll just wonder why I spend so much time on this garbage.
|
||||
|
||||
* [Convulse Screen Recorder](convulse/), a pure HTML5 screen recorder, with webcam overlay
|
||||
* [Convulse Screen Recorder](convulse/)
|
||||
(web app) a screen recorder, with webcam overlay.
|
||||
* [Face Light](facelight/)
|
||||
(web app) turn your monitor into a light, to improve your appearance in video calls.
|
||||
* [Starship Noise Generator](starship/)
|
||||
(web app) generate some background noise if your workspace is too quiet.
|
||||
* [Grep Dict](grepdict/) runs `grep` on `/usr/share/dict/words`; perfect for cheating on crossword puzzles
|
||||
* If you need to write someone a letter but really don't want to, try my
|
||||
[social letter generator](letter.html)
|
||||
|
|
Loading…
Reference in New Issue