You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
thebookofshaders/edit.html

220 lines
6.3 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GLSL Shader Code Editor</title>
<!-- CodeMirror -->
<link type='text/css' rel='stylesheet' href="src/codemirror/css/codemirror.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/fold/foldgutter.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/dialog/dialog.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/hint/show-hint.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/theme/monokai.css">
<script type="text/javascript" src="src/codemirror.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/searchcursor.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/search.js"></script>
<script type="text/javascript" src="src/codemirror/addon/dialog/dialog.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/matchbrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/comment/comment.js"></script>
<script type="text/javascript" src="src/codemirror/addon/wrap/hardwrap.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/foldcode.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/brace-fold.js"></script>
<script type="text/javascript" src="src/codemirror/keymap/sublime.js"></script>
<script type="text/javascript" src="src/codemirror/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
<!-- GLSL Canvas -->
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
<style>
body {
background: #272822;
}
h1 {
color: white;
font-family: Courier, Arial;
}
pre {
font-size: 130%;
}
canvas.right {
position: fixed;
right: 10px;
top: 10px;
background-color: #fff;
border-radius: 15px;
overflow: hidden;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
.CodeMirror {
font-size: 110%;
line-height: 1.3;
right: 10px;
height: 100%;
}
.CodeMirror-linenumbers {
padding: 0 8px;
}
</style>
</head>
<body>
<h1 id="title" >FILE NAME.frag</h1>
<div id="editor"></div>
<canvas id="canvas" class="right" width="500" height="500"></canvas>
<script type="text/javascript">
window.addEventListener("hashchange", function () {
loadTag()
}, false);
var editor;
var billboard;
var imgs = [];
function fetchHTTP(url, methood){
var request = new XMLHttpRequest(), response;
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
response = request.responseText;
}
}
request.open(methood ? methood : 'GET', url, false);
request.overrideMimeType("text/plain");
request.send(null);
return response;
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
function loadTag(){
var fragShader = "";
var fragFile = "";
while(imgs.length > 0) {
imgs.pop();
}
removeElementsByClass("CodeMirror");
if( window.location.hash === "" ){
fragShader = "#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
\n\
uniform vec2 u_resolution;\n\
uniform vec2 u_mouse;\n\
uniform float u_time;\n\
\n\
void main(){\n\
vec2 st = gl_FragCoord.xy/u_resolution.xy;\n\
gl_FragColor = vec4(st.x,st.y,0.0,1.0);\n\
}";
} else {
var hashes = location.hash.split('&');
for(i in hashes){
var ext = hashes[i].substr(hashes[i].lastIndexOf('.') + 1);
var name = hashes[i];
// Extract hash if is present
if(name.search("#") === 0){
name = name.substr(1);
}
if(ext == "frag"){
fragFile = name;
fragShader = fetchHTTP(fragFile);
} else if (ext == "png" || ext == "jpg" || ext == "PNG" || ext == "JPG" ){
imgs.push(hashes[i]);
}
}
}
var demoTitle = document.getElementById("title");
if(demoTitle){
demoTitle.innerText = fragFile;
}
var demoCanvas = document.getElementById("canvas");
if (demoCanvas && fragShader !== "") {
demoCanvas.setAttribute("data-fragment-url", fragFile);
if (imgs.length > 0) {
var textureList = "";
for (i in imgs) {
textureList += imgs[i];
textureList += (i < imgs.length-1)?",":"";
}
demoCanvas.setAttribute("data-textures",textureList);
console.log("data-textures: " + textureList);
}
billboard = new GlslCanvas(demoCanvas);
}
var demoEditor = document.getElementById("editor");
if (demoEditor) {
editor = CodeMirror(demoEditor,{
value: fragShader,
lineNumbers: true,
matchBrackets: true,
mode: "x-shader/x-fragment",
keyMap: "sublime",
autoCloseBrackets: true,
extraKeys: {"Ctrl-Space": "autocomplete"},
showCursorWhenSelecting: true,
theme: "monokai",
indentUnit: 4
});
editor.on("change", function() {
demoCanvas.setAttribute("data-fragment", editor.getValue());
billboard.load(editor.getValue());
});
}
}
window.onload = function () {
loadTag();
render();
};
function render() {
billboard.setMouse(mouse)
billboard.render()
window.requestAnimFrame(render);
}
</script>
</body>
</html>