mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
By default, camera features are disabled; they're opted into by URL param and browser prompt.
This commit is contained in:
39
js/camera.js
Normal file
39
js/camera.js
Normal file
@@ -0,0 +1,39 @@
|
||||
// TODO: switch to video-based texture
|
||||
// TODO: mipmap?
|
||||
const video = document.createElement("video");
|
||||
const cameraCanvas = document.createElement("canvas");
|
||||
cameraCanvas.width = 1;
|
||||
cameraCanvas.height = 1;
|
||||
const context = cameraCanvas.getContext("2d");
|
||||
let cameraAspectRatio = 1.0;
|
||||
|
||||
const drawToCanvas = () => {
|
||||
requestAnimationFrame(drawToCanvas);
|
||||
context.drawImage(video, 0, 0);
|
||||
};
|
||||
|
||||
const setupCamera = async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({video: {
|
||||
width: { min: 800, ideal: 1280 },
|
||||
frameRate: { ideal: 60 }
|
||||
}, audio: false});
|
||||
const videoTrack = stream.getVideoTracks()[0];
|
||||
const {width, height} = videoTrack.getSettings();
|
||||
|
||||
video.width = width;
|
||||
video.height = height;
|
||||
cameraCanvas.width = width;
|
||||
cameraCanvas.height = height;
|
||||
cameraAspectRatio = width / height;
|
||||
|
||||
video.srcObject = stream;
|
||||
video.play();
|
||||
|
||||
drawToCanvas();
|
||||
} catch (e) {
|
||||
console.warn(`Camera not initialized: ${e}`);
|
||||
}
|
||||
};
|
||||
|
||||
export { cameraCanvas, cameraAspectRatio, setupCamera };
|
||||
@@ -53,6 +53,7 @@ const fonts = {
|
||||
|
||||
const defaults = {
|
||||
font: "matrixcode",
|
||||
useCamera: false,
|
||||
backgroundColor: [0, 0, 0], // The color "behind" the glyphs
|
||||
volumetric: false, // A mode where the raindrops appear in perspective
|
||||
resurrectingCodeRatio: 0, // The percent of columns that flow upward
|
||||
@@ -257,6 +258,7 @@ const paramMapping = {
|
||||
version: { key: "version", parser: (s) => s },
|
||||
font: { key: "font", parser: (s) => s },
|
||||
effect: { key: "effect", parser: (s) => s },
|
||||
camera: { key: "useCamera", parser: (s) => s.toLowerCase().includes("true") },
|
||||
width: { key: "numColumns", parser: (s) => nullNaN(parseInt(s)) },
|
||||
numColumns: { key: "numColumns", parser: (s) => nullNaN(parseInt(s)) },
|
||||
density: { key: "density", parser: (s) => nullNaN(range(parseFloat(s), 0)) },
|
||||
|
||||
@@ -9,6 +9,7 @@ import makeResurrectionPass from "./resurrectionPass.js";
|
||||
import makeQuiltPass from "./quiltPass.js";
|
||||
import makeRipplesPass from "./ripplesPass.js";
|
||||
import getLKG from "./lkgHelper.js";
|
||||
import { setupCamera } from "../camera.js";
|
||||
|
||||
const effects = {
|
||||
none: null,
|
||||
@@ -67,6 +68,10 @@ export default async (canvas, config) => {
|
||||
|
||||
const lkg = await getLKG(config.useHoloplay, true);
|
||||
|
||||
if (config.useCamera) {
|
||||
await setupCamera();
|
||||
}
|
||||
|
||||
// All this takes place in a full screen quad.
|
||||
const fullScreenQuad = makeFullScreenQuad(regl);
|
||||
const effectName = config.effect in effects ? config.effect : "plain";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { loadImage, loadText, makePassFBO, makePass } from "./utils.js";
|
||||
import { cameraCanvas, cameraAspectRatio } from "../camera.js";
|
||||
|
||||
let start = Date.now();
|
||||
const numClicks = 5;
|
||||
@@ -13,38 +14,9 @@ window.onclick = (e) => {
|
||||
index = (index + 1) % numClicks;
|
||||
}
|
||||
|
||||
// TODO: switch to video-based texture
|
||||
// TODO: mipmap?
|
||||
const video = document.createElement("video");
|
||||
const canvas = document.createElement("canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
let cameraAspectRatio = 1.0;
|
||||
|
||||
const getCameraFeed = async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({video: {
|
||||
width: { min: 800, ideal: 1280 },
|
||||
frameRate: { ideal: 60 }
|
||||
}, audio: false});
|
||||
const videoTrack = stream.getVideoTracks()[0];
|
||||
const {width, height} = videoTrack.getSettings();
|
||||
console.log(videoTrack.getSettings());
|
||||
|
||||
video.width = width;
|
||||
video.height = height;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
cameraAspectRatio = width / height;
|
||||
|
||||
video.srcObject = stream;
|
||||
video.play();
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
export default ({ regl, config }, inputs) => {
|
||||
|
||||
getCameraFeed();
|
||||
const cameraTex = regl.texture(canvas);
|
||||
const cameraTex = regl.texture(cameraCanvas);
|
||||
|
||||
start = Date.now();
|
||||
|
||||
@@ -73,8 +45,7 @@ export default ({ regl, config }, inputs) => {
|
||||
aspectRatio = w / h;
|
||||
},
|
||||
() => {
|
||||
context.drawImage(video, 0, 0);
|
||||
cameraTex(canvas);
|
||||
cameraTex(cameraCanvas);
|
||||
render({ frag: ripplesPassFrag.text() });
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user