WIP
|
@ -16,10 +16,12 @@ const config = {
|
||||||
src: [
|
src: [
|
||||||
basePath + 'utils.js',
|
basePath + 'utils.js',
|
||||||
basePath + 'gl/glUtils.js',
|
basePath + 'gl/glUtils.js',
|
||||||
|
basePath + 'gl/Camera.js',
|
||||||
basePath + 'template.js',
|
basePath + 'template.js',
|
||||||
basePath + 'gl/handler.js',
|
basePath + 'gl/handler.js',
|
||||||
basePath + 'audio.js',
|
basePath + 'audio.js',
|
||||||
basePath + 'FileHandler.js',
|
basePath + 'FileHandler.js',
|
||||||
|
basePath + 'FetchHandler.js',
|
||||||
basePath + 'playerConfigHandler.js',
|
basePath + 'playerConfigHandler.js',
|
||||||
basePath + 'player.js',
|
basePath + 'player.js',
|
||||||
basePath + 'gui.js',
|
basePath + 'gui.js',
|
||||||
|
@ -42,7 +44,7 @@ function build() {
|
||||||
.pipe(concat('scripts.js'))
|
.pipe(concat('scripts.js'))
|
||||||
.pipe(gulp.dest(config.dest))
|
.pipe(gulp.dest(config.dest))
|
||||||
.pipe(rename('scripts.min.js'))
|
.pipe(rename('scripts.min.js'))
|
||||||
.pipe(terser())
|
.pipe(terser().on('error', console.error))
|
||||||
.pipe(gulp.dest(config.dest));
|
.pipe(gulp.dest(config.dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
0
empty.txt
Normal file
BIN
favicon.ico
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
favicon/android-chrome-192x192.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
favicon/android-chrome-512x512.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
favicon/apple-touch-icon.png
Executable file
After Width: | Height: | Size: 1.1 KiB |
BIN
favicon/favicon-16x16.png
Executable file
After Width: | Height: | Size: 311 B |
BIN
favicon/favicon-32x32.png
Executable file
After Width: | Height: | Size: 407 B |
BIN
favicon/mstile-150x150.png
Executable file
After Width: | Height: | Size: 890 B |
1
favicon/safari-pinned-tab.svg
Executable file
|
@ -0,0 +1 @@
|
||||||
|
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="893.333" height="893.333" viewBox="0 0 670.000000 670.000000"><path d="M48 256.8c0 .4 10.7 23.9 23.9 52.2 13.1 28.3 25.5 55.1 27.5 59.5l3.7 7.9 5.8-12.7 5.9-12.7L93 303.7l-21.9-47.2-11.5-.3c-6.4-.1-11.6.1-11.6.6zM178.2 262.2c-4.6 10-42.4 91.1-53.8 115.5L114 399.8l5.7 12.4c3.1 6.7 5.8 12.5 5.9 12.7.2.2 1.6-2.3 3.1-5.5 1.4-3.2 18.8-40.6 38.6-82.9 19.7-42.4 36.1-77.8 36.4-78.8.5-1.5-.5-1.7-11.1-1.7H181l-2.8 6.2zM255 257.9c-8.2 2.6-11.8 4.8-18.3 10.9-10.9 10.4-15.2 21.4-14.5 37.1.3 8.6.7 10.5 4.1 17.4 6.5 13.7 18.8 23.5 33.5 26.6 2.9.6 9.5 1.1 14.6 1.1 11.4 0 17.1 1.8 22.6 7.2 5.7 5.4 8 10.8 8 18.8 0 11.1-5.4 19.5-15.5 24.1-3.6 1.7-7.2 1.9-35.7 1.9H222v22h31.3c24.9 0 32.5-.3 37.2-1.5 23.9-6.3 39.7-30 35.7-53.8-2.7-15.8-11.6-27.9-25.6-34.7-9-4.4-16.6-6-29.6-6-9.7 0-14.5-1.7-19.8-7.1-5.8-5.7-7.7-10.4-7.6-18.9 0-9 2.2-14 8.5-19.3 7.4-6.4 9.6-6.7 44.1-6.7H327v-21l-33.2.1c-29.1 0-34 .2-38.8 1.8zM360 266.5V277h113v-21H360v10.5zM495 266.5V277h62.5l5.8-9.9c3.1-5.4 5.7-10.1 5.7-10.5 0-.3-16.6-.6-37-.6h-37v10.5zM575.1 286.3c-9.6 16.6-31.4 54.2-48.3 83.5-16.9 29.4-30.8 53.8-30.8 54.3s24.3.8 60.8.7l60.7-.3v-21l-42.2-.3c-23.3-.1-42.3-.6-42.3-1s.6-1.6 1.4-2.7c.7-1.1 8.7-14.8 17.6-30.5 9-15.7 26.7-46.5 39.5-68.5s23.7-41 24.4-42.3l1.2-2.2h-12.3l-12.3.1-17.4 30.2zM407 361v64h21V297h-21v64z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
13
index.html
|
@ -2,7 +2,18 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>VS3D-Vis</title>
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=yes, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<meta name="description" content="WebAudio Player created by VersusTuneZ"/>
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/manifest.json">
|
||||||
|
<link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#5bbad5">
|
||||||
|
<meta name="msapplication-TileColor" content="#3949ab">
|
||||||
|
<meta name="theme-color" content="#3949ab">
|
||||||
|
<title>VIS3D</title>
|
||||||
<link rel="stylesheet" href="out/theme/style.css">
|
<link rel="stylesheet" href="out/theme/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
21
manifest.json
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "VIS3D by VersusTuneZ",
|
||||||
|
"short_name": "VIS3D",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/favicon/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/favicon/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#3949ab",
|
||||||
|
"background_color": "#212121",
|
||||||
|
"display": "standalone",
|
||||||
|
"start_url": "/index.html",
|
||||||
|
"orientation": "landscape-primary"
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
[{"group":"","name":"fftSize","showName":"FFT-Size","options":[2048,4096,8192,16384,32768],"value":16384,"type":"select","tooltip":"How Many Items should the FFT Capture and Render","dataType":"int"},{"group":"rotation","name":["X","Y","Z"],"props":["x","y","z"],"type":"slider","max":360,"min":-360,"value":0,"dataType":"int"},{"group":"rotation","name":["X-Inc","Y-Inc","Z-Inc"],"props":["x-inc","y-inc","z-inc"],"type":"slider","max":1,"min":-1,"value":0,"stepSize":0.01,"dataType":"float"},{"group":"","name":"baseColor","showName":"Base Color","type":"color","value":"#0089ff","dataType":"rgb","tooltip":"Base Color!"},{"group":"","name":"gradientToColor","showName":"Second Color","type":"color","value":"#ff0000","dataType":"rgb","tooltip":"Second Color!"}]
|
[{"group":"","name":"fftSize","showName":"FFT-Size","options":[2048,4096,8192,16384,32768],"value":16384,"type":"select","tooltip":"How Many Items should the FFT Capture and Render","dataType":"int"},{"group":"rotation","name":["X","Y","Z"],"props":["x","y","z"],"type":"slider","max":360,"min":-360,"value":0,"dataType":"int"},{"group":"rotation","name":["X-Inc","Y-Inc","Z-Inc"],"props":["x-inc","y-inc","z-inc"],"type":"slider","max":1,"min":-1,"value":0,"stepSize":0.01,"dataType":"float"},{"group":"translate","name":["X","Y","Z"],"props":["x","y","z"],"type":"slider","max":1,"min":-1,"value":0,"stepSize":0.01,"dataType":"float"},{"group":"","name":"fudgeFactor","showName":"Fudge Factor","type":"slider","value":1,"max":2,"min":0,"tooltip":"z to w Fudge","stepSize":0.1,"dataType":"float"},{"group":"","name":"baseColor","showName":"Base Color","type":"color","value":"#0089ff","dataType":"rgb","tooltip":"Base Color!"},{"group":"","name":"gradientToColor","showName":"Second Color","type":"color","value":"#ff0000","dataType":"rgb","tooltip":"Second Color!"}]
|
|
@ -479,6 +479,15 @@ class TDUtils {
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static projection(width, height, depth) {
|
||||||
|
return [
|
||||||
|
2 / width, 0, 0, 0,
|
||||||
|
0, -2 / height, 0, 0,
|
||||||
|
0, 0, 2 / depth, 0,
|
||||||
|
-1, 1, 0, 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
static inverse(m, dst) {
|
static inverse(m, dst) {
|
||||||
dst = dst || new Float32Array(16);
|
dst = dst || new Float32Array(16);
|
||||||
let m00 = m[0],
|
let m00 = m[0],
|
||||||
|
@ -567,42 +576,13 @@ class TDUtils {
|
||||||
|
|
||||||
static aspectView(aspect) {
|
static aspectView(aspect) {
|
||||||
return [
|
return [
|
||||||
1 * aspect, 0, 0, 0,
|
1 / aspect, 0, 0, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1
|
0, 0, 0, 1
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static getMatrix(fov, aspect, near, far, camAngle, radius) {
|
|
||||||
let lMat = this.lastMatrix,
|
|
||||||
u = TDUtils;
|
|
||||||
if (!u.isSame('fov', fov)
|
|
||||||
|| !u.isSame('aspect', aspect)
|
|
||||||
|| !u.isSame('near', near)
|
|
||||||
|| !u.isSame('far', far)
|
|
||||||
|| !u.isSame('cam', camAngle)
|
|
||||||
|| !u.isSame('radius', radius)
|
|
||||||
) {
|
|
||||||
let matrix = TDUtils.perspective(TDUtils.degToRad(fov), aspect, near, far),
|
|
||||||
cameraMatrix = TDUtils.yRotation(TDUtils.degToRad(camAngle));
|
|
||||||
cameraMatrix = TDUtils.translate(cameraMatrix, 0, 0, radius * 1.5);
|
|
||||||
let viewMatrix = TDUtils.inverse(cameraMatrix);
|
|
||||||
matrix = TDUtils.multiply(matrix, viewMatrix)
|
|
||||||
lMat.m = matrix;
|
|
||||||
}
|
|
||||||
return lMat.m;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isSame(key, value) {
|
|
||||||
let lMat = this.lastMatrix;
|
|
||||||
if (lMat[key] !== value) {
|
|
||||||
lMat[key] = value;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateRotate(rotation, def) {
|
static updateRotate(rotation, def) {
|
||||||
let value = vConf.get(rotation, def) + vConf.get(rotation + '-inc', 0)
|
let value = vConf.get(rotation, def) + vConf.get(rotation + '-inc', 0)
|
||||||
if (value > 360) {
|
if (value > 360) {
|
||||||
|
@ -612,6 +592,149 @@ class TDUtils {
|
||||||
}
|
}
|
||||||
vConf.set(rotation, value);
|
vConf.set(rotation, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static makeZToWMatrix(fudgeFactor) {
|
||||||
|
return [
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
0, 0, 1, fudgeFactor,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLHelper {
|
||||||
|
constructor(program) {
|
||||||
|
this.matrix = new Float32Array(16);
|
||||||
|
this.program = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform4fv(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform4fv(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform3fv(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform3fv(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform1f(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform1f(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateX(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.xRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateY(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.yRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateZ(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.zRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
scale(scaling) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.scale(scaling[0], scaling[1], scaling[2]))
|
||||||
|
}
|
||||||
|
|
||||||
|
project(depth) {
|
||||||
|
depth = depth || (c.width > c.height) ? c.width : c.height;
|
||||||
|
this.matrix = TDUtils.projection(c.width, c.height, depth)
|
||||||
|
}
|
||||||
|
|
||||||
|
translate(t) {
|
||||||
|
this.matrix = TDUtils.translate(this.matrix, t[0] || 0, t[1] || 0, t[2] || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
addFudgeFactor(fudgeFactor) {
|
||||||
|
this.matrix = TDUtils.multiply(TDUtils.makeZToWMatrix(fudgeFactor), this.matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMatrix() {
|
||||||
|
let matrix = gl.getUniformLocation(this.program, "u_matrix");
|
||||||
|
gl.uniformMatrix4fv(matrix, false, this.matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Camera {
|
||||||
|
constructor() {
|
||||||
|
this.mouse;
|
||||||
|
this.rotation = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
this.lastMouse;
|
||||||
|
this.mousePressed = false;
|
||||||
|
this.translate = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this.mouse = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
window.addEventListener('mousedown', this.mouseDown.bind(this));
|
||||||
|
window.addEventListener('mouseup', this.mouseUp.bind(this));
|
||||||
|
window.addEventListener('mousemove', this.mouseMove.bind(this), {passive: true});
|
||||||
|
eventHandler.addEvent('keys-ArrowUp, keys-ArrowDown, keys-ArrowLeft, keys-ArrowRight, keys-KeyQ, keys-KeyE', this.keyPressed.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseDown() {
|
||||||
|
this.mousePressed = true;
|
||||||
|
this.lastMouse = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseUp() {
|
||||||
|
this.mousePressed = false;
|
||||||
|
this.lastMouse = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseMove(event) {
|
||||||
|
if (!this.mousePressed || gui.modal.open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.lastMouse) {
|
||||||
|
let mouse = this.mouse,
|
||||||
|
rotate = this.rotation;
|
||||||
|
mouse.x += (this.lastMouse.x - event.clientX) * 0.2;
|
||||||
|
mouse.y += (this.lastMouse.y - event.clientY) * 0.2;
|
||||||
|
rotate.x = VTUtils.map(mouse.x, -c.width, c.width, 180, -180, false);
|
||||||
|
rotate.y = VTUtils.map(mouse.y, -c.height, c.height, 180, -180, false);
|
||||||
|
}
|
||||||
|
this.lastMouse = {
|
||||||
|
x: event.clientX,
|
||||||
|
y: event.clientY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPressed(data) {
|
||||||
|
switch (data) {
|
||||||
|
case 'keys-ArrowUp':
|
||||||
|
this.translate.z += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowDown':
|
||||||
|
this.translate.z -= 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowLeft':
|
||||||
|
this.translate.x -= 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowRight':
|
||||||
|
this.translate.x += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-KeyQ':
|
||||||
|
this.translate.y += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-KeyE':
|
||||||
|
this.translate.y -= 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class Template {
|
class Template {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -621,9 +744,7 @@ class Template {
|
||||||
async loadTemplate(name) {
|
async loadTemplate(name) {
|
||||||
let self = this;
|
let self = this;
|
||||||
if (!this.tpl[name]) {
|
if (!this.tpl[name]) {
|
||||||
await fetch(templateDir + name + ".tpl").then((r) => r.text()).then(c => {
|
self.tpl[name] = await FetchHandler.loadFile(templateDir + name + '.tpl', false)
|
||||||
self.tpl[name] = c;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,16 +772,10 @@ class Template {
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFromAPI(url, name, cb) {
|
|
||||||
fetch(url).then((r) => r.json()).then(d => {
|
|
||||||
cb(this.parseTemplate(name, d))
|
|
||||||
}).catch(console.error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateEx = /\$(.*?)\$/gm;
|
const templateEx = /\$(.*?)\$/gm;
|
||||||
const templateDir = "out/tpl/"
|
const templateDir = "/out/tpl/"
|
||||||
class ShaderHandler {
|
class ShaderHandler {
|
||||||
constructor(gl) {
|
constructor(gl) {
|
||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
|
@ -682,8 +797,8 @@ class ShaderHandler {
|
||||||
async load(name, url, type) {
|
async load(name, url, type) {
|
||||||
let realName = name + "_" + type;
|
let realName = name + "_" + type;
|
||||||
if (!this.shaders[realName]) {
|
if (!this.shaders[realName]) {
|
||||||
let data = await fetch(url);
|
let data = await FetchHandler.loadFile(url, false);
|
||||||
let shader = this.createShader(await data.text(), type);
|
let shader = this.createShader(data, type);
|
||||||
if (shader) {
|
if (shader) {
|
||||||
this.shaders[realName] = shader;
|
this.shaders[realName] = shader;
|
||||||
}
|
}
|
||||||
|
@ -733,8 +848,7 @@ class ShaderHandler {
|
||||||
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
||||||
}
|
}
|
||||||
gl.linkProgram(pro);
|
gl.linkProgram(pro);
|
||||||
var success = gl.getProgramParameter(pro, gl.LINK_STATUS);
|
if (gl.getProgramParameter(pro, gl.LINK_STATUS)) {
|
||||||
if (success) {
|
|
||||||
this.programs[name] = pro;
|
this.programs[name] = pro;
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
@ -883,6 +997,42 @@ class AudioPlayerFile {
|
||||||
return template.parseTemplate('audio-information', tag);
|
return template.parseTemplate('audio-information', tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class FetchHandler {
|
||||||
|
static files = {};
|
||||||
|
|
||||||
|
static async loadFiles(array, isJSON) {
|
||||||
|
let content = [];
|
||||||
|
for (let i = 0; i < array; i++) {
|
||||||
|
content.push(await FetchHandler.loadFile(array[i], isJSON));
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async loadFile(filename, isJSON) {
|
||||||
|
filename += '?v=' + version;
|
||||||
|
let files = FetchHandler.files;
|
||||||
|
if (files[filename]) {
|
||||||
|
return files[filename];
|
||||||
|
}
|
||||||
|
let data = await FetchHandler.tryFromCache(filename);
|
||||||
|
if (isJSON) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
files[filename] = data;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async tryFromCache(filename) {
|
||||||
|
if (caches) {
|
||||||
|
let cache = await caches.open('vis3d-pwa-1');
|
||||||
|
let data = await cache.match(filename);
|
||||||
|
if (!data) {
|
||||||
|
data = await fetch(filename);
|
||||||
|
}
|
||||||
|
return await data.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
class PlayerConfigHandler {
|
class PlayerConfigHandler {
|
||||||
async init() {
|
async init() {
|
||||||
await template.loadArray([
|
await template.loadArray([
|
||||||
|
@ -984,7 +1134,7 @@ class VisualConfig {
|
||||||
let tem = VisualConfig.visualTemplates;
|
let tem = VisualConfig.visualTemplates;
|
||||||
if (!tem[name]) {
|
if (!tem[name]) {
|
||||||
//load config and save it
|
//load config and save it
|
||||||
tem[name] = await fetch('/out/gui/' + name + ".json").then((res) => res.json());
|
tem[name] = await FetchHandler.loadFile('/out/gui/' + name + ".json", true);
|
||||||
}
|
}
|
||||||
return tem[name];
|
return tem[name];
|
||||||
}
|
}
|
||||||
|
@ -1020,6 +1170,16 @@ class Player {
|
||||||
window.dispatchEvent(new CustomEvent('playSong'));
|
window.dispatchEvent(new CustomEvent('playSong'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (!audioHandler.lastSong) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let audioFile = audioHandler.audioFile;
|
||||||
|
audioFile.pause();
|
||||||
|
audioFile.currentTime = 0;
|
||||||
|
window.dispatchEvent(new CustomEvent('playSong'));
|
||||||
|
}
|
||||||
|
|
||||||
playByID(number) {
|
playByID(number) {
|
||||||
this.playlist.index = number;
|
this.playlist.index = number;
|
||||||
let next = this.playlist.getCurrent();
|
let next = this.playlist.getCurrent();
|
||||||
|
@ -1378,6 +1538,7 @@ class Modal {
|
||||||
let self = this;
|
let self = this;
|
||||||
self.currentModal = '';
|
self.currentModal = '';
|
||||||
self.modal = $('#modal');
|
self.modal = $('#modal');
|
||||||
|
self.open = false;
|
||||||
self.parent = self.modal.parentNode;
|
self.parent = self.modal.parentNode;
|
||||||
self.modal.addDelegatedEventListener('click', 'header .close', this.closeModal.bind(this));
|
self.modal.addDelegatedEventListener('click', 'header .close', this.closeModal.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -1411,6 +1572,7 @@ class Modal {
|
||||||
|
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.parent.addClass("hide")
|
this.parent.addClass("hide")
|
||||||
|
this.open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isCurrent(title) {
|
isCurrent(title) {
|
||||||
|
@ -1419,6 +1581,7 @@ class Modal {
|
||||||
|
|
||||||
showModal() {
|
showModal() {
|
||||||
this.parent.removeClass("hide")
|
this.parent.removeClass("hide")
|
||||||
|
this.open = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Visual {
|
class Visual {
|
||||||
|
@ -1843,13 +2006,15 @@ class Wave2D extends Visual {
|
||||||
|
|
||||||
updateData() {
|
updateData() {
|
||||||
let data = audioHandler.getFloatArray();
|
let data = audioHandler.getFloatArray();
|
||||||
let add = 2 / data.length,
|
let add = c.width / data.length,
|
||||||
x = -1;
|
x = 0,
|
||||||
|
y = c.height / 2,
|
||||||
|
goTrough = y / 2;
|
||||||
let outerLoop = 0;
|
let outerLoop = 0;
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
//first
|
//first
|
||||||
this.data[outerLoop] = x;
|
this.data[outerLoop] = x;
|
||||||
this.data[outerLoop + 1] = data[i];
|
this.data[outerLoop + 1] = y + (data[i] * goTrough);
|
||||||
this.data[outerLoop + 2] = data[i];
|
this.data[outerLoop + 2] = data[i];
|
||||||
outerLoop += 3;
|
outerLoop += 3;
|
||||||
x += add;
|
x += add;
|
||||||
|
@ -1872,17 +2037,18 @@ class Wave2D extends Visual {
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate(program) {
|
rotate(program) {
|
||||||
let matrix = [
|
let glHelper = new GLHelper(program);
|
||||||
1, 0, 0, 0,
|
glHelper.project();
|
||||||
0, 0.6, 0, 0,
|
glHelper.addFudgeFactor(vConf.get("fudgeFactor", 1));
|
||||||
0, 0, 1, 0,
|
glHelper.translate([
|
||||||
0, 0, 0, 1
|
camera.translate.x,
|
||||||
]
|
camera.translate.y,
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.xRotation(vConf.get("rotation-x", 0)));
|
camera.translate.z
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.yRotation(vConf.get("rotation-y", 0)));
|
]);
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.zRotation(vConf.get("rotation-z", 0)));
|
glHelper.rotateX(camera.mouse.x);
|
||||||
let rotate = gl.getUniformLocation(program, "u_matrix");
|
glHelper.rotateY(camera.mouse.y);
|
||||||
gl.uniformMatrix4fv(rotate, false, matrix);
|
glHelper.rotateZ(vConf.get("rotation-z", 0));
|
||||||
|
glHelper.applyMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -1896,9 +2062,8 @@ class Wave2D extends Visual {
|
||||||
|
|
||||||
prepare(program) {
|
prepare(program) {
|
||||||
this.position = gl.getAttribLocation(program, "a_position");
|
this.position = gl.getAttribLocation(program, "a_position");
|
||||||
this.color = gl.getUniformLocation(program, "u_color");
|
//GLHelper.uniform1f(program, "u_fudgeFactor", vConf.get("fudgeFactor", 1));
|
||||||
let lightPos = gl.getUniformLocation(program, "u_lightPos");
|
GLHelper.uniform3fv(program, "u_lightPos", vConf.get("light", [0, 5, -56]));
|
||||||
gl.uniform3fv(lightPos, vConf.get("light", [0, 5, -56]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afterDraw() {
|
afterDraw() {
|
||||||
|
@ -2186,7 +2351,8 @@ class KeyHandler {
|
||||||
media.setActionHandler('play', player.playStop.bind(player));
|
media.setActionHandler('play', player.playStop.bind(player));
|
||||||
media.setActionHandler('pause', player.playStop.bind(player));
|
media.setActionHandler('pause', player.playStop.bind(player));
|
||||||
media.setActionHandler('previoustrack', player.prevSong.bind(player));
|
media.setActionHandler('previoustrack', player.prevSong.bind(player));
|
||||||
media.setActionHandler('nexttrack', player.prevSong.bind(player));
|
media.setActionHandler('nexttrack', player.nextSong.bind(player));
|
||||||
|
media.setActionHandler('stop', player.stop.bind(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2224,7 +2390,8 @@ class KeyHandler {
|
||||||
|
|
||||||
if (eventHandler.handleEvent({
|
if (eventHandler.handleEvent({
|
||||||
data: {
|
data: {
|
||||||
cmd: name
|
cmd: name,
|
||||||
|
data: name
|
||||||
}
|
}
|
||||||
})) {
|
})) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -2267,9 +2434,11 @@ const shaderHandler = new ShaderHandler(null),
|
||||||
startup = new Startup(),
|
startup = new Startup(),
|
||||||
eventHandler = new EventHandler(),
|
eventHandler = new EventHandler(),
|
||||||
playerConf = new PlayerConfigHandler(),
|
playerConf = new PlayerConfigHandler(),
|
||||||
keyHandler = new KeyHandler();
|
keyHandler = new KeyHandler(),
|
||||||
|
version = 1,
|
||||||
|
camera = new Camera();
|
||||||
|
|
||||||
let c, gl, cInfo, ctx;
|
let c, gl, cInfo, ctx, sw;
|
||||||
|
|
||||||
worker.addEventListener('message', e => {
|
worker.addEventListener('message', e => {
|
||||||
if (e.data.status === 'startup') {
|
if (e.data.status === 'startup') {
|
||||||
|
@ -2286,6 +2455,9 @@ window.addEventListener('startupFin', e => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function startUP() {
|
async function startUP() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
sw = await navigator.serviceWorker.register('/sw.js');
|
||||||
|
}
|
||||||
pConf.loadConfigByName('default');
|
pConf.loadConfigByName('default');
|
||||||
c = $('#c'),
|
c = $('#c'),
|
||||||
gl = c.getContext("webgl2"),
|
gl = c.getContext("webgl2"),
|
||||||
|
@ -2296,10 +2468,11 @@ async function startUP() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
shaderHandler.setGL(gl)
|
shaderHandler.setGL(gl)
|
||||||
await shaderHandler.loadArray(["wave", "sphere", "water", "wave2d"], 'shaders/');
|
await shaderHandler.loadArray(["wave", "sphere", "water", "wave2d"], '/shaders/');
|
||||||
await NotificationHandler.instance.init();
|
await NotificationHandler.instance.init();
|
||||||
await audioHandler.init();
|
await audioHandler.init();
|
||||||
await player.init();
|
await player.init();
|
||||||
|
await camera.init();
|
||||||
await visual.init();
|
await visual.init();
|
||||||
await gui.init();
|
await gui.init();
|
||||||
await imageUploader.init();
|
await imageUploader.init();
|
||||||
|
|
2
out/js/scripts.min.js
vendored
|
@ -52,6 +52,37 @@
|
||||||
"stepSize": 0.01,
|
"stepSize": 0.01,
|
||||||
"dataType": "float"
|
"dataType": "float"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group": "translate",
|
||||||
|
"name": [
|
||||||
|
"X",
|
||||||
|
"Y",
|
||||||
|
"Z"
|
||||||
|
],
|
||||||
|
"props": [
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z"
|
||||||
|
],
|
||||||
|
"type": "slider",
|
||||||
|
"max": 1,
|
||||||
|
"min": -1,
|
||||||
|
"value": 0,
|
||||||
|
"stepSize": 0.01,
|
||||||
|
"dataType": "float"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "",
|
||||||
|
"name": "fudgeFactor",
|
||||||
|
"showName": "Fudge Factor",
|
||||||
|
"type": "slider",
|
||||||
|
"value": 1,
|
||||||
|
"max": 2,
|
||||||
|
"min": 0,
|
||||||
|
"tooltip": "z to w Fudge",
|
||||||
|
"stepSize": 0.1,
|
||||||
|
"dataType": "float"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group": "",
|
"group": "",
|
||||||
"name": "baseColor",
|
"name": "baseColor",
|
||||||
|
|
36
raw/javascript/FetchHandler.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
class FetchHandler {
|
||||||
|
static files = {};
|
||||||
|
|
||||||
|
static async loadFiles(array, isJSON) {
|
||||||
|
let content = [];
|
||||||
|
for (let i = 0; i < array; i++) {
|
||||||
|
content.push(await FetchHandler.loadFile(array[i], isJSON));
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async loadFile(filename, isJSON) {
|
||||||
|
filename += '?v=' + version;
|
||||||
|
let files = FetchHandler.files;
|
||||||
|
if (files[filename]) {
|
||||||
|
return files[filename];
|
||||||
|
}
|
||||||
|
let data = await FetchHandler.tryFromCache(filename);
|
||||||
|
if (isJSON) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
files[filename] = data;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async tryFromCache(filename) {
|
||||||
|
if (caches) {
|
||||||
|
let cache = await caches.open('vis3d-pwa-1');
|
||||||
|
let data = await cache.match(filename);
|
||||||
|
if (!data) {
|
||||||
|
data = await fetch(filename);
|
||||||
|
}
|
||||||
|
return await data.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,9 +10,11 @@ const shaderHandler = new ShaderHandler(null),
|
||||||
startup = new Startup(),
|
startup = new Startup(),
|
||||||
eventHandler = new EventHandler(),
|
eventHandler = new EventHandler(),
|
||||||
playerConf = new PlayerConfigHandler(),
|
playerConf = new PlayerConfigHandler(),
|
||||||
keyHandler = new KeyHandler();
|
keyHandler = new KeyHandler(),
|
||||||
|
version = 1,
|
||||||
|
camera = new Camera();
|
||||||
|
|
||||||
let c, gl, cInfo, ctx;
|
let c, gl, cInfo, ctx, sw;
|
||||||
|
|
||||||
worker.addEventListener('message', e => {
|
worker.addEventListener('message', e => {
|
||||||
if (e.data.status === 'startup') {
|
if (e.data.status === 'startup') {
|
||||||
|
@ -29,6 +31,9 @@ window.addEventListener('startupFin', e => {
|
||||||
})
|
})
|
||||||
|
|
||||||
async function startUP() {
|
async function startUP() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
sw = await navigator.serviceWorker.register('/sw.js');
|
||||||
|
}
|
||||||
pConf.loadConfigByName('default');
|
pConf.loadConfigByName('default');
|
||||||
c = $('#c'),
|
c = $('#c'),
|
||||||
gl = c.getContext("webgl2"),
|
gl = c.getContext("webgl2"),
|
||||||
|
@ -39,10 +44,11 @@ async function startUP() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
shaderHandler.setGL(gl)
|
shaderHandler.setGL(gl)
|
||||||
await shaderHandler.loadArray(["wave", "sphere", "water", "wave2d"], 'shaders/');
|
await shaderHandler.loadArray(["wave", "sphere", "water", "wave2d"], '/shaders/');
|
||||||
await NotificationHandler.instance.init();
|
await NotificationHandler.instance.init();
|
||||||
await audioHandler.init();
|
await audioHandler.init();
|
||||||
await player.init();
|
await player.init();
|
||||||
|
await camera.init();
|
||||||
await visual.init();
|
await visual.init();
|
||||||
await gui.init();
|
await gui.init();
|
||||||
await imageUploader.init();
|
await imageUploader.init();
|
||||||
|
|
78
raw/javascript/gl/Camera.js
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
class Camera {
|
||||||
|
constructor() {
|
||||||
|
this.mouse;
|
||||||
|
this.rotation = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
this.lastMouse;
|
||||||
|
this.mousePressed = false;
|
||||||
|
this.translate = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this.mouse = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
window.addEventListener('mousedown', this.mouseDown.bind(this));
|
||||||
|
window.addEventListener('mouseup', this.mouseUp.bind(this));
|
||||||
|
window.addEventListener('mousemove', this.mouseMove.bind(this), {passive: true});
|
||||||
|
eventHandler.addEvent('keys-ArrowUp, keys-ArrowDown, keys-ArrowLeft, keys-ArrowRight, keys-KeyQ, keys-KeyE', this.keyPressed.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseDown() {
|
||||||
|
this.mousePressed = true;
|
||||||
|
this.lastMouse = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseUp() {
|
||||||
|
this.mousePressed = false;
|
||||||
|
this.lastMouse = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseMove(event) {
|
||||||
|
if (!this.mousePressed || gui.modal.open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.lastMouse) {
|
||||||
|
let mouse = this.mouse,
|
||||||
|
rotate = this.rotation;
|
||||||
|
mouse.x += (this.lastMouse.x - event.clientX) * 0.2;
|
||||||
|
mouse.y += (this.lastMouse.y - event.clientY) * 0.2;
|
||||||
|
rotate.x = VTUtils.map(mouse.x, -c.width, c.width, 180, -180, false);
|
||||||
|
rotate.y = VTUtils.map(mouse.y, -c.height, c.height, 180, -180, false);
|
||||||
|
}
|
||||||
|
this.lastMouse = {
|
||||||
|
x: event.clientX,
|
||||||
|
y: event.clientY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPressed(data) {
|
||||||
|
switch (data) {
|
||||||
|
case 'keys-ArrowUp':
|
||||||
|
this.translate.z += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowDown':
|
||||||
|
this.translate.z -= 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowLeft':
|
||||||
|
this.translate.x -= 10;
|
||||||
|
break;
|
||||||
|
case 'keys-ArrowRight':
|
||||||
|
this.translate.x += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-KeyQ':
|
||||||
|
this.translate.y += 10;
|
||||||
|
break;
|
||||||
|
case 'keys-KeyE':
|
||||||
|
this.translate.y -= 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -210,6 +210,15 @@ class TDUtils {
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static projection(width, height, depth) {
|
||||||
|
return [
|
||||||
|
2 / width, 0, 0, 0,
|
||||||
|
0, -2 / height, 0, 0,
|
||||||
|
0, 0, 2 / depth, 0,
|
||||||
|
-1, 1, 0, 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
static inverse(m, dst) {
|
static inverse(m, dst) {
|
||||||
dst = dst || new Float32Array(16);
|
dst = dst || new Float32Array(16);
|
||||||
let m00 = m[0],
|
let m00 = m[0],
|
||||||
|
@ -298,42 +307,13 @@ class TDUtils {
|
||||||
|
|
||||||
static aspectView(aspect) {
|
static aspectView(aspect) {
|
||||||
return [
|
return [
|
||||||
1 * aspect, 0, 0, 0,
|
1 / aspect, 0, 0, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1
|
0, 0, 0, 1
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static getMatrix(fov, aspect, near, far, camAngle, radius) {
|
|
||||||
let lMat = this.lastMatrix,
|
|
||||||
u = TDUtils;
|
|
||||||
if (!u.isSame('fov', fov)
|
|
||||||
|| !u.isSame('aspect', aspect)
|
|
||||||
|| !u.isSame('near', near)
|
|
||||||
|| !u.isSame('far', far)
|
|
||||||
|| !u.isSame('cam', camAngle)
|
|
||||||
|| !u.isSame('radius', radius)
|
|
||||||
) {
|
|
||||||
let matrix = TDUtils.perspective(TDUtils.degToRad(fov), aspect, near, far),
|
|
||||||
cameraMatrix = TDUtils.yRotation(TDUtils.degToRad(camAngle));
|
|
||||||
cameraMatrix = TDUtils.translate(cameraMatrix, 0, 0, radius * 1.5);
|
|
||||||
let viewMatrix = TDUtils.inverse(cameraMatrix);
|
|
||||||
matrix = TDUtils.multiply(matrix, viewMatrix)
|
|
||||||
lMat.m = matrix;
|
|
||||||
}
|
|
||||||
return lMat.m;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isSame(key, value) {
|
|
||||||
let lMat = this.lastMatrix;
|
|
||||||
if (lMat[key] !== value) {
|
|
||||||
lMat[key] = value;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static updateRotate(rotation, def) {
|
static updateRotate(rotation, def) {
|
||||||
let value = vConf.get(rotation, def) + vConf.get(rotation + '-inc', 0)
|
let value = vConf.get(rotation, def) + vConf.get(rotation + '-inc', 0)
|
||||||
if (value > 360) {
|
if (value > 360) {
|
||||||
|
@ -343,4 +323,69 @@ class TDUtils {
|
||||||
}
|
}
|
||||||
vConf.set(rotation, value);
|
vConf.set(rotation, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static makeZToWMatrix(fudgeFactor) {
|
||||||
|
return [
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
0, 0, 1, fudgeFactor,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLHelper {
|
||||||
|
constructor(program) {
|
||||||
|
this.matrix = new Float32Array(16);
|
||||||
|
this.program = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform4fv(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform4fv(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform3fv(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform3fv(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uniform1f(program, name, data) {
|
||||||
|
let uniform = gl.getUniformLocation(program, name);
|
||||||
|
gl.uniform1f(uniform, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateX(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.xRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateY(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.yRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateZ(deg) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.zRotation(deg));
|
||||||
|
}
|
||||||
|
|
||||||
|
scale(scaling) {
|
||||||
|
this.matrix = TDUtils.multiply(this.matrix, TDUtils.scale(scaling[0], scaling[1], scaling[2]))
|
||||||
|
}
|
||||||
|
|
||||||
|
project(depth) {
|
||||||
|
depth = depth || (c.width > c.height) ? c.width : c.height;
|
||||||
|
this.matrix = TDUtils.projection(c.width, c.height, depth)
|
||||||
|
}
|
||||||
|
|
||||||
|
translate(t) {
|
||||||
|
this.matrix = TDUtils.translate(this.matrix, t[0] || 0, t[1] || 0, t[2] || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
addFudgeFactor(fudgeFactor) {
|
||||||
|
this.matrix = TDUtils.multiply(TDUtils.makeZToWMatrix(fudgeFactor), this.matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMatrix() {
|
||||||
|
let matrix = gl.getUniformLocation(this.program, "u_matrix");
|
||||||
|
gl.uniformMatrix4fv(matrix, false, this.matrix);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,8 +19,8 @@ class ShaderHandler {
|
||||||
async load(name, url, type) {
|
async load(name, url, type) {
|
||||||
let realName = name + "_" + type;
|
let realName = name + "_" + type;
|
||||||
if (!this.shaders[realName]) {
|
if (!this.shaders[realName]) {
|
||||||
let data = await fetch(url);
|
let data = await FetchHandler.loadFile(url, false);
|
||||||
let shader = this.createShader(await data.text(), type);
|
let shader = this.createShader(data, type);
|
||||||
if (shader) {
|
if (shader) {
|
||||||
this.shaders[realName] = shader;
|
this.shaders[realName] = shader;
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,7 @@ class ShaderHandler {
|
||||||
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
gl.attachShader(pro, this.getShader(shaders[i], gl.FRAGMENT_SHADER));
|
||||||
}
|
}
|
||||||
gl.linkProgram(pro);
|
gl.linkProgram(pro);
|
||||||
var success = gl.getProgramParameter(pro, gl.LINK_STATUS);
|
if (gl.getProgramParameter(pro, gl.LINK_STATUS)) {
|
||||||
if (success) {
|
|
||||||
this.programs[name] = pro;
|
this.programs[name] = pro;
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ class Modal {
|
||||||
let self = this;
|
let self = this;
|
||||||
self.currentModal = '';
|
self.currentModal = '';
|
||||||
self.modal = $('#modal');
|
self.modal = $('#modal');
|
||||||
|
self.open = false;
|
||||||
self.parent = self.modal.parentNode;
|
self.parent = self.modal.parentNode;
|
||||||
self.modal.addDelegatedEventListener('click', 'header .close', this.closeModal.bind(this));
|
self.modal.addDelegatedEventListener('click', 'header .close', this.closeModal.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -192,6 +193,7 @@ class Modal {
|
||||||
|
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.parent.addClass("hide")
|
this.parent.addClass("hide")
|
||||||
|
this.open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isCurrent(title) {
|
isCurrent(title) {
|
||||||
|
@ -200,5 +202,6 @@ class Modal {
|
||||||
|
|
||||||
showModal() {
|
showModal() {
|
||||||
this.parent.removeClass("hide")
|
this.parent.removeClass("hide")
|
||||||
|
this.open = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,8 @@ class KeyHandler {
|
||||||
media.setActionHandler('play', player.playStop.bind(player));
|
media.setActionHandler('play', player.playStop.bind(player));
|
||||||
media.setActionHandler('pause', player.playStop.bind(player));
|
media.setActionHandler('pause', player.playStop.bind(player));
|
||||||
media.setActionHandler('previoustrack', player.prevSong.bind(player));
|
media.setActionHandler('previoustrack', player.prevSong.bind(player));
|
||||||
media.setActionHandler('nexttrack', player.prevSong.bind(player));
|
media.setActionHandler('nexttrack', player.nextSong.bind(player));
|
||||||
|
media.setActionHandler('stop', player.stop.bind(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +50,8 @@ class KeyHandler {
|
||||||
|
|
||||||
if (eventHandler.handleEvent({
|
if (eventHandler.handleEvent({
|
||||||
data: {
|
data: {
|
||||||
cmd: name
|
cmd: name,
|
||||||
|
data: name
|
||||||
}
|
}
|
||||||
})) {
|
})) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -28,6 +28,16 @@ class Player {
|
||||||
window.dispatchEvent(new CustomEvent('playSong'));
|
window.dispatchEvent(new CustomEvent('playSong'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (!audioHandler.lastSong) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let audioFile = audioHandler.audioFile;
|
||||||
|
audioFile.pause();
|
||||||
|
audioFile.currentTime = 0;
|
||||||
|
window.dispatchEvent(new CustomEvent('playSong'));
|
||||||
|
}
|
||||||
|
|
||||||
playByID(number) {
|
playByID(number) {
|
||||||
this.playlist.index = number;
|
this.playlist.index = number;
|
||||||
let next = this.playlist.getCurrent();
|
let next = this.playlist.getCurrent();
|
||||||
|
|
|
@ -99,7 +99,7 @@ class VisualConfig {
|
||||||
let tem = VisualConfig.visualTemplates;
|
let tem = VisualConfig.visualTemplates;
|
||||||
if (!tem[name]) {
|
if (!tem[name]) {
|
||||||
//load config and save it
|
//load config and save it
|
||||||
tem[name] = await fetch('/out/gui/' + name + ".json").then((res) => res.json());
|
tem[name] = await FetchHandler.loadFile('/out/gui/' + name + ".json", true);
|
||||||
}
|
}
|
||||||
return tem[name];
|
return tem[name];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@ class Template {
|
||||||
async loadTemplate(name) {
|
async loadTemplate(name) {
|
||||||
let self = this;
|
let self = this;
|
||||||
if (!this.tpl[name]) {
|
if (!this.tpl[name]) {
|
||||||
await fetch(templateDir + name + ".tpl").then((r) => r.text()).then(c => {
|
self.tpl[name] = await FetchHandler.loadFile(templateDir + name + '.tpl', false)
|
||||||
self.tpl[name] = c;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +34,7 @@ class Template {
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFromAPI(url, name, cb) {
|
|
||||||
fetch(url).then((r) => r.json()).then(d => {
|
|
||||||
cb(this.parseTemplate(name, d))
|
|
||||||
}).catch(console.error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateEx = /\$(.*?)\$/gm;
|
const templateEx = /\$(.*?)\$/gm;
|
||||||
const templateDir = "out/tpl/"
|
const templateDir = "/out/tpl/"
|
|
@ -6,13 +6,15 @@ class Wave2D extends Visual {
|
||||||
|
|
||||||
updateData() {
|
updateData() {
|
||||||
let data = audioHandler.getFloatArray();
|
let data = audioHandler.getFloatArray();
|
||||||
let add = 2 / data.length,
|
let add = c.width / data.length,
|
||||||
x = -1;
|
x = 0,
|
||||||
|
y = c.height / 2,
|
||||||
|
goTrough = y / 2;
|
||||||
let outerLoop = 0;
|
let outerLoop = 0;
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
//first
|
//first
|
||||||
this.data[outerLoop] = x;
|
this.data[outerLoop] = x;
|
||||||
this.data[outerLoop + 1] = data[i];
|
this.data[outerLoop + 1] = y + (data[i] * goTrough);
|
||||||
this.data[outerLoop + 2] = data[i];
|
this.data[outerLoop + 2] = data[i];
|
||||||
outerLoop += 3;
|
outerLoop += 3;
|
||||||
x += add;
|
x += add;
|
||||||
|
@ -35,17 +37,18 @@ class Wave2D extends Visual {
|
||||||
}
|
}
|
||||||
|
|
||||||
rotate(program) {
|
rotate(program) {
|
||||||
let matrix = [
|
let glHelper = new GLHelper(program);
|
||||||
1, 0, 0, 0,
|
glHelper.project();
|
||||||
0, 0.6, 0, 0,
|
glHelper.addFudgeFactor(vConf.get("fudgeFactor", 1));
|
||||||
0, 0, 1, 0,
|
glHelper.translate([
|
||||||
0, 0, 0, 1
|
camera.translate.x,
|
||||||
]
|
camera.translate.y,
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.xRotation(vConf.get("rotation-x", 0)));
|
camera.translate.z
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.yRotation(vConf.get("rotation-y", 0)));
|
]);
|
||||||
matrix = TDUtils.multiply(matrix, TDUtils.zRotation(vConf.get("rotation-z", 0)));
|
glHelper.rotateX(camera.mouse.x);
|
||||||
let rotate = gl.getUniformLocation(program, "u_matrix");
|
glHelper.rotateY(camera.mouse.y);
|
||||||
gl.uniformMatrix4fv(rotate, false, matrix);
|
glHelper.rotateZ(vConf.get("rotation-z", 0));
|
||||||
|
glHelper.applyMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -59,9 +62,8 @@ class Wave2D extends Visual {
|
||||||
|
|
||||||
prepare(program) {
|
prepare(program) {
|
||||||
this.position = gl.getAttribLocation(program, "a_position");
|
this.position = gl.getAttribLocation(program, "a_position");
|
||||||
this.color = gl.getUniformLocation(program, "u_color");
|
//GLHelper.uniform1f(program, "u_fudgeFactor", vConf.get("fudgeFactor", 1));
|
||||||
let lightPos = gl.getUniformLocation(program, "u_lightPos");
|
GLHelper.uniform3fv(program, "u_lightPos", vConf.get("light", [0, 5, -56]));
|
||||||
gl.uniform3fv(lightPos, vConf.get("light", [0, 5, -56]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afterDraw() {
|
afterDraw() {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
in vec3 a_position;
|
in vec3 a_position;
|
||||||
uniform mat4 u_matrix;
|
uniform mat4 u_matrix;
|
||||||
|
uniform float u_fudgeFactor;
|
||||||
|
|
||||||
out vec4 pos;
|
out vec4 pos;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
pos = u_matrix * vec4(a_position, 1);
|
pos = u_matrix * vec4(a_position, 1);
|
||||||
pos.y = pos.y * 0.6;
|
|
||||||
gl_Position = pos;
|
gl_Position = pos;
|
||||||
}
|
}
|
44
sw.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
const cacheName = 'vis3d-pwa-1',
|
||||||
|
FILES_TO_CACHE = [
|
||||||
|
'/index.html',
|
||||||
|
'/empty.txt'
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', function (e) {
|
||||||
|
e.waitUntil(
|
||||||
|
caches.open(cacheName).then(function (cache) {
|
||||||
|
return cache.addAll(FILES_TO_CACHE);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function (event) {
|
||||||
|
if (event.request.method !== 'GET') return;
|
||||||
|
event.respondWith(handle.bind(event).call().then(r => {
|
||||||
|
return r
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handle() {
|
||||||
|
let event = this,
|
||||||
|
url = event.request.url;
|
||||||
|
if (url === self.registration.scope) {
|
||||||
|
url += 'index.html';
|
||||||
|
}
|
||||||
|
const cache = await caches.open(cacheName);
|
||||||
|
let response = await fetch(url).then((r) => {
|
||||||
|
return r
|
||||||
|
}).catch(async err => {
|
||||||
|
let cachedResponse = await cache.match(url);
|
||||||
|
if (cachedResponse) {
|
||||||
|
return cachedResponse;
|
||||||
|
}
|
||||||
|
cachedResponse = await cache.match('/empty.txt');
|
||||||
|
return cachedResponse;
|
||||||
|
});
|
||||||
|
if (response) {
|
||||||
|
await cache.put(event.request, response.clone());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|