chore: normalize line endings and remove gitignore - webgbcam - [fork] gameboy webcam
HTML git clone git://src.adamsgaard.dk/webgbcam
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit e49591b1954c1eae6ff4fe280185a475bb8180e2
DIR parent 6335cc127af852aa1af7f5ca6ee91bde91291dc4
HTML Author: Anders Damsgaard <anders@adamsgaard.dk>
Date: Sat, 14 Feb 2026 16:34:19 +0100
chore: normalize line endings and remove gitignore
Diffstat:
D .gitignore | 6 ------
M index.html | 176 ++++++++++++++++----------------
M manifest.webmanifest | 28 ++++++++++++++--------------
M style.css | 330 ++++++++++++++++----------------
M sw.js | 122 ++++++++++++++++----------------
5 files changed, 328 insertions(+), 334 deletions(-)
---
DIR diff --git a/.gitignore b/.gitignore
@@ -1,5 +0,0 @@
-*.aseprite
-todo.txt
-key.pem
-server.pem
-simple-https-server.py
-\ No newline at end of file
DIR diff --git a/index.html b/index.html
@@ -1,89 +1,89 @@
-<!doctype html>
-<html lang=”en”>
-<head>
- <meta charset="utf-8">
- <meta http-equiv="x-ua-compatible" content="ie=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>webgbcam</title>
- <link rel="stylesheet" href="style.css">
- <link rel="manifest" href="manifest.webmanifest">
-
- <meta property="og:title" content="webgbcam">
- <meta property="og:description" content="gameboy camera-like experience in your browser!">
- <meta property="og:image" content="https://maple.pet/webgbcam/icon.png">
- <meta property="og:url" content="https://maple.pet/webgbcam/">
-</head>
-<body>
- <div id="main-app-window" class="maple-window centered">
- <div class="maple-window-title"><span>webgbcam v4.3</span></div>
- <div id="camera">
- <canvas id="app-view"></canvas>
- <canvas id="camera-view"></canvas>
- <canvas id="camera-output"></canvas>
- <video id="camera-stream" autoplay playsinline></video>
- </div><br/>
- <button id="button-about" onclick="toggleAbout();">about</button>
- </div>
-
- <div id="about" class="maple-window centered modal hidden">
- <div class="maple-window-title"><span>about</span></div>
- <h2 class="blink">NFTs: No Fucking Thanks</h2>
-
- <p>made by <a href="https://maple.pet">maple</a> - inspired by christine love's interstellar selfie station</p>
-
- <p>if the app is blank, make sure you have cameras connected and browser camera permissions enabled!</p>
-
- <p>webgbcam uses <a href="https://github.com/jnordberg/gif.js">gif.js</a><br/>
- you can check the source code on <a href="https://github.com/Lana-chan/webgbcam">github</a>!</p>
-
- <p>as seen on:
- <ul>
- <li>Mashable: <a href="https://mashable.com/article/game-boy-camera-style-web-app">New web app lets you take Game Boy Camera-style pics and pretend it's 1998</a></li>
- <li>Nerdist: <a href="https://nerdist.com/article/game-boy-app-camera-selfies/">Web App Lets You Take 1998 Game Boy Camera-Style Selfies</a></li>
- <li>Hackaday: <a href="https://hackaday.com/2020/10/26/the-game-boy-camera-or-how-i-learned-to-stop-worrying-and-love-the-pixels/">The Game Boy Camera, Or: How I Learned To Stop Worrying And Love The Pixels</a></li>
- </ul>
- </p>
-
- <p>if you like the stuff i do, check out <a href="https://maple.pet/">my website</a> and please <a href="https://ko-fi.com/squirrel">donate to me on ko-fi</a>!</p>
-
- <p>ps: you look great today!</p>
-
- <button id="button-close" onclick="toggleAbout();">close</button>
- </div>
-
- <div id="gif-preview" class="maple-window modal hidden">
- <div class="maple-window-title"><span>gif preview</span></div>
- <img id="gif-img" src="ui/loading.gif"/>
- <div id="gif-buttons" class="hidden">
- <button type="button" onclick="downloadGif();">yes!!!</button>
- <button class="right" type="button" onclick="resetGifModal();">no!!!</button>
- </div>
- </div>
-
- <div class="hidden">
- <img src="ui/ui-main.png" id="ui-main" />
- <img src="ui/ui-settings.png" id="ui-settings" />
- <img src="ui/ui-capture.png" id="ui-capture" />
- <img src="ui/ui-hidden.png" id="ui-hidden" />
- <img src="ui/ui-timer.png" id="ui-timer" />
- <img src="ui/ui-record.png" id="ui-record" />
- </div>
-
- <script type="text/javascript" src="gifjs/gif.js"></script>
- <script src="app.js"></script>
- <script>
- if('serviceWorker' in navigator) {
- navigator.serviceWorker
- .register('sw.js', {scope: './'})
- .then(function(registration) {
- // Registration was successful
- console.log('ServiceWorker registration successful with scope: ', registration.scope);
- registration.update();
- }, function(err) {
- // registration failed :(
- console.log('ServiceWorker registration failed: ', err);
- });
- }
- </script>
-</body>
+<!doctype html>
+<html lang=”en”>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>webgbcam</title>
+ <link rel="stylesheet" href="style.css">
+ <link rel="manifest" href="manifest.webmanifest">
+
+ <meta property="og:title" content="webgbcam">
+ <meta property="og:description" content="gameboy camera-like experience in your browser!">
+ <meta property="og:image" content="https://maple.pet/webgbcam/icon.png">
+ <meta property="og:url" content="https://maple.pet/webgbcam/">
+</head>
+<body>
+ <div id="main-app-window" class="maple-window centered">
+ <div class="maple-window-title"><span>webgbcam v4.3</span></div>
+ <div id="camera">
+ <canvas id="app-view"></canvas>
+ <canvas id="camera-view"></canvas>
+ <canvas id="camera-output"></canvas>
+ <video id="camera-stream" autoplay playsinline></video>
+ </div><br/>
+ <button id="button-about" onclick="toggleAbout();">about</button>
+ </div>
+
+ <div id="about" class="maple-window centered modal hidden">
+ <div class="maple-window-title"><span>about</span></div>
+ <h2 class="blink">NFTs: No Fucking Thanks</h2>
+
+ <p>made by <a href="https://maple.pet">maple</a> - inspired by christine love's interstellar selfie station</p>
+
+ <p>if the app is blank, make sure you have cameras connected and browser camera permissions enabled!</p>
+
+ <p>webgbcam uses <a href="https://github.com/jnordberg/gif.js">gif.js</a><br/>
+ you can check the source code on <a href="https://github.com/Lana-chan/webgbcam">github</a>!</p>
+
+ <p>as seen on:
+ <ul>
+ <li>Mashable: <a href="https://mashable.com/article/game-boy-camera-style-web-app">New web app lets you take Game Boy Camera-style pics and pretend it's 1998</a></li>
+ <li>Nerdist: <a href="https://nerdist.com/article/game-boy-app-camera-selfies/">Web App Lets You Take 1998 Game Boy Camera-Style Selfies</a></li>
+ <li>Hackaday: <a href="https://hackaday.com/2020/10/26/the-game-boy-camera-or-how-i-learned-to-stop-worrying-and-love-the-pixels/">The Game Boy Camera, Or: How I Learned To Stop Worrying And Love The Pixels</a></li>
+ </ul>
+ </p>
+
+ <p>if you like the stuff i do, check out <a href="https://maple.pet/">my website</a> and please <a href="https://ko-fi.com/squirrel">donate to me on ko-fi</a>!</p>
+
+ <p>ps: you look great today!</p>
+
+ <button id="button-close" onclick="toggleAbout();">close</button>
+ </div>
+
+ <div id="gif-preview" class="maple-window modal hidden">
+ <div class="maple-window-title"><span>gif preview</span></div>
+ <img id="gif-img" src="ui/loading.gif"/>
+ <div id="gif-buttons" class="hidden">
+ <button type="button" onclick="downloadGif();">yes!!!</button>
+ <button class="right" type="button" onclick="resetGifModal();">no!!!</button>
+ </div>
+ </div>
+
+ <div class="hidden">
+ <img src="ui/ui-main.png" id="ui-main" />
+ <img src="ui/ui-settings.png" id="ui-settings" />
+ <img src="ui/ui-capture.png" id="ui-capture" />
+ <img src="ui/ui-hidden.png" id="ui-hidden" />
+ <img src="ui/ui-timer.png" id="ui-timer" />
+ <img src="ui/ui-record.png" id="ui-record" />
+ </div>
+
+ <script type="text/javascript" src="gifjs/gif.js"></script>
+ <script src="app.js"></script>
+ <script>
+ if('serviceWorker' in navigator) {
+ navigator.serviceWorker
+ .register('sw.js', {scope: './'})
+ .then(function(registration) {
+ // Registration was successful
+ console.log('ServiceWorker registration successful with scope: ', registration.scope);
+ registration.update();
+ }, function(err) {
+ // registration failed :(
+ console.log('ServiceWorker registration failed: ', err);
+ });
+ }
+ </script>
+</body>
</html>
\ No newline at end of file
DIR diff --git a/manifest.webmanifest b/manifest.webmanifest
@@ -1,15 +1,15 @@
-{
- "background_color": "#99ccff",
- "description": "A web-based camera filter that emulates the look of the Game Boy Camera.",
- "display": "standalone",
- "icons": [
- {
- "src": "icon.png",
- "sizes": "256x256",
- "type": "image/png"
- }
- ],
- "name": "webgbcam",
- "short_name": "webgbcam",
- "start_url": "index.html"
+{
+ "background_color": "#99ccff",
+ "description": "A web-based camera filter that emulates the look of the Game Boy Camera.",
+ "display": "standalone",
+ "icons": [
+ {
+ "src": "icon.png",
+ "sizes": "256x256",
+ "type": "image/png"
+ }
+ ],
+ "name": "webgbcam",
+ "short_name": "webgbcam",
+ "start_url": "index.html"
}
\ No newline at end of file
DIR diff --git a/style.css b/style.css
@@ -1,166 +1,166 @@
-html, body{
- margin: 0;
- padding: 0;
- height: 100%;
- width: 100%;
- touch-action: manipulation;
-}
-
-body {
- background: url("ui/bg.png");
- text-align: center;
- font: 12px sans-serif;
-}
-
-.centered {
- text-align: center !important;
-}
-
-.maple-window {
- margin: 5px;
- vertical-align: top;
- display: inline-block;
- border-width: 26px 12px 20px 12px;
- border-style: solid;
- border-image: url("ui/mac-frame.png") 30 40 22 22 fill repeat;
- border-image-width: 30px 40px 22px 22px;
- color: #000;
- position: relative;
- text-align: left;
- font-size: 12px;
- font-family: geneva, sans-serif;
- min-width: 200px;
- box-sizing: border-box;
-}
-
-.maple-window a {
- color: #9999cc;
- text-shadow: none;
-}
-.maple-window a:hover {
- color: #ccccff;
-}
-
-.maple-window-title {
- position: absolute;
- top: -23px;
- text-align: center;
- width: 100%;
- left: 0;
-}
-
-.maple-window-title > span {
- background: #ccc;
- padding: 1px 5px 1px 5px;
- font-size: 12px;
- font-weight: bold;
- font-family: chicago, sans-serif;
- /*vertical-align: middle;*/
- margin-right: 20px;
- white-space: nowrap;
-}
-
-/*#camera {
- position: fixed;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
-}*/
-
-#app-view {
- height: 100%;
- width: 100%;
- /*image-rendering: -moz-crisp-edges;
- image-rendering: -webkit-optimize-contrast;
- image-rendering: -o-crisp-edges;
- image-rendering: crisp-edges;*/
-}
-
-#camera-stream, #camera-output, #camera-view, .hidden {
- display: none;
-}
-
-.button {
- width: 200px;
- background-color: black;
- color: white;
- font-size: 16px;
- border-radius: 30px;
- border: none;
- padding: 15px 20px;
- text-align: center;
- box-shadow: 0 5px 10px 0 rgba(0,0,0,0.2);
- /*position: fixed;
- bottom: 30px;
- left: calc(50% - 100px);*/
-}
-.right {
- float: right;
-}
-
-.modal {
- position: absolute;
- top: 0;
- left: 0;
- max-width: 80%;
- max-height: 80%;
- transform: translate(calc(50vw - 50%),calc(50vh - 50%));
-}
-
-#gif-img {
- object-fit: scale-down;
- max-width:100%;
- display: block;
- margin: auto;
-}
-#gif-buttons {
- margin: .5em;
-}
-
-.blink {
- color: #f00;
- text-align: center;
- animation: blink-animation 1s steps(5, start) 4;
- -webkit-animation: blink-animation 1s steps(5, start) 4;
-}
-@keyframes blink-animation {
- to {
- visibility: hidden;
- }
-}
-@-webkit-keyframes blink-animation {
- to {
- visibility: hidden;
- }
-}
-
-ul {
- margin-top: -1em;
- padding: 0;
- list-style: none;
-}
-
-#main-app-window {
- width: 98%;
- top: 48%;
- transform: translateY(-50%);
-}
-
-#camera {
- display: inline-block;
- width: 100%;
-}
-
-@media (orientation:landscape) {
- #main-app-window {
- width: unset;
- height: 98%;
- top: unset;
- transform: unset;
- }
-
- #camera {
- width: unset;
- height: calc(100% - 2rem);
- }
+html, body{
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ width: 100%;
+ touch-action: manipulation;
+}
+
+body {
+ background: url("ui/bg.png");
+ text-align: center;
+ font: 12px sans-serif;
+}
+
+.centered {
+ text-align: center !important;
+}
+
+.maple-window {
+ margin: 5px;
+ vertical-align: top;
+ display: inline-block;
+ border-width: 26px 12px 20px 12px;
+ border-style: solid;
+ border-image: url("ui/mac-frame.png") 30 40 22 22 fill repeat;
+ border-image-width: 30px 40px 22px 22px;
+ color: #000;
+ position: relative;
+ text-align: left;
+ font-size: 12px;
+ font-family: geneva, sans-serif;
+ min-width: 200px;
+ box-sizing: border-box;
+}
+
+.maple-window a {
+ color: #9999cc;
+ text-shadow: none;
+}
+.maple-window a:hover {
+ color: #ccccff;
+}
+
+.maple-window-title {
+ position: absolute;
+ top: -23px;
+ text-align: center;
+ width: 100%;
+ left: 0;
+}
+
+.maple-window-title > span {
+ background: #ccc;
+ padding: 1px 5px 1px 5px;
+ font-size: 12px;
+ font-weight: bold;
+ font-family: chicago, sans-serif;
+ /*vertical-align: middle;*/
+ margin-right: 20px;
+ white-space: nowrap;
+}
+
+/*#camera {
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+}*/
+
+#app-view {
+ height: 100%;
+ width: 100%;
+ /*image-rendering: -moz-crisp-edges;
+ image-rendering: -webkit-optimize-contrast;
+ image-rendering: -o-crisp-edges;
+ image-rendering: crisp-edges;*/
+}
+
+#camera-stream, #camera-output, #camera-view, .hidden {
+ display: none;
+}
+
+.button {
+ width: 200px;
+ background-color: black;
+ color: white;
+ font-size: 16px;
+ border-radius: 30px;
+ border: none;
+ padding: 15px 20px;
+ text-align: center;
+ box-shadow: 0 5px 10px 0 rgba(0,0,0,0.2);
+ /*position: fixed;
+ bottom: 30px;
+ left: calc(50% - 100px);*/
+}
+.right {
+ float: right;
+}
+
+.modal {
+ position: absolute;
+ top: 0;
+ left: 0;
+ max-width: 80%;
+ max-height: 80%;
+ transform: translate(calc(50vw - 50%),calc(50vh - 50%));
+}
+
+#gif-img {
+ object-fit: scale-down;
+ max-width:100%;
+ display: block;
+ margin: auto;
+}
+#gif-buttons {
+ margin: .5em;
+}
+
+.blink {
+ color: #f00;
+ text-align: center;
+ animation: blink-animation 1s steps(5, start) 4;
+ -webkit-animation: blink-animation 1s steps(5, start) 4;
+}
+@keyframes blink-animation {
+ to {
+ visibility: hidden;
+ }
+}
+@-webkit-keyframes blink-animation {
+ to {
+ visibility: hidden;
+ }
+}
+
+ul {
+ margin-top: -1em;
+ padding: 0;
+ list-style: none;
+}
+
+#main-app-window {
+ width: 98%;
+ top: 48%;
+ transform: translateY(-50%);
+}
+
+#camera {
+ display: inline-block;
+ width: 100%;
+}
+
+@media (orientation:landscape) {
+ #main-app-window {
+ width: unset;
+ height: 98%;
+ top: unset;
+ transform: unset;
+ }
+
+ #camera {
+ width: unset;
+ height: calc(100% - 2rem);
+ }
}
\ No newline at end of file
DIR diff --git a/sw.js b/sw.js
@@ -1,62 +1,62 @@
-const cacheName = 'webgbcam-v4.3b'
-
-// Install a service worker
-self.addEventListener("install", (event) => {
- // Perform install steps
- caches.open(cacheName).then(function(cache) {
- return cache.addAll([
- '/',
- '/index.html',
- '/style.css',
- '/app.js',
- '/ui/bg.png',
- '/ui/mac-frame.png',
- '/ui/ui-capture.png',
- '/ui/ui-settings.png',
- '/ui/ui-main.png',
- '/ui/ui-hidden.png',
- '/ui/ui-timer.png',
- '/ui/ui-record.png',
- '/ui/loading.gif',
- '/gifjs/gif.js',
- '/gifjs/gif.worker.js'
- ]);
- });
-});
-
-// Cache lookup and fetch the request
-self.addEventListener("fetch", (event) => {
- event.respondWith(
- caches.match(event.request).then(function (response) {
- // Cache hit - return response
- if (response) {
- return response;
- }
- return fetch(event.request).then(function (response) {
- if (!response || response.status !== 200 || response.type !== "basic") {
- return response;
- }
-
- //Clone the response before putting into cache so that response to browser and response to cache happens in two difference streams
- var responseForCache = response.clone();
- caches.open(cacheName).then(function (cache) {
- cache.put(event.request, responseForCache);
- });
- return response;
- });
- })
- );
-});
-
-// Update a service worker
-self.addEventListener("activate", (event) => {
- event.waitUntil(
- caches.keys().then(function(keyList) {
- return Promise.all(keyList.map(function(key) {
- if (key != cacheName) {
- return caches.delete(key);
- }
- }));
- })
- ).then(self.clients.claim());
+const cacheName = 'webgbcam-v4.3b'
+
+// Install a service worker
+self.addEventListener("install", (event) => {
+ // Perform install steps
+ caches.open(cacheName).then(function(cache) {
+ return cache.addAll([
+ '/',
+ '/index.html',
+ '/style.css',
+ '/app.js',
+ '/ui/bg.png',
+ '/ui/mac-frame.png',
+ '/ui/ui-capture.png',
+ '/ui/ui-settings.png',
+ '/ui/ui-main.png',
+ '/ui/ui-hidden.png',
+ '/ui/ui-timer.png',
+ '/ui/ui-record.png',
+ '/ui/loading.gif',
+ '/gifjs/gif.js',
+ '/gifjs/gif.worker.js'
+ ]);
+ });
+});
+
+// Cache lookup and fetch the request
+self.addEventListener("fetch", (event) => {
+ event.respondWith(
+ caches.match(event.request).then(function (response) {
+ // Cache hit - return response
+ if (response) {
+ return response;
+ }
+ return fetch(event.request).then(function (response) {
+ if (!response || response.status !== 200 || response.type !== "basic") {
+ return response;
+ }
+
+ //Clone the response before putting into cache so that response to browser and response to cache happens in two difference streams
+ var responseForCache = response.clone();
+ caches.open(cacheName).then(function (cache) {
+ cache.put(event.request, responseForCache);
+ });
+ return response;
+ });
+ })
+ );
+});
+
+// Update a service worker
+self.addEventListener("activate", (event) => {
+ event.waitUntil(
+ caches.keys().then(function(keyList) {
+ return Promise.all(keyList.map(function(key) {
+ if (key != cacheName) {
+ return caches.delete(key);
+ }
+ }));
+ })
+ ).then(self.clients.claim());
});
\ No newline at end of file