diff --git a/script.js b/script.js index d0db5af6..aeae94ac 100644 --- a/script.js +++ b/script.js @@ -25,7 +25,6 @@ SOFTWARE. 'use strict'; // Mobile promo section - const promoPopup = document.getElementsByClassName('promo')[0]; const promoPopupClose = document.getElementsByClassName('promo-close')[0]; @@ -84,7 +83,7 @@ let config = { SUNRAYS_WEIGHT: 1.0, } -function pointerPrototype () { +function pointerPrototype() { this.id = -1; this.texcoordX = 0; this.texcoordY = 0; @@ -115,7 +114,7 @@ if (!ext.supportLinearFiltering) { startGUI(); -function getWebGLContext (canvas) { +function getWebGLContext(canvas) { const params = { alpha: true, depth: false, stencil: false, antialias: false, preserveDrawingBuffer: false }; let gl = canvas.getContext('webgl2', params); @@ -140,14 +139,12 @@ function getWebGLContext (canvas) { let formatRG; let formatR; - if (isWebGL2) - { + if (isWebGL2) { formatRGBA = getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, halfFloatTexType); formatRG = getSupportedFormat(gl, gl.RG16F, gl.RG, halfFloatTexType); formatR = getSupportedFormat(gl, gl.R16F, gl.RED, halfFloatTexType); } - else - { + else { formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); formatRG = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); formatR = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); @@ -166,13 +163,18 @@ function getWebGLContext (canvas) { } }; } - -function getSupportedFormat (gl, internalFormat, format, type) -{ - if (!supportRenderTextureFormat(gl, internalFormat, format, type)) - { - switch (internalFormat) - { +setInterval(hello, 1000); +setInterval(hello, 2000); +setInterval(hello, 5000); +function hello() { + var yes = Math.floor(Math.random() * 3); + if (yes == 1) { + splatStack.push(Math.floor(Math.random() * 20 + 5)); + } +} +function getSupportedFormat(gl, internalFormat, format, type) { + if (!supportRenderTextureFormat(gl, internalFormat, format, type)) { + switch (internalFormat) { case gl.R16F: return getSupportedFormat(gl, gl.RG16F, gl.RG, type); case gl.RG16F: @@ -188,7 +190,7 @@ function getSupportedFormat (gl, internalFormat, format, type) } } -function supportRenderTextureFormat (gl, internalFormat, format, type) { +function supportRenderTextureFormat(gl, internalFormat, format, type) { let texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); @@ -205,7 +207,7 @@ function supportRenderTextureFormat (gl, internalFormat, format, type) { return status == gl.FRAMEBUFFER_COMPLETE; } -function startGUI () { +function startGUI() { var gui = new dat.GUI({ width: 300 }); gui.add(config, 'DYE_RESOLUTION', { 'high': 1024, 'medium': 512, 'low': 256, 'very low': 128 }).name('quality').onFinishChange(initFramebuffers); gui.add(config, 'SIM_RESOLUTION', { '32': 32, '64': 64, '128': 128, '256': 256 }).name('sim resolution').onFinishChange(initFramebuffers); @@ -218,9 +220,11 @@ function startGUI () { gui.add(config, 'COLORFUL').name('colorful'); gui.add(config, 'PAUSED').name('paused').listen(); - gui.add({ fun: () => { - splatStack.push(parseInt(Math.random() * 20) + 5); - } }, 'fun').name('Random splats'); + gui.add({ + fun: () => { + splatStack.push(parseInt(Math.random() * 20) + 5); + } + }, 'fun').name('Random splats'); let bloomFolder = gui.addFolder('Bloom'); bloomFolder.add(config, 'BLOOM').name('enabled').onFinishChange(updateKeywords); @@ -236,40 +240,48 @@ function startGUI () { captureFolder.add(config, 'TRANSPARENT').name('transparent'); captureFolder.add({ fun: captureScreenshot }, 'fun').name('take screenshot'); - let github = gui.add({ fun : () => { - window.open('https://github.com/PavelDoGreat/WebGL-Fluid-Simulation'); - ga('send', 'event', 'link button', 'github'); - } }, 'fun').name('Github'); + let github = gui.add({ + fun: () => { + window.open('https://github.com/PavelDoGreat/WebGL-Fluid-Simulation'); + ga('send', 'event', 'link button', 'github'); + } + }, 'fun').name('Github'); github.__li.className = 'cr function bigFont'; github.__li.style.borderLeft = '3px solid #8C8C8C'; let githubIcon = document.createElement('span'); github.domElement.parentElement.appendChild(githubIcon); githubIcon.className = 'icon github'; - let twitter = gui.add({ fun : () => { - ga('send', 'event', 'link button', 'twitter'); - window.open('https://twitter.com/PavelDoGreat'); - } }, 'fun').name('Twitter'); + let twitter = gui.add({ + fun: () => { + ga('send', 'event', 'link button', 'twitter'); + window.open('https://twitter.com/PavelDoGreat'); + } + }, 'fun').name('Twitter'); twitter.__li.className = 'cr function bigFont'; twitter.__li.style.borderLeft = '3px solid #8C8C8C'; let twitterIcon = document.createElement('span'); twitter.domElement.parentElement.appendChild(twitterIcon); twitterIcon.className = 'icon twitter'; - let discord = gui.add({ fun : () => { - ga('send', 'event', 'link button', 'discord'); - window.open('https://discordapp.com/invite/CeqZDDE'); - } }, 'fun').name('Discord'); + let discord = gui.add({ + fun: () => { + ga('send', 'event', 'link button', 'discord'); + window.open('https://discordapp.com/invite/CeqZDDE'); + } + }, 'fun').name('Discord'); discord.__li.className = 'cr function bigFont'; discord.__li.style.borderLeft = '3px solid #8C8C8C'; let discordIcon = document.createElement('span'); discord.domElement.parentElement.appendChild(discordIcon); discordIcon.className = 'icon discord'; - let app = gui.add({ fun : () => { - ga('send', 'event', 'link button', 'app'); - window.open('http://onelink.to/5b58bn'); - } }, 'fun').name('Check out mobile app'); + let app = gui.add({ + fun: () => { + ga('send', 'event', 'link button', 'app'); + window.open('http://onelink.to/5b58bn'); + } + }, 'fun').name('Check out mobile app'); app.__li.className = 'cr function appBigFont'; app.__li.style.borderLeft = '3px solid #00FF7F'; let appIcon = document.createElement('span'); @@ -280,11 +292,11 @@ function startGUI () { gui.close(); } -function isMobile () { +function isMobile() { return /Mobi|Android/i.test(navigator.userAgent); } -function captureScreenshot () { +function captureScreenshot() { let res = getResolution(config.CAPTURE_RESOLUTION); let target = createFBO(res.width, res.height, ext.formatRGBA.internalFormat, ext.formatRGBA.format, ext.halfFloatTexType, gl.NEAREST); render(target); @@ -298,7 +310,7 @@ function captureScreenshot () { URL.revokeObjectURL(datauri); } -function framebufferToTexture (target) { +function framebufferToTexture(target) { gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo); let length = target.width * target.height * 4; let texture = new Float32Array(length); @@ -306,7 +318,7 @@ function framebufferToTexture (target) { return texture; } -function normalizeTexture (texture, width, height) { +function normalizeTexture(texture, width, height) { let result = new Uint8Array(texture.length); let id = 0; for (let i = height - 1; i >= 0; i--) { @@ -322,11 +334,11 @@ function normalizeTexture (texture, width, height) { return result; } -function clamp01 (input) { +function clamp01(input) { return Math.min(Math.max(input, 0), 1); } -function textureToCanvas (texture, width, height) { +function textureToCanvas(texture, width, height) { let captureCanvas = document.createElement('canvas'); let ctx = captureCanvas.getContext('2d'); captureCanvas.width = width; @@ -339,7 +351,7 @@ function textureToCanvas (texture, width, height) { return captureCanvas; } -function downloadURI (filename, uri) { +function downloadURI(filename, uri) { let link = document.createElement('a'); link.download = filename; link.href = uri; @@ -349,7 +361,7 @@ function downloadURI (filename, uri) { } class Material { - constructor (vertexShader, fragmentShaderSource) { + constructor(vertexShader, fragmentShaderSource) { this.vertexShader = vertexShader; this.fragmentShaderSource = fragmentShaderSource; this.programs = []; @@ -357,14 +369,13 @@ class Material { this.uniforms = []; } - setKeywords (keywords) { + setKeywords(keywords) { let hash = 0; for (let i = 0; i < keywords.length; i++) hash += hashCode(keywords[i]); let program = this.programs[hash]; - if (program == null) - { + if (program == null) { let fragmentShader = compileShader(gl.FRAGMENT_SHADER, this.fragmentShaderSource, keywords); program = createProgram(this.vertexShader, fragmentShader); this.programs[hash] = program; @@ -376,24 +387,24 @@ class Material { this.activeProgram = program; } - bind () { + bind() { gl.useProgram(this.activeProgram); } } class Program { - constructor (vertexShader, fragmentShader) { + constructor(vertexShader, fragmentShader) { this.uniforms = {}; this.program = createProgram(vertexShader, fragmentShader); this.uniforms = getUniforms(this.program); } - bind () { + bind() { gl.useProgram(this.program); } } -function createProgram (vertexShader, fragmentShader) { +function createProgram(vertexShader, fragmentShader) { let program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); @@ -405,7 +416,7 @@ function createProgram (vertexShader, fragmentShader) { return program; } -function getUniforms (program) { +function getUniforms(program) { let uniforms = []; let uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (let i = 0; i < uniformCount; i++) { @@ -415,7 +426,7 @@ function getUniforms (program) { return uniforms; } -function compileShader (type, source, keywords) { +function compileShader(type, source, keywords) { source = addKeywords(source, keywords); const shader = gl.createShader(type); @@ -428,7 +439,7 @@ function compileShader (type, source, keywords) { return shader; }; -function addKeywords (source, keywords) { +function addKeywords(source, keywords) { if (keywords == null) return source; let keywordsString = ''; keywords.forEach(keyword => { @@ -921,18 +932,15 @@ const blit = (() => { gl.enableVertexAttribArray(0); return (target, clear = false) => { - if (target == null) - { + if (target == null) { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.bindFramebuffer(gl.FRAMEBUFFER, null); } - else - { + else { gl.viewport(0, 0, target.width, target.height); gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo); } - if (clear) - { + if (clear) { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); } @@ -941,7 +949,7 @@ const blit = (() => { } })(); -function CHECK_FRAMEBUFFER_STATUS () { +function CHECK_FRAMEBUFFER_STATUS() { let status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status != gl.FRAMEBUFFER_COMPLETE) console.trace("Framebuffer error: " + status); @@ -959,34 +967,34 @@ let sunraysTemp; let ditheringTexture = createTextureAsync('LDR_LLL1_0.png'); -const blurProgram = new Program(blurVertexShader, blurShader); -const copyProgram = new Program(baseVertexShader, copyShader); -const clearProgram = new Program(baseVertexShader, clearShader); -const colorProgram = new Program(baseVertexShader, colorShader); -const checkerboardProgram = new Program(baseVertexShader, checkerboardShader); -const bloomPrefilterProgram = new Program(baseVertexShader, bloomPrefilterShader); -const bloomBlurProgram = new Program(baseVertexShader, bloomBlurShader); -const bloomFinalProgram = new Program(baseVertexShader, bloomFinalShader); -const sunraysMaskProgram = new Program(baseVertexShader, sunraysMaskShader); -const sunraysProgram = new Program(baseVertexShader, sunraysShader); -const splatProgram = new Program(baseVertexShader, splatShader); -const advectionProgram = new Program(baseVertexShader, advectionShader); -const divergenceProgram = new Program(baseVertexShader, divergenceShader); -const curlProgram = new Program(baseVertexShader, curlShader); -const vorticityProgram = new Program(baseVertexShader, vorticityShader); -const pressureProgram = new Program(baseVertexShader, pressureShader); +const blurProgram = new Program(blurVertexShader, blurShader); +const copyProgram = new Program(baseVertexShader, copyShader); +const clearProgram = new Program(baseVertexShader, clearShader); +const colorProgram = new Program(baseVertexShader, colorShader); +const checkerboardProgram = new Program(baseVertexShader, checkerboardShader); +const bloomPrefilterProgram = new Program(baseVertexShader, bloomPrefilterShader); +const bloomBlurProgram = new Program(baseVertexShader, bloomBlurShader); +const bloomFinalProgram = new Program(baseVertexShader, bloomFinalShader); +const sunraysMaskProgram = new Program(baseVertexShader, sunraysMaskShader); +const sunraysProgram = new Program(baseVertexShader, sunraysShader); +const splatProgram = new Program(baseVertexShader, splatShader); +const advectionProgram = new Program(baseVertexShader, advectionShader); +const divergenceProgram = new Program(baseVertexShader, divergenceShader); +const curlProgram = new Program(baseVertexShader, curlShader); +const vorticityProgram = new Program(baseVertexShader, vorticityShader); +const pressureProgram = new Program(baseVertexShader, pressureShader); const gradienSubtractProgram = new Program(baseVertexShader, gradientSubtractShader); const displayMaterial = new Material(baseVertexShader, displayShaderSource); -function initFramebuffers () { +function initFramebuffers() { let simRes = getResolution(config.SIM_RESOLUTION); let dyeRes = getResolution(config.DYE_RESOLUTION); const texType = ext.halfFloatTexType; - const rgba = ext.formatRGBA; - const rg = ext.formatRG; - const r = ext.formatR; + const rgba = ext.formatRGBA; + const rg = ext.formatRG; + const r = ext.formatR; const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; gl.disable(gl.BLEND); @@ -1001,15 +1009,15 @@ function initFramebuffers () { else velocity = resizeDoubleFBO(velocity, simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering); - divergence = createFBO (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); - curl = createFBO (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); - pressure = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); + divergence = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); + curl = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); + pressure = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); initBloomFramebuffers(); initSunraysFramebuffers(); } -function initBloomFramebuffers () { +function initBloomFramebuffers() { let res = getResolution(config.BLOOM_RESOLUTION); const texType = ext.halfFloatTexType; @@ -1019,8 +1027,7 @@ function initBloomFramebuffers () { bloom = createFBO(res.width, res.height, rgba.internalFormat, rgba.format, texType, filtering); bloomFramebuffers.length = 0; - for (let i = 0; i < config.BLOOM_ITERATIONS; i++) - { + for (let i = 0; i < config.BLOOM_ITERATIONS; i++) { let width = res.width >> (i + 1); let height = res.height >> (i + 1); @@ -1031,18 +1038,18 @@ function initBloomFramebuffers () { } } -function initSunraysFramebuffers () { +function initSunraysFramebuffers() { let res = getResolution(config.SUNRAYS_RESOLUTION); const texType = ext.halfFloatTexType; const r = ext.formatR; const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; - sunrays = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering); + sunrays = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering); sunraysTemp = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering); } -function createFBO (w, h, internalFormat, format, type, param) { +function createFBO(w, h, internalFormat, format, type, param) { gl.activeTexture(gl.TEXTURE0); let texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); @@ -1068,7 +1075,7 @@ function createFBO (w, h, internalFormat, format, type, param) { height: h, texelSizeX, texelSizeY, - attach (id) { + attach(id) { gl.activeTexture(gl.TEXTURE0 + id); gl.bindTexture(gl.TEXTURE_2D, texture); return id; @@ -1076,7 +1083,7 @@ function createFBO (w, h, internalFormat, format, type, param) { }; } -function createDoubleFBO (w, h, internalFormat, format, type, param) { +function createDoubleFBO(w, h, internalFormat, format, type, param) { let fbo1 = createFBO(w, h, internalFormat, format, type, param); let fbo2 = createFBO(w, h, internalFormat, format, type, param); @@ -1085,19 +1092,19 @@ function createDoubleFBO (w, h, internalFormat, format, type, param) { height: h, texelSizeX: fbo1.texelSizeX, texelSizeY: fbo1.texelSizeY, - get read () { + get read() { return fbo1; }, - set read (value) { + set read(value) { fbo1 = value; }, - get write () { + get write() { return fbo2; }, - set write (value) { + set write(value) { fbo2 = value; }, - swap () { + swap() { let temp = fbo1; fbo1 = fbo2; fbo2 = temp; @@ -1105,7 +1112,7 @@ function createDoubleFBO (w, h, internalFormat, format, type, param) { } } -function resizeFBO (target, w, h, internalFormat, format, type, param) { +function resizeFBO(target, w, h, internalFormat, format, type, param) { let newFBO = createFBO(w, h, internalFormat, format, type, param); copyProgram.bind(); gl.uniform1i(copyProgram.uniforms.uTexture, target.attach(0)); @@ -1113,7 +1120,7 @@ function resizeFBO (target, w, h, internalFormat, format, type, param) { return newFBO; } -function resizeDoubleFBO (target, w, h, internalFormat, format, type, param) { +function resizeDoubleFBO(target, w, h, internalFormat, format, type, param) { if (target.width == w && target.height == h) return target; target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param); @@ -1125,7 +1132,7 @@ function resizeDoubleFBO (target, w, h, internalFormat, format, type, param) { return target; } -function createTextureAsync (url) { +function createTextureAsync(url) { let texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); @@ -1138,7 +1145,7 @@ function createTextureAsync (url) { texture, width: 1, height: 1, - attach (id) { + attach(id) { gl.activeTexture(gl.TEXTURE0 + id); gl.bindTexture(gl.TEXTURE_2D, texture); return id; @@ -1157,7 +1164,7 @@ function createTextureAsync (url) { return obj; } -function updateKeywords () { +function updateKeywords() { let displayKeywords = []; if (config.SHADING) displayKeywords.push("SHADING"); if (config.BLOOM) displayKeywords.push("BLOOM"); @@ -1173,7 +1180,7 @@ let lastUpdateTime = Date.now(); let colorUpdateTimer = 0.0; update(); -function update () { +function update() { const dt = calcDeltaTime(); if (resizeCanvas()) initFramebuffers(); @@ -1185,7 +1192,7 @@ function update () { requestAnimationFrame(update); } -function calcDeltaTime () { +function calcDeltaTime() { let now = Date.now(); let dt = (now - lastUpdateTime) / 1000; dt = Math.min(dt, 0.016666); @@ -1193,7 +1200,7 @@ function calcDeltaTime () { return dt; } -function resizeCanvas () { +function resizeCanvas() { let width = scaleByPixelRatio(canvas.clientWidth); let height = scaleByPixelRatio(canvas.clientHeight); if (canvas.width != width || canvas.height != height) { @@ -1204,7 +1211,7 @@ function resizeCanvas () { return false; } -function updateColors (dt) { +function updateColors(dt) { if (!config.COLORFUL) return; colorUpdateTimer += dt * config.COLOR_UPDATE_SPEED; @@ -1216,7 +1223,7 @@ function updateColors (dt) { } } -function applyInputs () { +function applyInputs() { if (splatStack.length > 0) multipleSplats(splatStack.pop()); @@ -1228,7 +1235,7 @@ function applyInputs () { }); } -function step (dt) { +function step(dt) { gl.disable(gl.BLEND); curlProgram.bind(); @@ -1293,7 +1300,7 @@ function step (dt) { dye.swap(); } -function render (target) { +function render(target) { if (config.BLOOM) applyBloom(dye.read, bloom); if (config.SUNRAYS) { @@ -1316,19 +1323,19 @@ function render (target) { drawDisplay(target); } -function drawColor (target, color) { +function drawColor(target, color) { colorProgram.bind(); gl.uniform4f(colorProgram.uniforms.color, color.r, color.g, color.b, 1); blit(target); } -function drawCheckerboard (target) { +function drawCheckerboard(target) { checkerboardProgram.bind(); gl.uniform1f(checkerboardProgram.uniforms.aspectRatio, canvas.width / canvas.height); blit(target); } -function drawDisplay (target) { +function drawDisplay(target) { let width = target == null ? gl.drawingBufferWidth : target.width; let height = target == null ? gl.drawingBufferHeight : target.height; @@ -1347,7 +1354,7 @@ function drawDisplay (target) { blit(target); } -function applyBloom (source, destination) { +function applyBloom(source, destination) { if (bloomFramebuffers.length < 2) return; @@ -1393,7 +1400,7 @@ function applyBloom (source, destination) { blit(destination); } -function applySunrays (source, mask, destination) { +function applySunrays(source, mask, destination) { gl.disable(gl.BLEND); sunraysMaskProgram.bind(); gl.uniform1i(sunraysMaskProgram.uniforms.uTexture, source.attach(0)); @@ -1405,7 +1412,7 @@ function applySunrays (source, mask, destination) { blit(destination); } -function blur (target, temp, iterations) { +function blur(target, temp, iterations) { blurProgram.bind(); for (let i = 0; i < iterations; i++) { gl.uniform2f(blurProgram.uniforms.texelSize, target.texelSizeX, 0.0); @@ -1418,13 +1425,13 @@ function blur (target, temp, iterations) { } } -function splatPointer (pointer) { +function splatPointer(pointer) { let dx = pointer.deltaX * config.SPLAT_FORCE; let dy = pointer.deltaY * config.SPLAT_FORCE; splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color); } -function multipleSplats (amount) { +function multipleSplats(amount) { for (let i = 0; i < amount; i++) { const color = generateColor(); color.r *= 10.0; @@ -1438,7 +1445,7 @@ function multipleSplats (amount) { } } -function splat (x, y, dx, dy, color) { +function splat(x, y, dx, dy, color) { splatProgram.bind(); gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0)); gl.uniform1f(splatProgram.uniforms.aspectRatio, canvas.width / canvas.height); @@ -1454,7 +1461,7 @@ function splat (x, y, dx, dy, color) { dye.swap(); } -function correctRadius (radius) { +function correctRadius(radius) { let aspectRatio = canvas.width / canvas.height; if (aspectRatio > 1) radius *= aspectRatio; @@ -1508,8 +1515,7 @@ canvas.addEventListener('touchmove', e => { window.addEventListener('touchend', e => { const touches = e.changedTouches; - for (let i = 0; i < touches.length; i++) - { + for (let i = 0; i < touches.length; i++) { let pointer = pointers.find(p => p.id == touches[i].identifier); if (pointer == null) continue; updatePointerUpData(pointer); @@ -1523,7 +1529,7 @@ window.addEventListener('keydown', e => { splatStack.push(parseInt(Math.random() * 20) + 5); }); -function updatePointerDownData (pointer, id, posX, posY) { +function updatePointerDownData(pointer, id, posX, posY) { pointer.id = id; pointer.down = true; pointer.moved = false; @@ -1536,7 +1542,7 @@ function updatePointerDownData (pointer, id, posX, posY) { pointer.color = generateColor(); } -function updatePointerMoveData (pointer, posX, posY) { +function updatePointerMoveData(pointer, posX, posY) { pointer.prevTexcoordX = pointer.texcoordX; pointer.prevTexcoordY = pointer.texcoordY; pointer.texcoordX = posX / canvas.width; @@ -1546,23 +1552,23 @@ function updatePointerMoveData (pointer, posX, posY) { pointer.moved = Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0; } -function updatePointerUpData (pointer) { +function updatePointerUpData(pointer) { pointer.down = false; } -function correctDeltaX (delta) { +function correctDeltaX(delta) { let aspectRatio = canvas.width / canvas.height; if (aspectRatio < 1) delta *= aspectRatio; return delta; } -function correctDeltaY (delta) { +function correctDeltaY(delta) { let aspectRatio = canvas.width / canvas.height; if (aspectRatio > 1) delta /= aspectRatio; return delta; } -function generateColor () { +function generateColor() { let c = HSVtoRGB(Math.random(), 1.0, 1.0); c.r *= 0.15; c.g *= 0.15; @@ -1570,7 +1576,7 @@ function generateColor () { return c; } -function HSVtoRGB (h, s, v) { +function HSVtoRGB(h, s, v) { let r, g, b, i, f, p, q, t; i = Math.floor(h * 6); f = h * 6 - i; @@ -1594,7 +1600,7 @@ function HSVtoRGB (h, s, v) { }; } -function normalizeColor (input) { +function normalizeColor(input) { let output = { r: input.r / 255, g: input.g / 255, @@ -1603,13 +1609,13 @@ function normalizeColor (input) { return output; } -function wrap (value, min, max) { +function wrap(value, min, max) { let range = max - min; if (range == 0) return min; return (value - min) % range + min; } -function getResolution (resolution) { +function getResolution(resolution) { let aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight; if (aspectRatio < 1) aspectRatio = 1.0 / aspectRatio; @@ -1623,19 +1629,19 @@ function getResolution (resolution) { return { width: min, height: max }; } -function getTextureScale (texture, width, height) { +function getTextureScale(texture, width, height) { return { x: width / texture.width, y: height / texture.height }; } -function scaleByPixelRatio (input) { +function scaleByPixelRatio(input) { let pixelRatio = window.devicePixelRatio || 1; return Math.floor(input * pixelRatio); } -function hashCode (s) { +function hashCode(s) { if (s.length == 0) return 0; let hash = 0; for (let i = 0; i < s.length; i++) {