Skip to content

Instantly share code, notes, and snippets.

@okaq
Created May 10, 2014 11:58
Show Gist options
  • Save okaq/b9593f7cbec514a7d4f7 to your computer and use it in GitHub Desktop.
Save okaq/b9593f7cbec514a7d4f7 to your computer and use it in GitHub Desktop.
Vobu Glyph Sample
<!DOCTYPE html>
<html lang="en">
<!-- manifest="vobu.appcache" -->
<head id="zeta">
<title>okaq</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=1920,height=1080,initial-scale=1"/>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAMklEQVR4nGJxzPzPQEvARFPTRy0YtWDUglELRi0YtWDUglELRi0YtWDUAioCQAAAAP//0ssB7LPxfD4AAAAASUVORK5CYII=" />
<style type="text/css">
html,body{width:1920px;height:1080px;background-color:rgba(255,255,255,1.0);}
</style>
<script type="text/javascript">
// ok
console.log("hello vobu!");
// async_load
(function() {
var async_load = function() {
g.init();
}
window.addEventListener("load", async_load, false);
})();
// game
var g = {
"init": function() {
console.log("g init");
d.init();
g.m0 = 16;
g.c0 = c.list(g.m0);
// console.log(g.c0);
// g.id = window.setInterval(r.render, 1000);
r.render();
d.gamma();
r.sample();
}
}
// dom
var d = {
"init": function() {
d.alpha = document.getElementById("alpha");
d.beta = {};
d.beta.can = document.createElement("canvas");
d.beta.con = d.beta.can.getContext("2d");
// console.log(d.beta.can, d.beta.con);
d.beta.can.width = 786;
d.beta.can.height = 786;
d.beta.can.style.position = "absolute";
d.beta.can.style.top = "64px";
d.beta.can.style.left = "128px";
d.alpha.appendChild(d.beta.can);
d.beta.con.fillStyle = "rgba(0,0,0,1.0)";
d.beta.con.fillRect(0,0,d.beta.can.width,d.beta.can.height);
},
"gamma": function() {
d.gamma = {};
d.gamma.can = document.createElement("canvas");
d.gamma.con = d.gamma.can.getContext("2d");
console.log(d.gamma.can, d.gamma.con);
d.gamma.can.width = 384;
d.gamma.can.height = 384;
d.gamma.can.style.position = "absolute";
d.gamma.can.style.top = "108px";
d.gamma.can.style.left = "960px";
d.alpha.appendChild(d.gamma.can);
d.gamma.con.fillStyle = c.rgba(1.0);
d.gamma.con.fillRect(0,0,d.gamma.can.width,d.gamma.can.height);
// 1. icon font bitmap offscreen sample
d.off = {};
d.off.can = document.createElement("canvas");
d.off.con = d.off.can.getContext("2d");
console.log(d.off.can, d.off.con);
d.off.can.width = 384;
d.off.can.height = 384;
d.off.can.style.position = "absolute";
d.off.can.style.top = "108px";
d.off.can.style.left = "1400px";
d.alpha.appendChild(d.off.can);
d.off.con.fillStyle = c.rgba();
d.off.con.fillRect(0,0,d.off.can.width,d.off.can.height);
// 2. vector generation from random field
}
}
// render
var r = {
"render": function() {
d.beta.can = d.beta.can;
// var m0 = 16;
var x0 = (d.beta.can.width / (2*g.m0)) >>> 0;
// var c0 = c.list(m0);
c.step(g.c0);
for (var i = 0; i < g.m0; i++) {
// var c0 = c.rgba(1.0);
// console.log(c0);
// c.step(c0);
d.beta.con.fillStyle = g.c0[i];
var m1 = x0 * i;
var m2 = d.beta.can.width - 2*m1;
// console.log(m1,m2);
d.beta.con.fillRect(m1,m1,m2,m2);
}
},
"sample": function() {
d.off.con.fillStyle = "rgba(0,0,0,1.0)";
d.off.con.fillRect(0,0,d.off.can.width,d.off.can.height);
d.off.con.font = "300px Ubuntu, Arial, Helvetica";
d.off.con.textBaseline = "top";
// d.off.text = uni.rand(0x3040, 0x30ff);
d.off.text = uni.rand(0x4e00, 0x4eff);
// console.log(d.off.text);
d.off.con.fillStyle = "rgba(255,255,255,1.0)";
d.off.con.fillText(d.off.text, 48, 24);
// center glyph in onscreen texture
d.off.imagedata = d.off.con.getImageData(0,0,d.off.can.width,d.off.can.height);
d.off.data = d.off.imagedata.data;
// console.log(d.off.imagedata, d.off.data.length);
d.off.s = 16; // sample size
d.off.blocks = new Array(d.off.s*d.off.s);
d.off.w = (d.off.can.width / d.off.s) >>> 0;
d.off.h = (d.off.can.height / d.off.s) >>> 0;
for (var i = 0; i < d.off.blocks.length; i++) { // d.off.blocks.length; i++) {
var x0 = i % d.off.s;
var y0 = (i / d.off.s) >>> 0;
var x1 = x0 * d.off.w;
var y1 = y0 * d.off.h;
var i0 = y1 * d.off.can.height + x1; // err: d.off.h
var i1 = i0 * 4;
// console.log(d.off.data[i1]);
// one point is under sampling
// sample entire block and tally white/black
// then select based on threshold
// console.log(x0,y0,x1,y1,i0,i1);
// console.log(x1+d.off.w,y1+d.off.h);
// can sample size = 0.10 * block pixel size
var bc = 0;
var wc = 0;
for (var y2 = y1; y2 < (y1 + d.off.h); y2++) {
for (var x2 = x1; x2 < (x1 + d.off.w); x2++) {
var i2 = y2 * d.off.can.height + x2;
var i3 = i2 * 4;
// console.log(x2,y2,i3);
if (d.off.data[i3] == 0) {
bc = bc + 1;
}
else {
wc = wc + 1;
}
/*
if (d.off.data[i3] == 255) {
wc = wc + 1;
}
*/
}
}
if (wc > 0) {
d.gamma.con.fillStyle = c.rgba();
d.gamma.con.fillRect(x1, y1, d.off.w, d.off.h);
}
console.log(bc, wc);
}
var w0 = 0;
var b0 = 0;
for (var i = 0; i < d.off.data.length; i++) {
if (d.off.data[i] == 0) {
b0 = b0 + 1;
} else {
w0 = w0 + 1;
}
}
console.log(b0, w0);
}
}
// color
var c = {
"rgba": function(a1) {
var r0 = c.rb();
var g0 = c.rb();
var b0 = c.rb();
var a0 = Math.random() || a1;
var s0 = [r0,g0,b0,a0].join(",");
var s1 = "rgba(" + s0 + ")";
return s1;
},
"rb": function() {
// rand byte
return (Math.random() * 255) >>> 0;
},
"list": function(n0) {
var c0 = []; // new Array(n0);
for (var i = 0; i < n0; i++) {
c0[i] = c.rgba(1.0);
}
return c0;
},
"step": function(c0) {
for (var i = c0.length - 1; i > 0; i--) {
c0[i] = c0[i-1];
}
c0[0] = c.rgba(1.0);
}
}
// unicode
var uni = {
"rand": function(lo, hi) {
// return random unicode
// code point in range{lo,hi}
var d0 = (hi - lo) >>> 0;
var d1 = ((Math.random() * d0) + lo) >>> 0;
return String.fromCharCode(d1);
}
}
</script>
</head>
<body id="alpha">
</body>
</html>
CACHE MANIFEST
# AQ <[email protected]>
# v1 : 2014-05-07
# NETWORK:
# http://localhost:8008/
/*
* Golang Web Server
* AQ <[email protected]>
* 2014-05-01
*/
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
)
const (
MOTD = "vobu"
AINA = "aina.html"
PORT = ":8008"
APPCACHE = "vobu.appcache"
)
var (
Cache []byte // mutex locked on read?
err error
)
// Load HTML5 web app into cache
func Load() {
Cache, err = ioutil.ReadFile(AINA)
if err != nil {
log.Fatal(err)
}
}
// Any manual cache will need to be RWLock'd
// golang file server api uses sendfile
// and checks if file is modified
// Web server
func Serve() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// fmt.Printf("Request: %+v.\n", r)
// w.Write(Cache)
// r.Body.Close()
http.ServeFile(w, r, AINA)
})
http.HandleFunc("/vobu.appcache", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, APPCACHE)
})
log.Fatal(http.ListenAndServe(PORT, nil))
}
func main() {
fmt.Printf("Greetings %s!\nStarting web server on port: %s.\n", MOTD, PORT)
Load()
runtime.GOMAXPROCS(runtime.NumCPU())
Serve()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment