drawFrame optimization and error messages fixed - webgbcam - [fork] gameboy webcam
HTML git clone git://src.adamsgaard.dk/webgbcam
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit b2aa564673aa385da2d15a22efb9bd68c61e2404
DIR parent 343098c503f8ca87440bbfea1860facf5be42716
HTML Author: Erin Pinheiro <hello@mynameiser.in>
Date: Sat, 24 Oct 2020 20:42:13 -0300
drawFrame optimization and error messages fixed
Diffstat:
M app.js | 271 +++++++++++++++++++++++++------
M index.html | 2 +-
D palettes.js | 166 -------------------------------
3 files changed, 221 insertions(+), 218 deletions(-)
---
DIR diff --git a/app.js b/app.js
@@ -8,7 +8,171 @@
* ------------------------------------------------------------
*/
-import palettes from './palettes.js';
+// 4-color GB palette must be dark to light
+const palettes = [
+ // AYY4 - https://lospec.com/palette-list/ayy4
+ [
+ [0, 48, 59],
+ [255, 119, 119],
+ [255, 206, 150],
+ [241, 242, 218]
+ ],
+ /* this one was removed in favour of spacehaze which is very similar
+ // Barbie: The Slasher Movie - https://lospec.com/palette-list/barbie-the-slasher-movie
+ [
+ [0, 0, 0],
+ [110, 31, 177],
+ [204, 51, 133],
+ [248, 251, 243]
+ ],*/
+ // SpaceHaze - https://lospec.com/palette-list/spacehaze
+ [
+ [11, 6, 48],
+ [107, 31, 177],
+ [204, 52, 149],
+ [248, 227, 196]
+ ],
+ // CRTGB - https://lospec.com/palette-list/crtgb
+ [
+ [6, 6, 1],
+ [11, 62, 8],
+ [72, 154, 13],
+ [218, 242, 34]
+ ],
+ // Amber CRTGB - https://lospec.com/palette-list/amber-crtgb
+ [
+ [13, 4, 5],
+ [94, 18, 16],
+ [211, 86, 0],
+ [254, 208, 24]
+ ],
+ // Kirby (SGB) - https://lospec.com/palette-list/kirby-sgb
+ [
+ [44, 44, 150],
+ [119, 51, 231],
+ [231, 134, 134],
+ [247, 190, 247]
+ ],
+ // CherryMelon - https://lospec.com/palette-list/cherrymelon
+ [
+ [1, 40, 36],
+ [38, 89, 53],
+ [255, 77, 109],
+ [252, 222, 234]
+ ],
+ // Pumpkin GB - https://lospec.com/palette-list/pumpkin-gb
+ [
+ [20, 43, 35],
+ [25, 105, 44],
+ [244, 110, 22],
+ [247, 219, 126]
+ ],
+ // Purpledawn - https://lospec.com/palette-list/purpledawn
+ [
+ [0, 27, 46],
+ [45, 117, 126],
+ [154, 123, 188],
+ [238, 253, 237]
+ ],
+ // Royal4 - https://lospec.com/palette-list/royal4
+ [
+ [82, 18, 150],
+ [138, 31, 172],
+ [212, 134, 74],
+ [235, 219, 94]
+ ],
+ // Grand Dad 4 - https://lospec.com/palette-list/grand-dad-4
+ [
+ [76, 28, 45],
+ [210, 60, 78],
+ [95, 177, 245],
+ [234, 245, 250]
+ ],
+ // Mural GB - https://lospec.com/palette-list/mural-gb
+ [
+ [10, 22, 78],
+ [162, 81, 48],
+ [206, 173, 107],
+ [250, 253, 255]
+ ],
+ // Ocean GB - https://lospec.com/palette-list/ocean-gb
+ [
+ [28, 21, 48],
+ [42, 48, 139],
+ [54, 125, 1216],
+ [141, 226, 246]
+ ],
+ // Alleyway - ISS
+ [
+ [66, 66, 66],
+ [123, 123, 206],
+ [255, 107, 255],
+ [255, 214, 0]
+ ],
+ // Pocket - ISS
+ [
+ [108, 108, 78],
+ [142, 139, 97],
+ [195, 196, 165],
+ [227, 230, 201]
+ ],
+ // Kadabura4 - https://lospec.com/palette-list/kadabura4
+ [
+ [0, 0, 0],
+ [87, 87, 87],
+ [219, 0, 12],
+ [255, 255, 255]
+ ],
+ // Virtual - ISS
+ [
+ [2, 0, 0],
+ [65, 0, 0],
+ [127, 0, 0],
+ [255, 0, 0]
+ ],
+ // Love! Love! - ISS
+ [
+ [176, 16, 48],
+ [255, 96, 176],
+ [255, 184, 232],
+ [255, 255, 255]
+ ],
+ // Metroid II (SGB) - https://lospec.com/palette-list/metroid-ii-sgb
+ [
+ [44, 23, 0],
+ [4, 126, 96],
+ [182, 37, 88],
+ [174, 223, 30]
+ ],
+ // Micro 86 - https://lospec.com/palette-list/micro-86
+ [
+ [38, 0, 14],
+ [255, 0, 0],
+ [255, 123, 48],
+ [255, 217, 178]
+ ],
+ // Vivid 2Bit Scream - https://lospec.com/palette-list/vivid-2bit-scream
+ [
+ [86, 29, 23],
+ [92, 79, 163],
+ [116, 175, 52],
+ [202, 245, 50]
+ ],
+ // Pastel GBC/SGB - submitted by synth___ruiner
+ [
+ [4,2,4],
+ [156,146,244],
+ [236,138,140],
+ [252,250,172]
+ ],
+ // trans flag - by mavica
+ [
+ [32, 32, 32],
+ [91, 207, 250],
+ [245, 171, 185],
+ [255, 255, 255]
+ ]
+];
const cameraStream = document.querySelector("#camera-stream"),
cameraView = document.querySelector("#camera-view"),
@@ -20,22 +184,27 @@ const cameraStream = document.querySelector("#camera-stream"),
uiSettings = document.querySelector("#ui-settings");
var amountOfCameras = 0;
var currentFacingMode = 'user';
-var reportedFacingMode;
var appScale;
var frameDrawing;
// global settings for gbcamera
-var cameraWidth = 128,
- cameraHeight = 112,
- cameraDither = 0.6,
- //cameraBrightness = 0.0,
- cameraContrast = 3,
- cameraGamma = 3,
- renderWidth = 160,
+var renderWidth = 160,
renderHeight = 144,
currentPalette = 0,
currentUI = uiMain;
+var cameraVars = {
+ width: 128,
+ height: 112,
+ dither: 0.6,
+ contrast: 3,
+ gamma: 3,
+ xOffset: 0,
+ yOffset: 0,
+ xScale: 1,
+ yScale: 1
+};
+
const sliderGamma = [
2.5,
2,
@@ -111,8 +280,8 @@ function savePicture() {
// i love javascript
let dateString = now.getDate() + "-" + (now.getMonth()+1) + "-"+ now.getFullYear() + " " + now.getHours() + " " + now.getMinutes() + " " + now.getSeconds();
- cameraOutput.width = cameraWidth * scale;
- cameraOutput.height = cameraHeight * scale;
+ cameraOutput.width = cameraVars.width * scale;
+ cameraOutput.height = cameraVars.height * scale;
let ctx = cameraOutput.getContext("2d");
ctx.imageSmoothingEnabled = false;
ctx.drawImage(cameraView, 0,0, cameraOutput.width, cameraOutput.height);
@@ -218,7 +387,7 @@ Filters.gbcamera = function(pixels, ditherFactor) {
let c = r*0.3 + g*0.59 + b*0.11;
// apply levels
- c = clampNumber(applyLevels(c, 0, sliderContrast[cameraContrast], sliderGamma[cameraGamma]), 0, 255);
+ c = clampNumber(applyLevels(c, 0, sliderContrast[cameraVars.contrast], sliderGamma[cameraVars.gamma]), 0, 255);
// apply bayer
c = clampNumber(c + ((bayer - 32) * ditherFactor), 0, 255);
@@ -312,15 +481,19 @@ document.addEventListener('DOMContentLoaded', function (event) {
})
.catch(function (error) {
//https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
- if (error === 'PermissionDeniedError') {
- alert('Permission denied. Please refresh and give permission.');
+ if (error.name === 'NotAllowedError') {
+ alert('camera permission denied, please refresh and allow camera capture!');
+ } else if (error.name === 'NotFoundError') {
+ alert('no cameras found! make sure your webcam is plugged in and enabled!');
+ } else {
+ alert('unspecified camera error! make sure camera permissions are enabled!');
}
console.error('getUserMedia() error: ', error);
});
} else {
alert(
- 'Mobile camera is not supported by browser, or there is no camera detected/connected',
+ 'it seems your browser does not support camera capture! :(',
);
}
});
@@ -338,8 +511,8 @@ function initCameraUI() {
cameraDiv.style.height = appScale * renderHeight + "px";
// canvas sizes
- cameraView.width = cameraWidth;
- cameraView.height = cameraHeight;
+ cameraView.width = cameraVars.width;
+ cameraView.height = cameraVars.height;
appView.width = renderWidth;
appView.height = renderHeight;
@@ -382,13 +555,13 @@ function initCameraUI() {
currentUI = uiMain;
}
} else if(isInside(mousePos, buttons.contrastLeft)) {
- if(cameraContrast > 0) cameraContrast--;
+ if(cameraVars.contrast > 0) cameraVars.contrast--;
} else if(isInside(mousePos, buttons.contrastRight)) {
- if(cameraContrast < 6) cameraContrast++;
+ if(cameraVars.contrast < 6) cameraVars.contrast++;
} else if(isInside(mousePos, buttons.brightnessLeft)) {
- if(cameraGamma > 0) cameraGamma--;
+ if(cameraVars.gamma > 0) cameraVars.gamma--;
} else if(isInside(mousePos, buttons.brightnessRight)) {
- if(cameraGamma < 6) cameraGamma++;
+ if(cameraVars.gamma < 6) cameraVars.gamma++;
} else if(isInside(mousePos, buttons.paletteLeft)) {
currentPalette--;
if(currentPalette < 0) currentPalette = palettes.length-1;
@@ -433,11 +606,29 @@ function initCameraStream() {
const settings = track.getSettings();
let str = JSON.stringify(settings, null, 4);
console.log('settings ' + str);
- reportedFacingMode = settings.facingMode;
-
+
+ // calculate scale and offset to render camera stream to camera view canvas
+ if(settings.width >= settings.height) {
+ // horizontal
+ cameraVars.yScale = cameraVars.height;
+ cameraVars.xScale = (cameraVars.height / settings.height) * settings.width;
+ cameraVars.yOffset = 0;
+ cameraVars.xOffset = -((cameraVars.xScale - cameraVars.width) / 2);
+ } else {
+ //vertical
+ cameraVars.xScale = cameraVars.width;
+ cameraVars.yScale = (cameraVars.width / settings.width) * settings.height;
+ cameraVars.xOffset = 0;
+ cameraVars.yOffset = -((cameraVars.yScale - cameraVars.height) / 2);
+ }
+
// canvas starts flipped for user facing camera
cameraView.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
- if(reportedFacingMode != 'environment') cameraView.getContext('2d').scale(-1,1);
+ if(settings.facingMode != 'environment') {
+ cameraView.getContext('2d').scale(-1,1);
+ cameraVars.xOffset *= -1;
+ cameraVars.xScale *= -1;
+ }
clearInterval(frameDrawing)
frameDrawing = setInterval(drawFrame, 100);
@@ -449,44 +640,22 @@ function initCameraStream() {
}
function drawFrame() {
- let xOffset, yOffset, xScale, yScale;
-
- // calculate scale and offset to render camera stream to camera view canvas
- if(cameraStream.videoWidth >= cameraStream.videoHeight) {
- // horizontal
- yScale = cameraHeight;
- xScale = (cameraHeight / cameraStream.videoHeight) * cameraStream.videoWidth;
- yOffset = 0;
- xOffset = -((xScale - cameraWidth) / 2);
- } else {
- //vertical
- xScale = cameraWidth;
- yScale = (cameraWidth / cameraStream.videoWidth) * cameraStream.videoHeight;
- xOffset = 0;
- yOffset = -((yScale - cameraHeight) / 2);
- }
-
let camctx = cameraView.getContext('2d');
-
- if(reportedFacingMode != 'environment') {
- xOffset *= -1;
- xScale *= -1;
- }
- camctx.drawImage(cameraStream, xOffset, yOffset, xScale, yScale);
+ camctx.drawImage(cameraStream, cameraVars.xOffset, cameraVars.yOffset, cameraVars.xScale, cameraVars.yScale);
- Filters.filterImage(Filters.gbcamera, cameraView, [cameraDither]);
+ Filters.filterImage(Filters.gbcamera, cameraView, [cameraVars.dither]);
let ctx = appView.getContext("2d");
ctx.drawImage(cameraView, 16, 16);
ctx.drawImage(currentUI, 0, 0);
if(currentUI === uiSettings) {
- // update settings values
+ // update settings values
ctx.fillStyle = "rgb(192,192,192)"
- for(let i = 1; i <= cameraContrast; i++) {
+ for(let i = 1; i <= cameraVars.contrast; i++) {
ctx.fillRect(42, 22 - (i*3), 4, 2);
}
- for(let i = 1; i <= cameraGamma; i++) {
+ for(let i = 1; i <= cameraVars.gamma; i++) {
ctx.fillRect(97, 22 - (i*3), 4, 2);
}
}
DIR diff --git a/index.html b/index.html
@@ -35,6 +35,6 @@
<img src="ui-capture.png" id="ui-capture" />
</div>
- <script type="module" src="app.js"></script>
+ <script src="app.js"></script>
</body>
</html>
\ No newline at end of file
DIR diff --git a/palettes.js b/palettes.js
@@ -1,165 +0,0 @@
-/*
- * Palettes included in this file are taken from lospec.com and
- * the Interstellar Selfie Station where noted, credit is given
- * to their respective creators.
- */
-
-// 4-color GB palette must be dark to light
-const palettes = [
- // AYY4 - https://lospec.com/palette-list/ayy4
- [
- [0, 48, 59],
- [255, 119, 119],
- [255, 206, 150],
- [241, 242, 218]
- ],
- // Barbie: The Slasher Movie - https://lospec.com/palette-list/barbie-the-slasher-movie
- [
- [0, 0, 0],
- [110, 31, 177],
- [204, 51, 133],
- [248, 251, 243]
- ],
- // CRTGB - https://lospec.com/palette-list/crtgb
- [
- [6, 6, 1],
- [11, 62, 8],
- [72, 154, 13],
- [218, 242, 34]
- ],
- // Amber CRTGB - https://lospec.com/palette-list/amber-crtgb
- [
- [13, 4, 5],
- [94, 18, 16],
- [211, 86, 0],
- [254, 208, 24]
- ],
- // Kirby (SGB) - https://lospec.com/palette-list/kirby-sgb
- [
- [44, 44, 150],
- [119, 51, 231],
- [231, 134, 134],
- [247, 190, 247]
- ],
- // CherryMelon - https://lospec.com/palette-list/cherrymelon
- [
- [1, 40, 36],
- [38, 89, 53],
- [255, 77, 109],
- [252, 222, 234]
- ],
- // Pumpkin GB - https://lospec.com/palette-list/pumpkin-gb
- [
- [20, 43, 35],
- [25, 105, 44],
- [244, 110, 22],
- [247, 219, 126]
- ],
- // Purpledawn - https://lospec.com/palette-list/purpledawn
- [
- [0, 27, 46],
- [45, 117, 126],
- [154, 123, 188],
- [238, 253, 237]
- ],
- // Royal4 - https://lospec.com/palette-list/royal4
- [
- [82, 18, 150],
- [138, 31, 172],
- [212, 134, 74],
- [235, 219, 94]
- ],
- // Grand Dad 4 - https://lospec.com/palette-list/grand-dad-4
- [
- [76, 28, 45],
- [210, 60, 78],
- [95, 177, 245],
- [234, 245, 250]
- ],
- // Mural GB - https://lospec.com/palette-list/mural-gb
- [
- [10, 22, 78],
- [162, 81, 48],
- [206, 173, 107],
- [250, 253, 255]
- ],
- // Ocean GB - https://lospec.com/palette-list/ocean-gb
- [
- [28, 21, 48],
- [42, 48, 139],
- [54, 125, 1216],
- [141, 226, 246]
- ],
- // Alleyway - ISS
- [
- [66, 66, 66],
- [123, 123, 206],
- [255, 107, 255],
- [255, 214, 0]
- ],
- // Pocket - ISS
- [
- [108, 108, 78],
- [142, 139, 97],
- [195, 196, 165],
- [227, 230, 201]
- ],
- // Kadabura4 - https://lospec.com/palette-list/kadabura4
- [
- [0, 0, 0],
- [87, 87, 87],
- [219, 0, 12],
- [255, 255, 255]
- ],
- // Virtual - ISS
- [
- [2, 0, 0],
- [65, 0, 0],
- [127, 0, 0],
- [255, 0, 0]
- ],
- // Love! Love! - ISS
- [
- [176, 16, 48],
- [255, 96, 176],
- [255, 184, 232],
- [255, 255, 255]
- ],
- // Metroid II (SGB) - https://lospec.com/palette-list/metroid-ii-sgb
- [
- [44, 23, 0],
- [4, 126, 96],
- [182, 37, 88],
- [174, 223, 30]
- ],
- // Micro 86 - https://lospec.com/palette-list/micro-86
- [
- [38, 0, 14],
- [255, 0, 0],
- [255, 123, 48],
- [255, 217, 178]
- ],
- // Vivid 2Bit Scream - https://lospec.com/palette-list/vivid-2bit-scream
- [
- [86, 29, 23],
- [92, 79, 163],
- [116, 175, 52],
- [202, 245, 50]
- ],
- // Pastel GBC/SGB - submitted by synth___ruiner
- [
- [4,2,4],
- [156,146,244],
- [236,138,140],
- [252,250,172]
- ],
- // trans flag - by mavica
- [
- [32, 32, 32],
- [91, 207, 250],
- [245, 171, 185],
- [255, 255, 255]
- ]
-];
-
-export default palettes;
-\ No newline at end of file