Working demo

Down on you knees!
This commit is contained in:
Victor Westerlund 2021-01-26 05:47:26 +01:00
parent 3501d1b0fa
commit fa0c46d5c7
8 changed files with 144 additions and 51 deletions

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<title>Cathode Ray</title>
<title>CRT</title>
<style>
:root {
/* Screen */

View file

@ -1,7 +1,43 @@
import { FluorescentScreen } from "./modules/Screen.mjs";
import { RasterScan } from "./modules/Gun.mjs";
import { RasterScan } from "./modules/ElectronGun.mjs";
const screen = new FluorescentScreen(document.getElementById("screen"));
class CRT {
const CRT = new RasterScan(screen.pixels);
CRT.load("../../tapes/sample");
constructor(element) {
this.element = element;
this.initScreen();
this.raster = new RasterScan(this.screen.pixels);
}
async fetchJSON(url) {
const response = await fetch(url);
return response.json();
}
loadTape(ref) {
this.fetchJSON(ref + "/header.json").then(headers => {
// Reinitialize player with resolution from tape header
if(headers.resolution[0] !== this.element.clientWidth || headers.resolution[1] !== this.element.clientHeight) {
this.element.style.setProperty("width",headers.resolution[0] + "px");
this.element.style.setProperty("height",headers.resolution[1] + "px");
this.initScreen();
this.raster.pixels = this.screen.pixels;
}
this.raster.load(headers);
});
}
play() {
this.raster.playstate("play");
}
initScreen() {
this.screen = new FluorescentScreen(this.element);
}
}
window.video = new CRT(document.getElementById("screen"));
window.video.loadTape("tapes/sample");
window.video.play();

View file

@ -0,0 +1,31 @@
export class RasterScan {
constructor(pixels) {
this.pixels = pixels;
this.signal = new Worker("./js/modules/Raster.mjs");
this.signal.addEventListener("message",event => {
this.fire(event.data);
});
}
fire(pixel) {
this.pixels[pixel.index].style.setProperty("background",pixel.color);
//this.pixels[data.pixel].style.setProperty("animation",`decay 10ms ${data.pixel} linear forwards`);
}
load(headers) {
this.signal.postMessage({
type: "headers",
payload: headers
});
}
playstate(state) {
this.signal.postMessage({
type: "playstate",
payload: state
});
}
}

View file

@ -1,24 +0,0 @@
export class RasterScan {
constructor(pixels) {
this.pixels = pixels;
this.coils = new Worker("./js/modules/Raster.mjs");
this.coils.addEventListener("message",event => {
this.fire(event.data);
});
}
fire(data) {
this.pixels[data.pixel].style.setProperty("background",data.color);
this.pixels[data.pixel].style.setProperty("animation",`decay 10ms ${data.pixel} linear forwards`);
}
load(tape) {
this.coils.postMessage({
density: this.pixels.length,
tape: tape
});
}
}

4
js/modules/Helper.mjs Normal file
View file

@ -0,0 +1,4 @@
export async function fetchJSON(url) {
const response = await fetch(url);
return response.json();
}

View file

@ -1,17 +1,16 @@
let field;
let clock;
let meta = {
fields: 0,
pixels: 0,
framerate: 100
};
let tape = {
header: (data) => {
clock = data.framerate;
this.format = format;
let clock = null;
self.postMessage({
type: "resolutionUpdate",
data: resolution
});
},
stream: []
let tape = null;
let stream = (stream) => {
meta.fields = Math.floor(stream.length / meta.pixels);
tape = stream;
return true;
}
async function fetchJSON(url) {
@ -19,11 +18,47 @@ async function fetchJSON(url) {
return response.json();
}
function loadTape(ref) {
fetchJSON(ref + "/header.json").then(data => tape.header(data));
fetchJSON(ref + "/data.json").then(data => tape.stream = data);
function scan() {
let pixel = 0;
for(let head = 0; head < tape.length; head++) {
if(pixel == meta.pixels) {
pixel = 0;
}
self.postMessage({
index: pixel,
color: tape[head]
});
pixel++;
}
}
function playstate(state) {
if(state == "play") {
clock = setInterval(scan,meta.framerate);
return;
}
clock = null;
}
self.addEventListener("message",event => {
loadTape(event.data.tape);
const payload = event.data.payload;
switch(event.data.type) {
case "headers":
meta.pixels = payload.resolution[0] * payload.resolution[1];
meta.framerate = payload.framerate;
const segmentURL = new Array("../../tapes",payload.manifest,payload.segments[0]).join("/");
fetchJSON(segmentURL).then(tape => stream(tape));
break;
case "playstate":
playstate(payload);
break;
default: console.warn("Unknown instruction: " + event.data.type); break;
}
});

View file

@ -4,6 +4,7 @@ export class FluorescentScreen {
this.screen = screen;
this.pixels = [];
this.destroyPixels();
this.spawnPixels();
}
@ -26,4 +27,10 @@ export class FluorescentScreen {
this.createMatrix();
}
destroyPixels() {
while(this.screen.firstChild) {
this.screen.removeChild(this.screen.lastChild);
}
}
}

View file

@ -1,5 +1,9 @@
{
"manifest": "sample",
"format": "signed-hex",
"resolution": ["64","64"],
"framerate": 10
"resolution": ["32","32"],
"framerate": 100,
"segments": [
"data.json"
]
}