Skip to content

Commit

Permalink
Implement router and several pages with several things
Browse files Browse the repository at this point in the history
  • Loading branch information
rexim committed May 16, 2021
1 parent 61673ea commit e812298
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 6 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</head>
<body>
<div id="entry"></div>
<script src="webgl.js"></script>
<script src="tag.js"></script>
</body>
</html>
Binary file added monkaMEGA.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 95 additions & 6 deletions tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do e
function tag(name, ...children) {
const result = document.createElement(name);
for (const child of children) {
if (typeof(child) === 'string') {
throw new Error('Looks like you are trying to add string as the tag component. Wrap it with the text() function to turn the string into the Text Node');
}
result.appendChild(child);
}

Expand All @@ -23,6 +26,10 @@ function text(s) {
return document.createTextNode(s);
}

function canvas(...children) {
return tag("canvas", ...children);
}

function h1(...children) {
return tag("h1", ...children);
}
Expand Down Expand Up @@ -109,11 +116,93 @@ function tabs(ts) {
);
}

function router(routes) {
let result = div(text("Hash is not synced!"));

result.syncHash$ = function() {
let hashLocation = document.location.hash.split('#')[1];
if (!hashLocation) {
hashLocation = '/';
}

if (!(hashLocation in routes)) {
const route404 = '/404';
console.assert(route404 in routes);
hashLocation = route404;
}

while (this.firstChild) {
this.removeChild(this.lastChild);
}
this.appendChild(routes[hashLocation]);
};

return result;
}

function webglPreview() {
const PREVIEW_WIDTH = 112;
const PREVIEW_HEIGHT = 112;
const previewCanvas = canvas()
.att$("width", PREVIEW_WIDTH)
.att$("height", PREVIEW_HEIGHT);
const gl = previewCanvas.getContext("webgl");

if (!gl) {
throw new Error("Could not initialize WebGL context");
}

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

prepareMeshPositionAttribute(gl);
prepareShaders(gl)

gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.drawArrays(gl.TRIANGLES, 0, TRIANGLE_PAIR * TRIANGLE_VERTICIES);

return div(
h1(text("Simple WebGL Component")),
previewCanvas
)
}

window.onload = () => {
entry.appendChild(tabs({
"jebaited": jebaited(),
"blogpost": blogpost(),
"forsen1": forsen1(),
"lorem": div(text(LOREM)),
}));
const app = router({
"/": div(
tabs({
"jebaited": jebaited(),
"blogpost": blogpost(),
"forsen1": forsen1(),
"lorem": div(text(LOREM)),
}),
div(
h2(text("Other Pages")),
div(a(text("secret page")).att$("href", "#/secret")),
div(a(text("webgl page")).att$("href", "#/webgl")),
)
),
"/secret": div(
p(text("This is a secret page! What are you doing in here!")),
img("monkaMEGA.png"),
p(a(text("Back to Home")).att$('href', '#'))
),
"/webgl": div(
webglPreview(),
p(a(text("Back to Home")).att$('href', '#'))
),
"/404": div(
p(text("Path is not found")),
p(a(text("Back to Home")).att$('href', '#'))
)
});

app.syncHash$();
window.addEventListener("hashchange", () => {
app.syncHash$();
});

entry.appendChild(app);
}
113 changes: 113 additions & 0 deletions webgl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const vertexAttribs = {
"meshPosition": 0
};

const TRIANGLE_PAIR = 2;
const TRIANGLE_VERTICIES = 3;
const VEC2_COUNT = 2;
const VEC2_X = 0;
const VEC2_Y = 1;

function shaderTypeToString(gl, shaderType) {
switch (shaderType) {
case gl.VERTEX_SHADER: return 'Vertex';
case gl.FRAGMENT_SHADER: return 'Fragment';
default: return shaderType;
}
}

function compileShaderSource(gl, source, shaderType) {
const shader = gl.createShader(shaderType);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(`Could not compile ${shaderTypeToString(shaderType)} shader: ${gl.getShaderInfoLog(shader)}`);
}
return shader;
}


function linkShaderProgram(gl, shaders, vertexAttribs) {
const program = gl.createProgram();
for (let shader of shaders) {
gl.attachShader(program, shader);
}

for (let vertexName in vertexAttribs) {
gl.bindAttribLocation(program, vertexAttribs[vertexName], vertexName);
}

gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(`Could not link shader program: ${gl.getProgramInfoLog(program)}`);
}
return program;
}

function prepareMeshPositionAttribute(gl) {
let meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT);
for (let triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) {
for (let vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) {
const quad = triangle + vertex;
const index =
triangle * TRIANGLE_VERTICIES * VEC2_COUNT +
vertex * VEC2_COUNT;
meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1);
meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1);
}
}

let meshPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW);

const meshPositionAttrib = vertexAttribs['meshPosition'];
gl.vertexAttribPointer(
meshPositionAttrib,
VEC2_COUNT,
gl.FLOAT,
false,
0,
0);
gl.enableVertexAttribArray(meshPositionAttrib);
}


const vertexShaderSource = `#version 100
precision mediump float;
attribute vec2 meshPosition;
varying vec2 uv;
void main() {
gl_Position = vec4(meshPosition, 0.0, 1.0);
uv = (meshPosition + 1.0) / 2.0;
}
`;

const fragmentShaderSource = `#version 100
precision mediump float;
varying vec2 uv;
vec3 hsl2rgb(vec3 c) {
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0);
return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
}
void main() {
vec4 rainbow = vec4(hsl2rgb(vec3((uv.x - uv.y) * 0.5, 1.0, 0.80)), 1.0);
gl_FragColor = rainbow;
}
`;

function prepareShaders(gl) {
let vertexShader = compileShaderSource(gl, vertexShaderSource, gl.VERTEX_SHADER);
let fragmentShader = compileShaderSource(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
let id = linkShaderProgram(gl, [vertexShader, fragmentShader], vertexAttribs);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
gl.useProgram(id);
}

0 comments on commit e812298

Please sign in to comment.