├── vanilla ├── README.md ├── .yarnrc.yml ├── .vscode │ ├── settings.json │ └── extensions.json ├── .gitignore ├── .eslintrc.js ├── tsconfig.json ├── types │ └── skypack.d.ts ├── package.json ├── dist │ ├── thick.js │ ├── thick.js.map │ ├── grid.js │ ├── polar.js │ ├── axis │ │ ├── axis.js │ │ └── axis.js.map │ ├── grid.js.map │ ├── polar.js.map │ ├── scatterXY.js │ ├── scatterXY.js.map │ ├── camera_hist.js │ ├── sine.js │ ├── multiPlot.js │ ├── randomness.js │ ├── randomness.js.map │ ├── radar.js │ ├── camera_hist.js.map │ ├── sine.js.map │ ├── multiPlot.js.map │ ├── radar.js.map │ ├── microphone.js.map │ ├── cross.js │ ├── microphone.js │ ├── cross.js.map │ ├── histogram.js │ └── histogram.js.map ├── src │ ├── thick.ts │ ├── grid.ts │ ├── polar.ts │ ├── axis │ │ └── axis.ts │ ├── scatterXY.ts │ ├── camera_hist.ts │ ├── multiPlot.ts │ ├── sine.ts │ ├── randomness.ts │ ├── radar.ts │ ├── microphone.ts │ ├── cross.ts │ └── histogram.ts ├── style.css ├── Github_logo.svg ├── inject.js ├── thick.html ├── microphone.html ├── grid.html ├── multiPlot.html ├── jpsm.json ├── camera.html ├── log.html └── axis.html ├── offScreen ├── rollup │ ├── .gitignore │ ├── .vscode │ │ └── settings.json │ ├── src │ │ ├── web-worker.d.ts │ │ ├── offScreen.ts │ │ └── offScreen-worker.ts │ ├── .eslintrc.json │ ├── @types │ │ └── worker-loader.d.ts │ ├── tsconfig.json │ ├── rollup.config.js │ ├── package.json │ ├── style.css │ ├── index.html │ └── Github_logo.svg ├── webpack-loader │ ├── .gitignore │ ├── .vscode │ │ └── settings.json │ ├── .eslintrc.json │ ├── @types │ │ └── worker-loader.d.ts │ ├── src │ │ ├── worker-loader.d.ts │ │ ├── offScreen.ts │ │ └── offScreen-worker.ts │ ├── tsconfig.json │ ├── webpack.config.js │ ├── package.json │ ├── style.css │ ├── index.html │ └── Github_logo.svg └── webpack-plugin │ ├── .gitignore │ ├── .vscode │ └── settings.json │ ├── .eslintrc.json │ ├── tsconfig.json │ ├── package.json │ ├── webpack.config.js │ ├── src │ ├── offScreen.ts │ └── offScreen-worker.ts │ ├── style.css │ ├── index.html │ └── Github_logo.svg ├── .github ├── workflows │ ├── vanilla.yml │ └── codeql-analysis.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE ├── README.md └── index.html /vanilla/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /offScreen/rollup/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /offScreen/webpack-loader/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /offScreen/webpack-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /vanilla/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | yarnPath: ".yarn/releases/yarn-berry.cjs" 2 | nodeLinker: node-modules 3 | -------------------------------------------------------------------------------- /offScreen/rollup/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib" 3 | } -------------------------------------------------------------------------------- /offScreen/webpack-loader/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib" 3 | } -------------------------------------------------------------------------------- /offScreen/webpack-plugin/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib" 3 | } -------------------------------------------------------------------------------- /vanilla/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib", 3 | "liveServer.settings.port": 5501 4 | } -------------------------------------------------------------------------------- /vanilla/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "arcanis.vscode-zipfs" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /offScreen/rollup/src/web-worker.d.ts: -------------------------------------------------------------------------------- 1 | declare module "web-worker:*" { 2 | const WokerFactory: new () => Worker; 3 | export default WokerFactory; 4 | } 5 | -------------------------------------------------------------------------------- /vanilla/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | webgl-plot 3 | build 4 | temp 5 | .yarn/* 6 | !.yarn/patches 7 | !.yarn/plugins 8 | !.yarn/releases 9 | !.yarn/sdks 10 | !.yarn/versions -------------------------------------------------------------------------------- /offScreen/rollup/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2020": true 5 | }, 6 | "extends": [""], 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "ecmaVersion": 11, 10 | "sourceType": "module" 11 | }, 12 | "plugins": ["@typescript-eslint"], 13 | "rules": {} 14 | } 15 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2020": true 5 | }, 6 | "extends": [""], 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "ecmaVersion": 11, 10 | "sourceType": "module" 11 | }, 12 | "plugins": ["@typescript-eslint"], 13 | "rules": {} 14 | } 15 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2020": true 5 | }, 6 | "extends": [""], 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "ecmaVersion": 11, 10 | "sourceType": "module" 11 | }, 12 | "plugins": ["@typescript-eslint"], 13 | "rules": {} 14 | } 15 | -------------------------------------------------------------------------------- /offScreen/rollup/@types/worker-loader.d.ts: -------------------------------------------------------------------------------- 1 | declare module "worker-loader!*" { 2 | // You need to change `Worker`, if you specified a different value for the `workerType` option 3 | class WebpackWorker extends Worker { 4 | constructor(); 5 | } 6 | 7 | // Uncomment this if you set the `esModule` option to `false` 8 | // export = WebpackWorker; 9 | export default WebpackWorker; 10 | } 11 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/@types/worker-loader.d.ts: -------------------------------------------------------------------------------- 1 | declare module "worker-loader!*" { 2 | // You need to change `Worker`, if you specified a different value for the `workerType` option 3 | class WebpackWorker extends Worker { 4 | constructor(); 5 | } 6 | 7 | // Uncomment this if you set the `esModule` option to `false` 8 | // export = WebpackWorker; 9 | export default WebpackWorker; 10 | } 11 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/src/worker-loader.d.ts: -------------------------------------------------------------------------------- 1 | declare module "worker-loader!*" { 2 | // You need to change `Worker`, if you specified a different value for the `workerType` option 3 | class WebpackWorker extends Worker { 4 | constructor(); 5 | } 6 | 7 | // Uncomment this if you set the `esModule` option to `false` 8 | // export = WebpackWorker; 9 | export default WebpackWorker; 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/vanilla.yml: -------------------------------------------------------------------------------- 1 | name: Vanilla 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | - name: Run a one-line script 12 | run: echo Hello, world! 13 | 14 | - name: install 15 | working-directory: ./vanilla 16 | run: yarn install 17 | 18 | - name: build 19 | working-directory: ./vanilla 20 | run: yarn run build 21 | -------------------------------------------------------------------------------- /vanilla/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | rules: { 5 | "@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }] 6 | }, 7 | plugins: [ 8 | '@typescript-eslint', 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:@typescript-eslint/eslint-recommended', 13 | 'plugin:@typescript-eslint/recommended', 14 | ] 15 | }; -------------------------------------------------------------------------------- /vanilla/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "target": "esnext", 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "allowSyntheticDefaultImports": true, 8 | "downlevelIteration": true, 9 | "sourceMap": true, 10 | "typeRoots": ["node_modules/@types", "@types"], 11 | "outDir": "./dist", 12 | "baseUrl": "./src" 13 | }, 14 | "include": [ 15 | "src", 16 | "types" 17 | , ] 18 | } 19 | -------------------------------------------------------------------------------- /vanilla/types/skypack.d.ts: -------------------------------------------------------------------------------- 1 | // First, let TypeScript allow all module names starting with "https://". This will suppress TS errors. 2 | declare module "https://*"; 3 | 4 | // Second, list out all your dependencies. For every URL, you must map it to its local module. 5 | declare module "https://cdn.skypack.dev/webgl-plot" { 6 | export * from "webgl-plot"; 7 | } 8 | 9 | declare module "https://cdn.skypack.dev/@danchitnis/simple-slider" { 10 | export * from "@danchitnis/simple-slider"; 11 | } 12 | -------------------------------------------------------------------------------- /offScreen/rollup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "target": "esnext", 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "allowSyntheticDefaultImports": true, 8 | "downlevelIteration": true, 9 | "sourceMap": true, 10 | "typeRoots": ["node_modules/@types", "@types"], 11 | "outDir": "./dist", 12 | "baseUrl": ".", 13 | "paths": { 14 | "*": ["node_modules/*"] 15 | } 16 | }, 17 | "include": ["src/**/*"] 18 | } 19 | -------------------------------------------------------------------------------- /offScreen/rollup/rollup.config.js: -------------------------------------------------------------------------------- 1 | // rollup.config.js 2 | import sourceMaps from "rollup-plugin-sourcemaps"; 3 | import workerLoader from "rollup-plugin-web-worker-loader"; 4 | import resolve from "rollup-plugin-node-resolve"; 5 | import commonjs from "rollup-plugin-commonjs"; 6 | import typescript from "rollup-plugin-typescript2"; 7 | 8 | export default { 9 | input: "./src/offScreen.ts", 10 | output: { 11 | dir: "./prod", 12 | format: "iife", 13 | }, 14 | plugins: [resolve(), commonjs(), workerLoader(), typescript(), sourceMaps()], 15 | }; 16 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "target": "esnext", 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "allowSyntheticDefaultImports": true, 8 | "downlevelIteration": true, 9 | "sourceMap": true, 10 | "typeRoots": ["node_modules/@types", "@types"], 11 | "outDir": "./dist", 12 | "baseUrl": ".", 13 | "lib": ["dom", "webworker", "esnext"], 14 | "paths": { 15 | "*": ["node_modules/*"] 16 | } 17 | }, 18 | "include": ["src/**/*"] 19 | } 20 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "target": "esnext", 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "allowSyntheticDefaultImports": true, 8 | "downlevelIteration": true, 9 | "sourceMap": true, 10 | "typeRoots": ["node_modules/@types", "@types"], 11 | "outDir": "./dist", 12 | "baseUrl": ".", 13 | "lib": ["dom", "webworker", "esnext"], 14 | "paths": { 15 | "*": ["node_modules/*"] 16 | } 17 | }, 18 | "include": ["src/**/*"] 19 | } 20 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | mode: "development", 5 | entry: "./src/offScreen.ts", 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.worker\.ts$/, 10 | loader: "worker-loader", 11 | }, 12 | { test: /\.ts?$/, loader: "ts-loader" }, 13 | ], 14 | }, 15 | //plugins: [new WorkerPlugin()], 16 | resolve: { 17 | extensions: [".tsx", ".ts", ".js"], 18 | }, 19 | output: { 20 | filename: "bundle.js", 21 | path: path.resolve(__dirname, "dist"), 22 | //need this for the worker-loader 23 | publicPath: "./dist/", 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "./src/offScreen.ts", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "author": "Danial Chitnis", 10 | "license": "MIT", 11 | "dependencies": { 12 | "comlink": "^4.3.0", 13 | "webgl-plot": "^0.6.1" 14 | }, 15 | "devDependencies": { 16 | "@typescript-eslint/eslint-plugin": "^4.22.1", 17 | "@typescript-eslint/parser": "^4.22.1", 18 | "eslint": "^7.25.0", 19 | "ts-loader": "^9.1.2", 20 | "typescript": "^4.2.4", 21 | "webpack": "^5.36.2", 22 | "webpack-cli": "^4.7.0", 23 | "worker-loader": "^3.0.8" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "./src/offScreen.ts", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "author": "Danial Chitnis", 10 | "license": "MIT", 11 | "dependencies": { 12 | "comlink": "^4.3.0", 13 | "webgl-plot": "^0.6.1" 14 | }, 15 | "devDependencies": { 16 | "@typescript-eslint/eslint-plugin": "^4.22.1", 17 | "@typescript-eslint/parser": "^4.22.1", 18 | "eslint": "^7.25.0", 19 | "ts-loader": "^9.1.2", 20 | "typescript": "^4.2.4", 21 | "webpack": "^5.36.2", 22 | "webpack-cli": "^4.7.0", 23 | "worker-plugin": "^5.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const WorkerPlugin = require("worker-plugin"); 3 | 4 | module.exports = { 5 | mode: "development", 6 | entry: "./src/offScreen.ts", 7 | plugins: [ 8 | new WorkerPlugin({ 9 | // use "self" as the global object when receiving hot updates. 10 | globalObject: "self", // <-- this is the default value 11 | }), 12 | ], 13 | module: { 14 | rules: [{ test: /\.ts?$/, loader: "ts-loader" }], 15 | }, 16 | 17 | resolve: { 18 | extensions: [".tsx", ".ts", ".js"], 19 | }, 20 | output: { 21 | filename: "bundle.js", 22 | path: path.resolve(__dirname, "dist"), 23 | //need this for the worker-loader 24 | publicPath: "./dist/", 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /offScreen/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "rollup.config.js", 6 | "scripts": { 7 | "build": "rollup -c", 8 | "rome": "rome init --apply" 9 | }, 10 | "author": "Danial Chitnis", 11 | "license": "MIT", 12 | "dependencies": { 13 | "webgl-plot": "^0.6.2" 14 | }, 15 | "devDependencies": { 16 | "@typescript-eslint/eslint-plugin": "^4.29.3", 17 | "@typescript-eslint/parser": "^4.29.3", 18 | "eslint": "^7.32.0", 19 | "rollup": "^2.56.3", 20 | "rollup-plugin-commonjs": "^10.1.0", 21 | "rollup-plugin-node-resolve": "^5.2.0", 22 | "rollup-plugin-sourcemaps": "^0.6.3", 23 | "rollup-plugin-typescript2": "^0.30.0", 24 | "rollup-plugin-web-worker-loader": "^1.6.1", 25 | "typescript": "^4.4.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webgl-plot-examples", 3 | "version": "0.0.1", 4 | "description": "webgl-plot examples", 5 | "scripts": { 6 | "webpack": "webpack", 7 | "roll": "rollup -c", 8 | "build": "tsc" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/danchitnis/WebGL-plot-examples.git" 13 | }, 14 | "author": "Danial Chitnis", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/danchitnis/WebGL-plot-examples/issues" 18 | }, 19 | "homepage": "https://github.com/danchitnis/WebGL-plot-examples#readme", 20 | "dependencies": { 21 | "@danchitnis/simple-slider": "^0.2.0", 22 | "@spectrum-web-components/bundle": "^0.28.7", 23 | "webgl-plot": "^0.7.0" 24 | }, 25 | "devDependencies": { 26 | "@typescript-eslint/eslint-plugin": "^5.50.0", 27 | "@typescript-eslint/parser": "^5.50.0", 28 | "eslint": "^8.33.0", 29 | "typescript": "^4.9.5" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /offScreen/rollup/src/offScreen.ts: -------------------------------------------------------------------------------- 1 | import WebWorker from "web-worker:./offScreen-worker.ts"; 2 | 3 | const htmlCanvas = document.getElementById("my_canvas") as HTMLCanvasElement; 4 | 5 | const offscreen = htmlCanvas.transferControlToOffscreen(); 6 | 7 | offscreen.width = htmlCanvas.clientWidth * window.devicePixelRatio; 8 | offscreen.height = htmlCanvas.clientHeight * window.devicePixelRatio; 9 | 10 | const worker = new WebWorker(); 11 | worker.postMessage({ canvas: offscreen }, [offscreen]); 12 | 13 | document.getElementById("btBusy").addEventListener("click", () => { 14 | const info = document.getElementById("info"); 15 | 16 | info.innerHTML = 17 | "Main thread working...
Check the console (F12)
Try resizing the window now"; 18 | 19 | let a = 0; 20 | const total = 100000000; 21 | 22 | for (let i = 0; i < total; i++) { 23 | a = a + Math.sin(i); 24 | if (i % (total / 20) == 0) { 25 | console.log(((100 * i) / total).toFixed(0) + "%"); 26 | } 27 | } 28 | info.innerHTML = "Done!"; 29 | }); 30 | -------------------------------------------------------------------------------- /offScreen/rollup/src/offScreen-worker.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, WebglLine, ColorRGBA } from "webgl-plot"; 2 | 3 | self.addEventListener("message", (e) => { 4 | const canvas = e.data.canvas; 5 | 6 | console.log(canvas); 7 | 8 | const numX = canvas.width; 9 | 10 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 11 | 12 | const line = new WebglLine(color, numX); 13 | 14 | const wglp = new WebglPlot(canvas, true); 15 | 16 | line.lineSpaceX(-1, 2 / numX); 17 | wglp.addDataLine(line); 18 | 19 | function newFrame() { 20 | update(); 21 | wglp.update(); 22 | requestAnimationFrame(newFrame); 23 | } 24 | requestAnimationFrame(newFrame); 25 | 26 | function update() { 27 | const freq = 0.001; 28 | const amp = 0.5; 29 | const noise = 0.1; 30 | 31 | for (let i = 0; i < line.numPoints; i++) { 32 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 33 | const yNoise = Math.random() - 0.5; 34 | line.setY(i, ySin * amp + yNoise * noise); 35 | } 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Danial Chitnis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vanilla/dist/thick.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglThickLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | const canvas = document.getElementById("my_canvas"); 3 | const devicePixelRatio = window.devicePixelRatio || 1; 4 | canvas.width = canvas.clientWidth * devicePixelRatio; 5 | canvas.height = canvas.clientHeight * devicePixelRatio; 6 | const wglp = new WebglPlot(canvas); 7 | const numX = canvas.width; 8 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 9 | const lineThick = new WebglThickLine(color, numX, 0.01); 10 | lineThick.lineSpaceX(-1, 2 / numX); 11 | wglp.addThickLine(lineThick); 12 | function newFrame() { 13 | update(); 14 | wglp.update(); 15 | requestAnimationFrame(newFrame); 16 | } 17 | requestAnimationFrame(newFrame); 18 | function update() { 19 | const freq = 0.001; 20 | const amp = 0.5; 21 | const noise = 0.01; 22 | for (let i = 0; i < lineThick.numPoints; i++) { 23 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 24 | const yNoise = Math.random() - 0.5; 25 | lineThick.setY(i, ySin * amp + yNoise * noise); 26 | } 27 | } 28 | //# sourceMappingURL=thick.js.map -------------------------------------------------------------------------------- /vanilla/src/thick.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglThickLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | 3 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 4 | const devicePixelRatio = window.devicePixelRatio || 1; 5 | canvas.width = canvas.clientWidth * devicePixelRatio; 6 | canvas.height = canvas.clientHeight * devicePixelRatio; 7 | 8 | const wglp = new WebglPlot(canvas); 9 | 10 | const numX = canvas.width; 11 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 12 | const lineThick = new WebglThickLine(color, numX, 0.01); 13 | lineThick.lineSpaceX(-1, 2 / numX); 14 | wglp.addThickLine(lineThick); 15 | 16 | function newFrame(): void { 17 | update(); 18 | wglp.update(); 19 | requestAnimationFrame(newFrame); 20 | } 21 | requestAnimationFrame(newFrame); 22 | 23 | function update(): void { 24 | const freq = 0.001; 25 | const amp = 0.5; 26 | const noise = 0.01; 27 | 28 | for (let i = 0; i < lineThick.numPoints; i++) { 29 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 30 | const yNoise = Math.random() - 0.5; 31 | lineThick.setY(i, ySin * amp + yNoise * noise); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/src/offScreen.ts: -------------------------------------------------------------------------------- 1 | import { wrap, transfer } from "comlink"; 2 | 3 | const init = async () => { 4 | const htmlCanvas = document.getElementById("my_canvas") as HTMLCanvasElement; 5 | 6 | const offscreen = htmlCanvas.transferControlToOffscreen(); 7 | 8 | offscreen.width = htmlCanvas.clientWidth * window.devicePixelRatio; 9 | offscreen.height = htmlCanvas.clientHeight * window.devicePixelRatio; 10 | 11 | const worker = new Worker("./offScreen-worker", { type: "module" }); 12 | const workerApi = wrap(worker); 13 | await workerApi.run(transfer(offscreen, [offscreen])); 14 | await workerApi.set(0.8); 15 | }; 16 | 17 | init(); 18 | 19 | document.getElementById("btBusy").addEventListener("click", () => { 20 | const info = document.getElementById("info"); 21 | 22 | info.innerHTML = 23 | "Main thread working...
Check the console (F12)
Try resizing the window now"; 24 | 25 | let a = 0; 26 | const total = 100000000; 27 | 28 | for (let i = 0; i < total; i++) { 29 | a = a + Math.sin(i); 30 | if (i % (total / 20) == 0) { 31 | console.log(((100 * i) / total).toFixed(0) + "%"); 32 | } 33 | } 34 | info.innerHTML = "Done!"; 35 | }); 36 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/src/offScreen.ts: -------------------------------------------------------------------------------- 1 | import { wrap, transfer } from "comlink"; 2 | import Worker from "worker-loader!./offScreen-worker"; 3 | 4 | const init = async () => { 5 | const htmlCanvas = document.getElementById("my_canvas") as HTMLCanvasElement; 6 | 7 | const offscreen = htmlCanvas.transferControlToOffscreen(); 8 | 9 | offscreen.width = htmlCanvas.clientWidth * window.devicePixelRatio; 10 | offscreen.height = htmlCanvas.clientHeight * window.devicePixelRatio; 11 | 12 | const worker = new Worker(); 13 | const workerApi = wrap(worker); 14 | await workerApi.run(transfer(offscreen, [offscreen])); 15 | await workerApi.set(0.8); 16 | }; 17 | 18 | init(); 19 | 20 | document.getElementById("btBusy").addEventListener("click", () => { 21 | const info = document.getElementById("info"); 22 | 23 | info.innerHTML = 24 | "Main thread working...
Check the console (F12)
Try resizing the window now"; 25 | 26 | let a = 0; 27 | const total = 100000000; 28 | 29 | for (let i = 0; i < total; i++) { 30 | a = a + Math.sin(i); 31 | if (i % (total / 20) == 0) { 32 | console.log(((100 * i) / total).toFixed(0) + "%"); 33 | } 34 | } 35 | info.innerHTML = "Done!"; 36 | }); 37 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/src/offScreen-worker.ts: -------------------------------------------------------------------------------- 1 | import { expose } from "comlink"; 2 | import { WebglPlot, WebglLine, ColorRGBA } from "webgl-plot"; 3 | 4 | const exports = { 5 | amp: 0.5, 6 | 7 | run(canvas: OffscreenCanvas): Promise { 8 | console.log(canvas); 9 | 10 | const numX = canvas.width; 11 | 12 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 13 | 14 | const line = new WebglLine(color, numX); 15 | 16 | const wglp = new WebglPlot(canvas); 17 | 18 | line.lineSpaceX(-1, 2 / numX); 19 | wglp.addDataLine(line); 20 | 21 | function newFrame() { 22 | update(); 23 | wglp.update(); 24 | requestAnimationFrame(newFrame); 25 | } 26 | requestAnimationFrame(newFrame); 27 | 28 | function update() { 29 | const freq = 0.001; 30 | //const amp = 0.5; 31 | const noise = 0.1; 32 | 33 | for (let i = 0; i < line.numPoints; i++) { 34 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 35 | const yNoise = Math.random() - 0.5; 36 | line.setY(i, ySin * exports.amp + yNoise * noise); 37 | } 38 | } 39 | return; 40 | }, 41 | set(a: number): Promise { 42 | exports.amp = a; 43 | return; 44 | }, 45 | }; 46 | export type CanvasWorker = typeof exports; 47 | 48 | expose(exports); 49 | -------------------------------------------------------------------------------- /vanilla/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgb(10, 10, 10); 3 | color: white; 4 | font-family: Arial, Helvetica, sans-serif; 5 | } 6 | 7 | .canvas { 8 | width: 100%; 9 | height: 70vh; 10 | } 11 | 12 | .items { 13 | display: flex; 14 | margin: auto; 15 | width: 80%; 16 | flex-direction: column; 17 | align-items: center; 18 | } 19 | 20 | .menu > a { 21 | border: 4px solid dodgerblue; 22 | background-color: dodgerblue; 23 | border-radius: 10px; 24 | color: white; 25 | padding: 15px 32px; 26 | text-align: center; 27 | text-decoration: none; 28 | display: inline-block; 29 | font-size: 1em; 30 | margin-top: auto; 31 | margin-bottom: 0.5em; 32 | cursor: pointer; 33 | transition-duration: 0.4s; 34 | } 35 | 36 | .menu > a:hover { 37 | background-color: forestgreen; 38 | border-color: forestgreen; 39 | color: white; 40 | } 41 | 42 | .button { 43 | border: 4px solid dodgerblue; 44 | background-color: dodgerblue; 45 | border-radius: 10px; 46 | color: white; 47 | padding: 15px 32px; 48 | text-align: center; 49 | text-decoration: none; 50 | display: inline-block; 51 | font-size: 1em; 52 | margin-top: auto; 53 | margin-bottom: 0.5em; 54 | cursor: pointer; 55 | transition-duration: 0.4s; 56 | } 57 | 58 | @media only screen and (max-width: 800px) { 59 | .canvas { 60 | width: 95%; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vanilla/dist/thick.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"thick.js","sourceRoot":"","sources":["../src/thick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE1F,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAsB,CAAC;AACzE,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;AACtD,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC;AACrD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEvD,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAEnC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;AAC1B,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACxD,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AACnC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAE7B,SAAS,QAAQ;IACf,MAAM,EAAE,CAAC;IACT,IAAI,CAAC,MAAM,EAAE,CAAC;IACd,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC;AACD,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAEhC,SAAS,MAAM;IACb,MAAM,IAAI,GAAG,KAAK,CAAC;IACnB,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,MAAM,KAAK,GAAG,IAAI,CAAC;IAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;QACnC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;KAChD;AACH,CAAC"} -------------------------------------------------------------------------------- /offScreen/rollup/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgb(0.1, 0.1,0.1); 3 | color: white; 4 | font-family: Arial, Helvetica, sans-serif; 5 | } 6 | 7 | .canvas { 8 | width: 100%; 9 | height: 70vh; 10 | } 11 | 12 | .items { 13 | display: flex; 14 | margin: auto; 15 | width: 80%; 16 | flex-direction: column; 17 | align-items: center; 18 | 19 | } 20 | 21 | 22 | .menu > a { 23 | border: 4px solid dodgerblue; 24 | background-color: dodgerblue; 25 | border-radius: 10px; 26 | color: white; 27 | padding: 15px 32px; 28 | text-align: center; 29 | text-decoration: none; 30 | display: inline-block; 31 | font-size: 1em; 32 | margin-top: auto; 33 | margin-bottom: 0.5em; 34 | cursor: pointer; 35 | transition-duration: 0.4s; 36 | } 37 | 38 | .menu > a:hover { 39 | background-color: forestgreen; 40 | border-color: forestgreen; 41 | color: white; 42 | } 43 | 44 | .button { 45 | border: 4px solid dodgerblue; 46 | background-color: dodgerblue; 47 | border-radius: 10px; 48 | color: white; 49 | padding: 15px 32px; 50 | text-align: center; 51 | text-decoration: none; 52 | display: inline-block; 53 | font-size: 1em; 54 | margin-top: auto; 55 | margin-bottom: 0.5em; 56 | cursor: pointer; 57 | transition-duration: 0.4s; 58 | } 59 | 60 | 61 | 62 | @media only screen and (max-width: 800px) { 63 | .canvas { 64 | width: 95%; 65 | } 66 | } -------------------------------------------------------------------------------- /offScreen/webpack-loader/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgb(0.1, 0.1,0.1); 3 | color: white; 4 | font-family: Arial, Helvetica, sans-serif; 5 | } 6 | 7 | .canvas { 8 | width: 100%; 9 | height: 70vh; 10 | } 11 | 12 | .items { 13 | display: flex; 14 | margin: auto; 15 | width: 80%; 16 | flex-direction: column; 17 | align-items: center; 18 | 19 | } 20 | 21 | 22 | .menu > a { 23 | border: 4px solid dodgerblue; 24 | background-color: dodgerblue; 25 | border-radius: 10px; 26 | color: white; 27 | padding: 15px 32px; 28 | text-align: center; 29 | text-decoration: none; 30 | display: inline-block; 31 | font-size: 1em; 32 | margin-top: auto; 33 | margin-bottom: 0.5em; 34 | cursor: pointer; 35 | transition-duration: 0.4s; 36 | } 37 | 38 | .menu > a:hover { 39 | background-color: forestgreen; 40 | border-color: forestgreen; 41 | color: white; 42 | } 43 | 44 | .button { 45 | border: 4px solid dodgerblue; 46 | background-color: dodgerblue; 47 | border-radius: 10px; 48 | color: white; 49 | padding: 15px 32px; 50 | text-align: center; 51 | text-decoration: none; 52 | display: inline-block; 53 | font-size: 1em; 54 | margin-top: auto; 55 | margin-bottom: 0.5em; 56 | cursor: pointer; 57 | transition-duration: 0.4s; 58 | } 59 | 60 | 61 | 62 | @media only screen and (max-width: 800px) { 63 | .canvas { 64 | width: 95%; 65 | } 66 | } -------------------------------------------------------------------------------- /offScreen/webpack-plugin/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgb(0.1, 0.1,0.1); 3 | color: white; 4 | font-family: Arial, Helvetica, sans-serif; 5 | } 6 | 7 | .canvas { 8 | width: 100%; 9 | height: 70vh; 10 | } 11 | 12 | .items { 13 | display: flex; 14 | margin: auto; 15 | width: 80%; 16 | flex-direction: column; 17 | align-items: center; 18 | 19 | } 20 | 21 | 22 | .menu > a { 23 | border: 4px solid dodgerblue; 24 | background-color: dodgerblue; 25 | border-radius: 10px; 26 | color: white; 27 | padding: 15px 32px; 28 | text-align: center; 29 | text-decoration: none; 30 | display: inline-block; 31 | font-size: 1em; 32 | margin-top: auto; 33 | margin-bottom: 0.5em; 34 | cursor: pointer; 35 | transition-duration: 0.4s; 36 | } 37 | 38 | .menu > a:hover { 39 | background-color: forestgreen; 40 | border-color: forestgreen; 41 | color: white; 42 | } 43 | 44 | .button { 45 | border: 4px solid dodgerblue; 46 | background-color: dodgerblue; 47 | border-radius: 10px; 48 | color: white; 49 | padding: 15px 32px; 50 | text-align: center; 51 | text-decoration: none; 52 | display: inline-block; 53 | font-size: 1em; 54 | margin-top: auto; 55 | margin-bottom: 0.5em; 56 | cursor: pointer; 57 | transition-duration: 0.4s; 58 | } 59 | 60 | 61 | 62 | @media only screen and (max-width: 800px) { 63 | .canvas { 64 | width: 95%; 65 | } 66 | } -------------------------------------------------------------------------------- /offScreen/rollup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 |

18 | 19 |
20 | 21 |

22 | 23 |
24 | 39 |

40 | See the 41 | Github repository for the details 44 |

45 |
46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 |

18 | 19 |
20 | 21 |

22 | 23 |
24 | 39 |

40 | See the 41 | Github repository for the details 44 |

45 |
46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 |

18 | 19 |
20 | 21 |

22 | 23 |
24 | 39 |

40 | See the 41 | Github repository for the details 44 |

45 |
46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/src/offScreen-worker.ts: -------------------------------------------------------------------------------- 1 | import { expose } from "comlink"; 2 | import { WebglPlot, WebglLine, ColorRGBA } from "webgl-plot"; 3 | 4 | const exports = { 5 | amp: 0.5, 6 | 7 | run(canvas: OffscreenCanvas): Promise { 8 | console.log("😉"); 9 | //const canvas = this.getElementById("my_canvas") as HTMLCanvasElement; 10 | 11 | console.log(canvas); 12 | 13 | const numX = canvas.width; 14 | 15 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 16 | 17 | const line = new WebglLine(color, numX); 18 | 19 | const wglp = new WebglPlot(canvas); 20 | 21 | line.lineSpaceX(-1, 2 / numX); 22 | wglp.addDataLine(line); 23 | 24 | function newFrame() { 25 | update(); 26 | wglp.update(); 27 | requestAnimationFrame(newFrame); 28 | } 29 | requestAnimationFrame(newFrame); 30 | 31 | function update() { 32 | const freq = 0.001; 33 | //const amp = 0.5; 34 | const noise = 0.1; 35 | 36 | for (let i = 0; i < line.numPoints; i++) { 37 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 38 | const yNoise = Math.random() - 0.5; 39 | line.setY(i, ySin * exports.amp + yNoise * noise); 40 | } 41 | } 42 | return; 43 | }, 44 | set(a: number): Promise { 45 | exports.amp = a; 46 | return; 47 | }, 48 | }; 49 | export type CanvasWorker = typeof exports; 50 | 51 | expose(exports); 52 | -------------------------------------------------------------------------------- /vanilla/Github_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /offScreen/rollup/Github_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /offScreen/webpack-loader/Github_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /offScreen/webpack-plugin/Github_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebglPlot Examples 2 | 3 | Examples for the [WebGL-plot](https://github.com/danchitnis/webgl-plot) library 4 | 5 | ## Vanilla Javascript Examples 6 | 7 | - ### [Random Lines](https://danchitnis.github.io/webgl-plot-examples/vanilla/index.html) 8 | - ### [Sine wave with dynamic noise](https://danchitnis.github.io/webgl-plot-examples/vanilla/sine.html) 9 | - ### [Static Lines (Zoom & Drag)](https://danchitnis.github.io/webgl-plot-examples/vanilla/static.html) 10 | - ### [Multi 2D Grid Plotting](https://danchitnis.github.io/webgl-plot-examples/vanilla/multiPlot.html) 11 | - ### [Axis demonstrator](https://danchitnis.github.io/webgl-plot-examples/vanilla/axis.html) 12 | - ### [Histograms](https://danchitnis.github.io/webgl-plot-examples/vanilla/histogram.html) 13 | - ### [XY Scatter Plot](https://danchitnis.github.io/webgl-plot-examples/vanilla/scatterXY.html) 14 | - ### [Polar](https://danchitnis.github.io/webgl-plot-examples/vanilla/polar.html) 15 | - ### [Radar](https://danchitnis.github.io/webgl-plot-examples/vanilla/radar.html) 16 | - ### [Camera (RGB Histogram)](https://danchitnis.github.io/webgl-plot-examples/vanilla/camera.html) 17 | - ### [Microphone (Realtime & Spectrum)](https://danchitnis.github.io/webgl-plot-examples/vanilla/microphone.html) 18 | - ### [Thick line demonstrator](https://danchitnis.github.io/webgl-plot-examples/vanilla/thick.html) 19 | - ### [Axis Grid](https://danchitnis.github.io/webgl-plot-examples/vanilla/grid.html) 20 | - ### [Cross for finding values](https://danchitnis.github.io/webgl-plot-examples/vanilla/cross.html) 21 | 22 | ## Getting started 23 | 24 | ```bash 25 | git clone https://github.com/danchitnis/webgl-plot-examples.git 26 | cd webgl-plot-examples 27 | npm i 28 | npm run build 29 | ``` 30 | 31 | Then serve index.html on any http server. If you don't have an HTTP server then you should be to open the file locally. 32 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [master, ] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [master] 9 | schedule: 10 | - cron: '0 9 * * 4' 11 | 12 | jobs: 13 | analyse: 14 | name: Analyse 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | with: 21 | # We must fetch at least the immediate parents so that if this is 22 | # a pull request then we can checkout the head. 23 | fetch-depth: 2 24 | 25 | # If this run was triggered by a pull request event, then checkout 26 | # the head of the pull request instead of the merge commit. 27 | - run: git checkout HEAD^2 28 | if: ${{ github.event_name == 'pull_request' }} 29 | 30 | # Initializes the CodeQL tools for scanning. 31 | - name: Initialize CodeQL 32 | uses: github/codeql-action/init@v1 33 | # Override language selection by uncommenting this and choosing your languages 34 | # with: 35 | # languages: go, javascript, csharp, python, cpp, java 36 | 37 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 38 | # If this step fails, then you should remove it and run the build manually (see below) 39 | - name: Autobuild 40 | uses: github/codeql-action/autobuild@v1 41 | 42 | # ℹ️ Command-line programs to run using the OS shell. 43 | # 📚 https://git.io/JvXDl 44 | 45 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 46 | # and modify them (or add more) to build your code if your project 47 | # uses a compiled language 48 | 49 | #- run: | 50 | # make bootstrap 51 | # make release 52 | 53 | - name: Perform CodeQL Analysis 54 | uses: github/codeql-action/analyze@v1 55 | -------------------------------------------------------------------------------- /vanilla/dist/grid.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | const gridX = document.getElementById("gridX"); 3 | const gridY = document.getElementById("gridY"); 4 | gridX.addEventListener("change", updateGrid); 5 | gridY.addEventListener("change", updateGrid); 6 | const canvas = document.getElementById("my_canvas"); 7 | const devicePixelRatio = window.devicePixelRatio || 1; 8 | canvas.width = canvas.clientWidth * devicePixelRatio; 9 | canvas.height = canvas.clientHeight * devicePixelRatio; 10 | const wglp = new WebglPlot(canvas); 11 | const numX = canvas.width; 12 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 13 | const lineMain = new WebglLine(color, numX); 14 | lineMain.lineSpaceX(-1, 2 / numX); 15 | //wglp.addLine(lineMain); 16 | updateGrid(); 17 | function newFrame() { 18 | update(); 19 | wglp.update(); 20 | requestAnimationFrame(newFrame); 21 | } 22 | requestAnimationFrame(newFrame); 23 | function addGridLine(coords) { 24 | const color = new ColorRGBA(0.5, 0.5, 0.5, 1); 25 | const line = new WebglLine(color, 2); 26 | line.xy = coords; 27 | wglp.addLine(line); 28 | } 29 | function update() { 30 | const freq = 0.001; 31 | const amp = 0.5; 32 | const noise = 0.1; 33 | for (let i = 0; i < lineMain.numPoints; i++) { 34 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 35 | const yNoise = Math.random() - 0.5; 36 | lineMain.setY(i, ySin * amp + yNoise * noise); 37 | } 38 | } 39 | function updateGrid() { 40 | wglp.removeAllLines(); 41 | wglp.addLine(lineMain); 42 | console.log(gridX.value, gridY.value); 43 | const ngX = parseInt(gridX.value); 44 | const ngY = parseInt(gridY.value); 45 | for (let i = 0; i < ngX; i++) { 46 | const divPoint = (2 * i) / (ngX - 1) - 1; 47 | addGridLine(new Float32Array([divPoint, -1, divPoint, 1])); 48 | } 49 | for (let i = 0; i < ngY; i++) { 50 | const divPoint = (2 * i) / (ngY - 1) - 1; 51 | addGridLine(new Float32Array([-1, divPoint, 1, divPoint])); 52 | } 53 | } 54 | //# sourceMappingURL=grid.js.map -------------------------------------------------------------------------------- /vanilla/src/grid.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | 3 | const gridX = document.getElementById("gridX") as HTMLInputElement; 4 | const gridY = document.getElementById("gridY") as HTMLInputElement; 5 | gridX.addEventListener("change", updateGrid); 6 | gridY.addEventListener("change", updateGrid); 7 | 8 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 9 | const devicePixelRatio = window.devicePixelRatio || 1; 10 | canvas.width = canvas.clientWidth * devicePixelRatio; 11 | canvas.height = canvas.clientHeight * devicePixelRatio; 12 | 13 | const wglp = new WebglPlot(canvas); 14 | 15 | const numX = canvas.width; 16 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 17 | const lineMain = new WebglLine(color, numX); 18 | lineMain.lineSpaceX(-1, 2 / numX); 19 | //wglp.addLine(lineMain); 20 | updateGrid(); 21 | 22 | function newFrame(): void { 23 | update(); 24 | wglp.update(); 25 | requestAnimationFrame(newFrame); 26 | } 27 | requestAnimationFrame(newFrame); 28 | 29 | function addGridLine(coords: Float32Array) { 30 | const color = new ColorRGBA(0.5, 0.5, 0.5, 1); 31 | const line = new WebglLine(color, 2); 32 | line.xy = coords; 33 | wglp.addLine(line); 34 | } 35 | 36 | function update(): void { 37 | const freq = 0.001; 38 | const amp = 0.5; 39 | const noise = 0.1; 40 | 41 | for (let i = 0; i < lineMain.numPoints; i++) { 42 | const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2); 43 | const yNoise = Math.random() - 0.5; 44 | lineMain.setY(i, ySin * amp + yNoise * noise); 45 | } 46 | } 47 | 48 | function updateGrid(): void { 49 | wglp.removeAllLines(); 50 | wglp.addLine(lineMain); 51 | console.log(gridX.value, gridY.value); 52 | const ngX = parseInt(gridX.value); 53 | const ngY = parseInt(gridY.value); 54 | for (let i = 0; i < ngX; i++) { 55 | const divPoint = (2 * i) / (ngX - 1) - 1; 56 | addGridLine(new Float32Array([divPoint, -1, divPoint, 1])); 57 | } 58 | for (let i = 0; i < ngY; i++) { 59 | const divPoint = (2 * i) / (ngY - 1) - 1; 60 | addGridLine(new Float32Array([-1, divPoint, 1, divPoint])); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vanilla/dist/polar.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglPolar } from "webgl-plot"; 2 | let rotation = 0.1; 3 | let freq = 0.01; 4 | const canvas = document.getElementById("my_canvas"); 5 | const numPointList = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]; 6 | let numPoints = numPointList[9]; 7 | const devicePixelRatio = window.devicePixelRatio || 1; 8 | canvas.width = canvas.clientWidth * devicePixelRatio; 9 | canvas.height = canvas.clientHeight * devicePixelRatio; 10 | const wglp = new WebglPlot(canvas); 11 | let line; 12 | createUI(); 13 | init(); 14 | let resizeId; 15 | window.addEventListener("resize", () => { 16 | window.clearTimeout(resizeId); 17 | resizeId = window.setTimeout(doneResizing, 100); 18 | }); 19 | function newFrame() { 20 | update(); 21 | wglp.update(); 22 | requestAnimationFrame(newFrame); 23 | } 24 | requestAnimationFrame(newFrame); 25 | function init() { 26 | wglp.removeAllLines(); 27 | const numX = canvas.width; 28 | const numY = canvas.height; 29 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 30 | line = new WebglPolar(color, numPoints); 31 | wglp.gScaleX = numY / numX; 32 | wglp.gScaleY = 1; 33 | wglp.addLine(line); 34 | } 35 | function update() { 36 | line.offsetTheta = 10 * rotation; 37 | for (let i = 0; i < line.numPoints; i++) { 38 | const theta = (i * 360) / line.numPoints; 39 | const r = Math.cos((2 * Math.PI * freq * theta) / 360); 40 | line.setRtheta(i, theta, r); 41 | } 42 | } 43 | function doneResizing() { 44 | //wglp.viewport(0, 0, canv.width, canv.height); 45 | init(); 46 | } 47 | function createUI() { 48 | const sliderLine = document.getElementById("sliderLine"); 49 | sliderLine.max = numPointList.length - 1; 50 | sliderLine.addEventListener("input", () => { 51 | numPoints = numPointList[sliderLine.value]; 52 | init(); 53 | }); 54 | sliderLine.getAriaValueText = () => { 55 | return numPointList[sliderLine.value].toString(); 56 | }; 57 | const sliderFreq = document.getElementById("sliderFreq"); 58 | sliderFreq.addEventListener("input", () => { 59 | freq = sliderFreq.value; 60 | }); 61 | const sliderRotation = document.getElementById("sliderRotation"); 62 | sliderRotation.addEventListener("input", () => { 63 | rotation = sliderRotation.value; 64 | }); 65 | } 66 | //# sourceMappingURL=polar.js.map -------------------------------------------------------------------------------- /vanilla/dist/axis/axis.js: -------------------------------------------------------------------------------- 1 | //import { unitConvert2string } from "./sim/unitConverter"; 2 | const canvasX = document.getElementById("canvas_xAxis"); 3 | const canvasY = document.getElementById("canvas_yAxis"); 4 | //let canvasSize = { width: 0, height: 0 } as CanvasSize; 5 | const initCanvas = (canvas) => { 6 | const devicePixelRatio = window.devicePixelRatio || 1; 7 | canvas.width = canvas.clientWidth * devicePixelRatio; 8 | canvas.height = canvas.clientHeight * devicePixelRatio; 9 | //canvasSize = { width: canvas.width, height: canvas.height }; 10 | const ctx2d = canvas.getContext("2d"); 11 | if (ctx2d) { 12 | ctx2d.font = "16px Courier New"; 13 | ctx2d.fillStyle = "white"; 14 | ctx2d.strokeStyle = "white"; 15 | } 16 | return ctx2d; 17 | //const rect = canvas?.getBoundingClientRect(); 18 | //console.log("axis->", rect); 19 | }; 20 | const ctxX = initCanvas(canvasX); 21 | const ctxY = initCanvas(canvasY); 22 | const updateX = (ctx2d, width, height, scale, offset, divs) => { 23 | ctx2d.clearRect(0, 0, width, height); 24 | for (let i = 0; i < divs; i++) { 25 | const midpoint = -(offset - i / (divs / 2) + 1) / scale; 26 | const x = (i / divs) * width; 27 | ctx2d.fillText(`${midpoint.toExponential(2)}`, x, 15); 28 | //ctx.fillRect(10, 10, 100, 100); 29 | ctx2d.moveTo(x, 0); 30 | ctx2d.lineTo(x, 10); 31 | ctx2d.stroke(); 32 | } 33 | }; 34 | const updateY = (ctx2d, width, height, scale, offset, divs) => { 35 | //console.log("yaxis->", canvasSize); 36 | ctx2d.clearRect(0, 0, width, height); 37 | for (let i = 0; i < divs; i++) { 38 | const midpoint = -(offset + i / (divs / 2) - 1) / scale; 39 | const y = (i / divs) * height; 40 | ctx2d.fillText(`${midpoint.toExponential(2)}`, 5, y); 41 | //ctx.fillRect(10, 10, 100, 100); 42 | ctx2d.moveTo(width - 10, y); 43 | ctx2d.lineTo(width, y); 44 | ctx2d.stroke(); 45 | } 46 | }; 47 | export const updateAxisX = (scale, offset, divs) => { 48 | //console.log("axis->", axis == "y"); 49 | //console.log("axis->", midpoint); 50 | if (ctxX) { 51 | updateX(ctxX, canvasX.width, canvasX.height, scale, offset, divs); 52 | } 53 | }; 54 | export const updateAxisY = (scale, offset, divs) => { 55 | if (ctxY) { 56 | updateY(ctxY, canvasY.width, canvasY.height, scale, offset, divs); 57 | } 58 | }; 59 | //updateAxisX(1, 0); 60 | //# sourceMappingURL=axis.js.map -------------------------------------------------------------------------------- /vanilla/dist/axis/axis.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"axis.js","sourceRoot":"","sources":["../../src/axis/axis.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /vanilla/dist/grid.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /vanilla/src/polar.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglPolar } from "webgl-plot"; 2 | import { Slider } from "@spectrum-web-components/slider"; 3 | 4 | let rotation = 0.1; 5 | let freq = 0.01; 6 | 7 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 8 | 9 | const numPointList = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]; 10 | let numPoints = numPointList[9]; 11 | 12 | const devicePixelRatio = window.devicePixelRatio || 1; 13 | canvas.width = canvas.clientWidth * devicePixelRatio; 14 | canvas.height = canvas.clientHeight * devicePixelRatio; 15 | const wglp = new WebglPlot(canvas); 16 | 17 | let line: WebglPolar; 18 | 19 | createUI(); 20 | 21 | init(); 22 | 23 | let resizeId: number; 24 | window.addEventListener("resize", () => { 25 | window.clearTimeout(resizeId); 26 | resizeId = window.setTimeout(doneResizing, 100); 27 | }); 28 | 29 | function newFrame(): void { 30 | update(); 31 | 32 | wglp.update(); 33 | 34 | requestAnimationFrame(newFrame); 35 | } 36 | 37 | requestAnimationFrame(newFrame); 38 | 39 | function init(): void { 40 | wglp.removeAllLines(); 41 | 42 | const numX = canvas.width; 43 | const numY = canvas.height; 44 | 45 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 46 | line = new WebglPolar(color, numPoints); 47 | 48 | wglp.gScaleX = numY / numX; 49 | wglp.gScaleY = 1; 50 | 51 | wglp.addLine(line); 52 | } 53 | 54 | function update(): void { 55 | line.offsetTheta = 10 * rotation; 56 | 57 | for (let i = 0; i < line.numPoints; i++) { 58 | const theta = (i * 360) / line.numPoints; 59 | const r = Math.cos((2 * Math.PI * freq * theta) / 360); 60 | 61 | line.setRtheta(i, theta, r); 62 | } 63 | } 64 | 65 | function doneResizing(): void { 66 | //wglp.viewport(0, 0, canv.width, canv.height); 67 | init(); 68 | } 69 | 70 | function createUI(): void { 71 | const sliderLine = document.getElementById("sliderLine") as Slider; 72 | sliderLine.max = numPointList.length - 1; 73 | sliderLine.addEventListener("input", () => { 74 | numPoints = numPointList[sliderLine.value]; 75 | init(); 76 | }); 77 | sliderLine.getAriaValueText = () => { 78 | return numPointList[sliderLine.value].toString(); 79 | }; 80 | 81 | const sliderFreq = document.getElementById("sliderFreq") as Slider; 82 | sliderFreq.addEventListener("input", () => { 83 | freq = sliderFreq.value; 84 | }); 85 | 86 | const sliderRotation = document.getElementById("sliderRotation") as Slider; 87 | sliderRotation.addEventListener("input", () => { 88 | rotation = sliderRotation.value; 89 | }); 90 | } 91 | -------------------------------------------------------------------------------- /vanilla/dist/polar.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"polar.js","sourceRoot":"","sources":["../src/polar.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /vanilla/src/axis/axis.ts: -------------------------------------------------------------------------------- 1 | //import { unitConvert2string } from "./sim/unitConverter"; 2 | 3 | const canvasX = document.getElementById("canvas_xAxis") as HTMLCanvasElement; 4 | const canvasY = document.getElementById("canvas_yAxis") as HTMLCanvasElement; 5 | 6 | //let canvasSize = { width: 0, height: 0 } as CanvasSize; 7 | 8 | const initCanvas = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => { 9 | const devicePixelRatio = window.devicePixelRatio || 1; 10 | canvas.width = canvas.clientWidth * devicePixelRatio; 11 | canvas.height = canvas.clientHeight * devicePixelRatio; 12 | 13 | //canvasSize = { width: canvas.width, height: canvas.height }; 14 | 15 | const ctx2d = canvas.getContext("2d"); 16 | if (ctx2d) { 17 | ctx2d.font = "16px Courier New"; 18 | ctx2d.fillStyle = "white"; 19 | ctx2d.strokeStyle = "white"; 20 | } 21 | return ctx2d; 22 | 23 | //const rect = canvas?.getBoundingClientRect(); 24 | //console.log("axis->", rect); 25 | }; 26 | 27 | const ctxX = initCanvas(canvasX); 28 | const ctxY = initCanvas(canvasY); 29 | 30 | const updateX = ( 31 | ctx2d: CanvasRenderingContext2D, 32 | width: number, 33 | height: number, 34 | scale: number, 35 | offset: number, 36 | divs: number 37 | ) => { 38 | ctx2d.clearRect(0, 0, width, height); 39 | 40 | for (let i = 0; i < divs; i++) { 41 | const midpoint = -(offset - i / (divs / 2) + 1) / scale; 42 | const x = (i / divs) * width; 43 | 44 | ctx2d.fillText(`${midpoint.toExponential(2)}`, x, 15); 45 | //ctx.fillRect(10, 10, 100, 100); 46 | ctx2d.moveTo(x, 0); 47 | ctx2d.lineTo(x, 10); 48 | ctx2d.stroke(); 49 | } 50 | }; 51 | 52 | const updateY = ( 53 | ctx2d: CanvasRenderingContext2D, 54 | width: number, 55 | height: number, 56 | scale: number, 57 | offset: number, 58 | divs: number 59 | ) => { 60 | //console.log("yaxis->", canvasSize); 61 | ctx2d.clearRect(0, 0, width, height); 62 | for (let i = 0; i < divs; i++) { 63 | const midpoint = -(offset + i / (divs / 2) - 1) / scale; 64 | const y = (i / divs) * height; 65 | 66 | ctx2d.fillText(`${midpoint.toExponential(2)}`, 5, y); 67 | //ctx.fillRect(10, 10, 100, 100); 68 | ctx2d.moveTo(width - 10, y); 69 | ctx2d.lineTo(width, y); 70 | ctx2d.stroke(); 71 | } 72 | }; 73 | 74 | export const updateAxisX = (scale: number, offset: number, divs: number): void => { 75 | //console.log("axis->", axis == "y"); 76 | //console.log("axis->", midpoint); 77 | if (ctxX) { 78 | updateX(ctxX, canvasX.width, canvasX.height, scale, offset, divs); 79 | } 80 | }; 81 | 82 | export const updateAxisY = (scale: number, offset: number, divs: number): void => { 83 | if (ctxY) { 84 | updateY(ctxY, canvasY.width, canvasY.height, scale, offset, divs); 85 | } 86 | }; 87 | 88 | //updateAxisX(1, 0); 89 | -------------------------------------------------------------------------------- /vanilla/inject.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | const names = ["histogram", "scatterXY", "polar", "radar", "static", "cross"]; 4 | 5 | names.forEach((element) => { 6 | injectCode(element); 7 | }); 8 | 9 | function injectCode(filename) { 10 | fs.readFile(filename + ".html", "utf-8", function (err, data) { 11 | if (err) { 12 | console.error(err); 13 | return; 14 | } 15 | 16 | let newData = data; 17 | 18 | fs.readFile("jpsm.json", "utf-8", function (err, jsonData) { 19 | if (err) { 20 | console.error(err); 21 | return; 22 | } 23 | 24 | // Convert the JSON data to a JavaScript object 25 | const parsedData = JSON.parse(jsonData); 26 | 27 | const moduleScript = ` 28 | 33 | 34 | 46 | `; 47 | 48 | // Insert your code here 49 | const codeToInsert = 50 | '" + 53 | "\n" + 54 | moduleScript; 55 | const tagLocation = ""; 56 | 57 | // Remove the previous injected code 58 | newData = newData.replace(/ 105 | 106 | -------------------------------------------------------------------------------- /vanilla/dist/microphone.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"microphone.js","sourceRoot":"","sources":["../src/microphone.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /vanilla/dist/cross.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "webgl-plot"; 2 | const numLines = 2; 3 | const AuxLines = { crossX: 0, crossY: 1, testRec: 2 }; 4 | const canvas = document.getElementById("my_canvas"); 5 | const info = document.getElementById("info"); 6 | let crossX = 0; 7 | let crossY = 0; 8 | let numX; 9 | let wglp; 10 | createUI(); 11 | init(); 12 | let resizeId; 13 | window.addEventListener("resize", () => { 14 | window.clearTimeout(resizeId); 15 | resizeId = window.setTimeout(doneResizing, 500); 16 | }); 17 | function newFrame() { 18 | updateTextDisplay(); 19 | wglp.update(); 20 | requestAnimationFrame(newFrame); 21 | } 22 | requestAnimationFrame(newFrame); 23 | function init() { 24 | const devicePixelRatio = window.devicePixelRatio || 1; 25 | canvas.width = canvas.clientWidth * devicePixelRatio; 26 | canvas.height = canvas.clientHeight * devicePixelRatio; 27 | numX = 10000; 28 | wglp = new WebglPlot(canvas); 29 | wglp.removeAllLines(); 30 | for (let i = 0; i < numLines; i++) { 31 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 32 | const line = new WebglLine(color, numX); 33 | line.lineSpaceX(-1, 2 / numX); 34 | wglp.addDataLine(line); 35 | } 36 | wglp.linesData.forEach((line) => { 37 | line.setY(0, Math.random() - 0.5); 38 | for (let i = 1; i < line.numPoints; i++) { 39 | let y = line.getY(i - 1) + 0.01 * (Math.round(Math.random()) - 0.5); 40 | if (y > 0.9) { 41 | y = 0.9; 42 | } 43 | if (y < -0.9) { 44 | y = -0.9; 45 | } 46 | line.setY(i, y); 47 | } 48 | }); 49 | // test rec 50 | const testRect = new WebglLine(new ColorRGBA(0.1, 0.9, 0.9, 1), 4); 51 | testRect.loop = true; 52 | testRect.xy = new Float32Array([-0.7, -0.8, -0.7, 0.8, -0.6, 0.8, -0.6, -0.8]); 53 | //wglp.viewport(0, 0, 1000, 1000); 54 | wglp.gScaleX = 1; 55 | canvas.addEventListener("dblclick", dblClick); 56 | canvas.addEventListener("mousemove", mouseMove); 57 | canvas.addEventListener("contextmenu", contextMenu); 58 | //canvas.style.cursor = "zoom-in"; 59 | canvas.style.cursor = "crosshair"; 60 | //add cross 61 | const green = new ColorRGBA(0.1, 0.9, 0.1, 1); 62 | wglp.addAuxLine(new WebglLine(green, 2)); 63 | wglp.addAuxLine(new WebglLine(green, 2)); 64 | wglp.addAuxLine(testRect); 65 | } 66 | function mouseMove(e) { 67 | const x = (1 / wglp.gScaleX) * 68 | ((2 * ((e.pageX - canvas.offsetLeft) * devicePixelRatio - canvas.width / 2)) / canvas.width - 69 | wglp.gOffsetX); 70 | const y = (1 / wglp.gScaleY) * 71 | ((2 * (canvas.height / 2 - (e.pageY - canvas.offsetTop) * devicePixelRatio)) / canvas.height - 72 | wglp.gOffsetY); 73 | cross(x, y); 74 | } 75 | function cross(x, y) { 76 | wglp.linesAux[AuxLines.crossX].xy = new Float32Array([x, -1, x, 1]); 77 | wglp.linesAux[AuxLines.crossY].xy = new Float32Array([-1, y, 1, y]); 78 | crossX = x; 79 | crossY = y; 80 | } 81 | function dblClick(e) { 82 | e.preventDefault(); 83 | wglp.gScaleX = 1; 84 | wglp.gOffsetX = 0; 85 | } 86 | function contextMenu(e) { 87 | e.preventDefault(); 88 | } 89 | function doneResizing() { 90 | //wglp.viewport(0, 0, canv.width, canv.height); 91 | } 92 | function createUI() { 93 | const sliderScale = document.getElementById("sliderScale"); 94 | sliderScale.addEventListener("input", () => { 95 | wglp.gScaleX = sliderScale.value; 96 | updateTextDisplay(); 97 | }); 98 | const sliderOffset = document.getElementById("sliderOffset"); 99 | sliderOffset.addEventListener("input", () => { 100 | wglp.gOffsetX = -1 * sliderOffset.value * wglp.gScaleX; 101 | updateTextDisplay(); 102 | }); 103 | } 104 | function log(str) { 105 | //display.innerHTML = str; 106 | console.log(str); 107 | } 108 | function updateTextDisplay() { 109 | info.innerHTML = `Zoom: ${wglp.gScaleX.toFixed(2)}, Offset ${wglp.gOffsetX.toFixed(2)}, X:${crossX.toFixed(3)} Y:${crossY.toFixed(3)}`; 110 | } 111 | //# sourceMappingURL=cross.js.map -------------------------------------------------------------------------------- /vanilla/dist/microphone.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | const canvas = document.getElementById("my_canvas"); 3 | const player = document.getElementById("player"); 4 | let numX; 5 | let analyser; 6 | let wglp; 7 | let lineTime; 8 | let lineFreq; 9 | const fftSize = Math.pow(2, 14); 10 | const maxA = new Array(60 * 2); 11 | //createUI(); 12 | init(); 13 | let resizeId; 14 | window.addEventListener("resize", () => { 15 | window.clearTimeout(resizeId); 16 | resizeId = window.setTimeout(doneResizing, 500); 17 | }); 18 | function newFrame() { 19 | if (analyser != undefined) { 20 | update(); 21 | } 22 | wglp.update(); 23 | //wglp.gScaleY = scaleY; 24 | window.requestAnimationFrame(newFrame); 25 | } 26 | window.requestAnimationFrame(newFrame); 27 | function init() { 28 | // Create the canvas and get a context 29 | // Set the canvas to be the same size as the original image 30 | // Draw the image onto the top-left corner of the canvas 31 | const handleSuccess = function (stream) { 32 | player.srcObject = stream; 33 | const context = new AudioContext(); 34 | const source = context.createMediaStreamSource(stream); 35 | const processor = context.createScriptProcessor(1024, 1, 1); 36 | analyser = context.createAnalyser(); 37 | analyser.fftSize = fftSize; 38 | const bufferLength = analyser.frequencyBinCount; 39 | console.log(analyser.frequencyBinCount); 40 | const dataArray = new Uint8Array(bufferLength); 41 | source.connect(analyser); 42 | //source.connect(processor); 43 | //processor.connect(context.destination); 44 | processor.onaudioprocess = () => { 45 | // Do something with the data, e.g. convert it to WAV 46 | //console.log(e.inputBuffer); 47 | //analyser.getByteTimeDomainData(dataArray); 48 | analyser.getByteFrequencyData(dataArray); 49 | //const buffer = e.inputBuffer.getChannelData(0); 50 | for (let i = 0; i < dataArray.length; i++) { 51 | //line.setY(i, buffer[i]); 52 | lineFreq.setY(i, dataArray[i] / 255); 53 | } 54 | //console.log(dataArray); 55 | }; 56 | }; 57 | navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(handleSuccess); 58 | player.height = 0; 59 | player.width = 0; 60 | const devicePixelRatio = window.devicePixelRatio || 1; 61 | canvas.width = canvas.clientWidth * devicePixelRatio; 62 | canvas.height = canvas.clientHeight * devicePixelRatio; 63 | numX = 1024; 64 | lineTime = new WebglLine(new ColorRGBA(0.2, 0.9, 0.2, 1), numX); 65 | lineFreq = new WebglLine(new ColorRGBA(0.9, 0.2, 0.2, 1), fftSize / 2); 66 | wglp = new WebglPlot(canvas); 67 | wglp.gOffsetY = 0; 68 | lineTime.offsetY = 0; 69 | lineTime.lineSpaceX(-1, 2 / numX); 70 | lineFreq.lineSpaceX(-1, 2 / numX); 71 | lineFreq.offsetY = -1; 72 | lineFreq.scaleY = 2; 73 | lineFreq.offsetX = -1; 74 | wglp.addLine(lineTime); 75 | wglp.addLine(lineFreq); 76 | } 77 | function update() { 78 | const bufferLength = analyser.frequencyBinCount; 79 | const dataArray = new Uint8Array(bufferLength); 80 | analyser.getByteFrequencyData(dataArray); 81 | const maxF = Math.max(...dataArray); 82 | for (let i = 0; i < dataArray.length; i++) { 83 | //line.setY(i, buffer[i]); 84 | lineFreq.setY(i, dataArray[i] / maxF); 85 | lineFreq.setX(i, Math.log10(i) / 2); 86 | //max = Math.max(buffer.); 87 | } 88 | const buffer = new Float32Array(bufferLength); 89 | analyser.getFloatTimeDomainData(buffer); 90 | maxA.shift(); 91 | maxA.push(Math.max(...buffer)); 92 | const maxAcurrent = Math.max(...maxA); 93 | for (let i = 0; i < buffer.length; i++) { 94 | lineTime.setY(i, buffer[i] / maxAcurrent); 95 | } 96 | } 97 | function doneResizing() { 98 | //wglp.viewport(0, 0, canv.width, canv.height); 99 | init(); 100 | } 101 | /*function createUI(): void { 102 | const ui = document.getElementById("ui") as HTMLDivElement; 103 | }*/ 104 | //# sourceMappingURL=microphone.js.map -------------------------------------------------------------------------------- /vanilla/thick.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 | 68 |
69 | 70 |
71 | 72 | 88 | 89 |

90 | 91 |
92 | 107 |

108 | See the 109 | Github repository for the details 112 |

113 |
114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /vanilla/src/microphone.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "https://cdn.skypack.dev/webgl-plot"; 2 | 3 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 4 | const player = document.getElementById("player") as HTMLVideoElement; 5 | 6 | let numX: number; 7 | 8 | let analyser: AnalyserNode; 9 | 10 | let wglp: WebglPlot; 11 | let lineTime: WebglLine; 12 | let lineFreq: WebglLine; 13 | 14 | const fftSize = Math.pow(2, 14); 15 | const maxA = new Array(60 * 2); 16 | 17 | //createUI(); 18 | 19 | init(); 20 | 21 | let resizeId: number; 22 | window.addEventListener("resize", () => { 23 | window.clearTimeout(resizeId); 24 | resizeId = window.setTimeout(doneResizing, 500); 25 | }); 26 | 27 | function newFrame(): void { 28 | if (analyser != undefined) { 29 | update(); 30 | } 31 | 32 | wglp.update(); 33 | //wglp.gScaleY = scaleY; 34 | 35 | window.requestAnimationFrame(newFrame); 36 | } 37 | 38 | window.requestAnimationFrame(newFrame); 39 | 40 | function init(): void { 41 | // Create the canvas and get a context 42 | 43 | // Set the canvas to be the same size as the original image 44 | 45 | // Draw the image onto the top-left corner of the canvas 46 | 47 | const handleSuccess = function (stream: MediaStream) { 48 | player.srcObject = stream; 49 | 50 | const context = new AudioContext(); 51 | const source = context.createMediaStreamSource(stream); 52 | const processor = context.createScriptProcessor(1024, 1, 1); 53 | analyser = context.createAnalyser(); 54 | 55 | analyser.fftSize = fftSize; 56 | const bufferLength = analyser.frequencyBinCount; 57 | console.log(analyser.frequencyBinCount); 58 | const dataArray = new Uint8Array(bufferLength); 59 | 60 | source.connect(analyser); 61 | 62 | //source.connect(processor); 63 | //processor.connect(context.destination); 64 | 65 | processor.onaudioprocess = () => { 66 | // Do something with the data, e.g. convert it to WAV 67 | //console.log(e.inputBuffer); 68 | //analyser.getByteTimeDomainData(dataArray); 69 | analyser.getByteFrequencyData(dataArray); 70 | //const buffer = e.inputBuffer.getChannelData(0); 71 | for (let i = 0; i < dataArray.length; i++) { 72 | //line.setY(i, buffer[i]); 73 | lineFreq.setY(i, dataArray[i] / 255); 74 | } 75 | 76 | //console.log(dataArray); 77 | }; 78 | }; 79 | 80 | navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(handleSuccess); 81 | 82 | player.height = 0; 83 | player.width = 0; 84 | 85 | const devicePixelRatio = window.devicePixelRatio || 1; 86 | canvas.width = canvas.clientWidth * devicePixelRatio; 87 | canvas.height = canvas.clientHeight * devicePixelRatio; 88 | 89 | numX = 1024; 90 | 91 | lineTime = new WebglLine(new ColorRGBA(0.2, 0.9, 0.2, 1), numX); 92 | 93 | lineFreq = new WebglLine(new ColorRGBA(0.9, 0.2, 0.2, 1), fftSize / 2); 94 | 95 | wglp = new WebglPlot(canvas); 96 | 97 | wglp.gOffsetY = 0; 98 | 99 | lineTime.offsetY = 0; 100 | 101 | lineTime.lineSpaceX(-1, 2 / numX); 102 | lineFreq.lineSpaceX(-1, 2 / numX); 103 | 104 | lineFreq.offsetY = -1; 105 | lineFreq.scaleY = 2; 106 | lineFreq.offsetX = -1; 107 | 108 | wglp.addLine(lineTime); 109 | wglp.addLine(lineFreq); 110 | } 111 | 112 | function update(): void { 113 | const bufferLength = analyser.frequencyBinCount; 114 | const dataArray = new Uint8Array(bufferLength); 115 | analyser.getByteFrequencyData(dataArray); 116 | 117 | const maxF = Math.max(...dataArray); 118 | 119 | for (let i = 0; i < dataArray.length; i++) { 120 | //line.setY(i, buffer[i]); 121 | lineFreq.setY(i, dataArray[i] / maxF); 122 | lineFreq.setX(i, Math.log10(i) / 2); 123 | //max = Math.max(buffer.); 124 | } 125 | 126 | const buffer = new Float32Array(bufferLength); 127 | analyser.getFloatTimeDomainData(buffer); 128 | 129 | maxA.shift(); 130 | maxA.push(Math.max(...buffer)); 131 | const maxAcurrent = Math.max(...maxA); 132 | for (let i = 0; i < buffer.length; i++) { 133 | lineTime.setY(i, buffer[i] / maxAcurrent); 134 | } 135 | } 136 | 137 | function doneResizing(): void { 138 | //wglp.viewport(0, 0, canv.width, canv.height); 139 | init(); 140 | } 141 | 142 | /*function createUI(): void { 143 | const ui = document.getElementById("ui") as HTMLDivElement; 144 | }*/ 145 | -------------------------------------------------------------------------------- /vanilla/src/cross.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglLine } from "webgl-plot"; 2 | import { Slider } from "@spectrum-web-components/slider"; 3 | 4 | const numLines = 2; 5 | const AuxLines = { crossX: 0, crossY: 1, testRec: 2 }; 6 | 7 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 8 | const info = document.getElementById("info") as HTMLSpanElement; 9 | 10 | let crossX = 0; 11 | let crossY = 0; 12 | 13 | let numX: number; 14 | 15 | let wglp: WebglPlot; 16 | 17 | createUI(); 18 | 19 | init(); 20 | 21 | let resizeId: number; 22 | window.addEventListener("resize", () => { 23 | window.clearTimeout(resizeId); 24 | resizeId = window.setTimeout(doneResizing, 500); 25 | }); 26 | 27 | function newFrame(): void { 28 | updateTextDisplay(); 29 | wglp.update(); 30 | 31 | requestAnimationFrame(newFrame); 32 | } 33 | 34 | requestAnimationFrame(newFrame); 35 | 36 | function init(): void { 37 | const devicePixelRatio = window.devicePixelRatio || 1; 38 | canvas.width = canvas.clientWidth * devicePixelRatio; 39 | canvas.height = canvas.clientHeight * devicePixelRatio; 40 | 41 | numX = 10000; 42 | 43 | wglp = new WebglPlot(canvas); 44 | 45 | wglp.removeAllLines(); 46 | 47 | for (let i = 0; i < numLines; i++) { 48 | const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1); 49 | const line = new WebglLine(color, numX); 50 | line.lineSpaceX(-1, 2 / numX); 51 | wglp.addDataLine(line); 52 | } 53 | 54 | wglp.linesData.forEach((line) => { 55 | (line as WebglLine).setY(0, Math.random() - 0.5); 56 | for (let i = 1; i < line.numPoints; i++) { 57 | let y = (line as WebglLine).getY(i - 1) + 0.01 * (Math.round(Math.random()) - 0.5); 58 | if (y > 0.9) { 59 | y = 0.9; 60 | } 61 | if (y < -0.9) { 62 | y = -0.9; 63 | } 64 | (line as WebglLine).setY(i, y); 65 | } 66 | }); 67 | 68 | // test rec 69 | const testRect = new WebglLine(new ColorRGBA(0.1, 0.9, 0.9, 1), 4); 70 | testRect.loop = true; 71 | testRect.xy = new Float32Array([-0.7, -0.8, -0.7, 0.8, -0.6, 0.8, -0.6, -0.8]); 72 | 73 | //wglp.viewport(0, 0, 1000, 1000); 74 | wglp.gScaleX = 1; 75 | 76 | canvas.addEventListener("dblclick", dblClick); 77 | canvas.addEventListener("mousemove", mouseMove); 78 | 79 | canvas.addEventListener("contextmenu", contextMenu); 80 | 81 | //canvas.style.cursor = "zoom-in"; 82 | canvas.style.cursor = "crosshair"; 83 | 84 | //add cross 85 | const green = new ColorRGBA(0.1, 0.9, 0.1, 1); 86 | 87 | wglp.addAuxLine(new WebglLine(green, 2)); 88 | wglp.addAuxLine(new WebglLine(green, 2)); 89 | wglp.addAuxLine(testRect); 90 | } 91 | 92 | function mouseMove(e: MouseEvent): void { 93 | const x = 94 | (1 / wglp.gScaleX) * 95 | ((2 * ((e.pageX - canvas.offsetLeft) * devicePixelRatio - canvas.width / 2)) / canvas.width - 96 | wglp.gOffsetX); 97 | const y = 98 | (1 / wglp.gScaleY) * 99 | ((2 * (canvas.height / 2 - (e.pageY - canvas.offsetTop) * devicePixelRatio)) / canvas.height - 100 | wglp.gOffsetY); 101 | cross(x, y); 102 | } 103 | 104 | function cross(x: number, y: number): void { 105 | wglp.linesAux[AuxLines.crossX].xy = new Float32Array([x, -1, x, 1]); 106 | wglp.linesAux[AuxLines.crossY].xy = new Float32Array([-1, y, 1, y]); 107 | crossX = x; 108 | crossY = y; 109 | } 110 | 111 | function dblClick(e: MouseEvent) { 112 | e.preventDefault(); 113 | wglp.gScaleX = 1; 114 | wglp.gOffsetX = 0; 115 | } 116 | 117 | function contextMenu(e: Event) { 118 | e.preventDefault(); 119 | } 120 | 121 | function doneResizing(): void { 122 | //wglp.viewport(0, 0, canv.width, canv.height); 123 | } 124 | 125 | function createUI(): void { 126 | const sliderScale = document.getElementById("sliderScale") as Slider; 127 | sliderScale.addEventListener("input", () => { 128 | wglp.gScaleX = sliderScale.value; 129 | updateTextDisplay(); 130 | }); 131 | 132 | const sliderOffset = document.getElementById("sliderOffset") as Slider; 133 | sliderOffset.addEventListener("input", () => { 134 | wglp.gOffsetX = -1 * sliderOffset.value * wglp.gScaleX; 135 | updateTextDisplay(); 136 | }); 137 | } 138 | 139 | function log(str: string) { 140 | //display.innerHTML = str; 141 | console.log(str); 142 | } 143 | 144 | function updateTextDisplay() { 145 | info.innerHTML = `Zoom: ${wglp.gScaleX.toFixed(2)}, Offset ${wglp.gOffsetX.toFixed( 146 | 2 147 | )}, X:${crossX.toFixed(3)} Y:${crossY.toFixed(3)}`; 148 | } 149 | -------------------------------------------------------------------------------- /vanilla/microphone.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Radar 7 | 8 | 9 | 10 | 11 | 68 |
69 | 70 | 71 |
72 | 73 | 89 | 90 |

91 | 92 |
93 | 94 |

95 | Permission is required to access media input. No data is being uploaded. All data remains 96 | locally and processed in client's browser 97 |

98 | 99 |
100 | 115 |

116 | See the 117 | Github repository for the details 120 |

121 |
122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /vanilla/grid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 | 68 |
69 | 70 |
71 | 72 | 88 | 89 |

90 | 91 |
92 |

Move the Sliders!

93 | 94 | 95 | 96 | 97 |
98 | 99 |
100 | 115 |

116 | See the 117 | Github repository for the details 120 |

121 |
122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /vanilla/multiPlot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 | 68 |
69 | 70 |
71 | 72 | 88 | 89 |

90 | 91 |
92 |

Change the grid numbers!

93 | 94 | 95 | 96 | 97 |
98 | 99 |
100 | 115 |

116 | See the 117 | Github repository for the details 120 |

121 |
122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /vanilla/dist/cross.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"cross.js","sourceRoot":"","sources":["../src/cross.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /vanilla/jpsm.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "@spectrum-web-components/button": "https://ga.jspm.io/npm:@spectrum-web-components/button@0.19.10/src/index.js", 4 | "@spectrum-web-components/button/sp-button.js": "https://ga.jspm.io/npm:@spectrum-web-components/button@0.19.10/sp-button.js", 5 | "@spectrum-web-components/slider": "https://ga.jspm.io/npm:@spectrum-web-components/slider@0.15.5/src/index.js", 6 | "@spectrum-web-components/slider/sp-slider-handle.js": "https://ga.jspm.io/npm:@spectrum-web-components/slider@0.15.5/sp-slider-handle.js", 7 | "@spectrum-web-components/slider/sp-slider.js": "https://ga.jspm.io/npm:@spectrum-web-components/slider@0.15.5/sp-slider.js", 8 | "@spectrum-web-components/theme": "https://ga.jspm.io/npm:@spectrum-web-components/theme@0.14.10/src/index.js", 9 | "@spectrum-web-components/theme/scale-large.js": "https://ga.jspm.io/npm:@spectrum-web-components/theme@0.14.10/scale-large.js", 10 | "@spectrum-web-components/theme/sp-theme.js": "https://ga.jspm.io/npm:@spectrum-web-components/theme@0.14.10/sp-theme.js", 11 | "@spectrum-web-components/theme/theme-dark.js": "https://ga.jspm.io/npm:@spectrum-web-components/theme@0.14.10/theme-dark.js", 12 | "webgl-plot": "https://ga.jspm.io/npm:webgl-plot@0.7.0/dist/webglplot.esm.mjs" 13 | }, 14 | "scopes": { 15 | "https://ga.jspm.io/": { 16 | "@internationalized/number": "https://ga.jspm.io/npm:@internationalized/number@3.1.2/dist/module.js", 17 | "@lit-labs/observers/mutation_controller.js": "https://ga.jspm.io/npm:@lit-labs/observers@1.1.0/mutation_controller.js", 18 | "@lit/reactive-element": "https://ga.jspm.io/npm:@lit/reactive-element@1.6.1/reactive-element.js", 19 | "@lit/reactive-element/decorators/": "https://ga.jspm.io/npm:@lit/reactive-element@1.6.1/decorators/", 20 | "@spectrum-web-components/action-button/sp-action-button.js": "https://ga.jspm.io/npm:@spectrum-web-components/action-button@0.10.10/sp-action-button.js", 21 | "@spectrum-web-components/base": "https://ga.jspm.io/npm:@spectrum-web-components/base@0.7.4/src/index.js", 22 | "@spectrum-web-components/base/src/": "https://ga.jspm.io/npm:@spectrum-web-components/base@0.7.4/src/", 23 | "@spectrum-web-components/clear-button/src/clear-button.css.js": "https://ga.jspm.io/npm:@spectrum-web-components/clear-button@0.2.5/src/clear-button.css.js", 24 | "@spectrum-web-components/close-button/src/close-button.css.js": "https://ga.jspm.io/npm:@spectrum-web-components/close-button@0.3.8/src/close-button.css.js", 25 | "@spectrum-web-components/field-label/sp-field-label.js": "https://ga.jspm.io/npm:@spectrum-web-components/field-label@0.10.5/sp-field-label.js", 26 | "@spectrum-web-components/help-text/src/manage-help-text.js": "https://ga.jspm.io/npm:@spectrum-web-components/help-text@0.2.9/src/manage-help-text.js", 27 | "@spectrum-web-components/icon": "https://ga.jspm.io/npm:@spectrum-web-components/icon@0.12.7/src/index.js", 28 | "@spectrum-web-components/icon/src/": "https://ga.jspm.io/npm:@spectrum-web-components/icon@0.12.7/src/", 29 | "@spectrum-web-components/icons-ui/icons/": "https://ga.jspm.io/npm:@spectrum-web-components/icons-ui@0.9.7/icons/", 30 | "@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js": "https://ga.jspm.io/npm:@spectrum-web-components/icons-workflow@0.9.7/icons/sp-icon-alert.js", 31 | "@spectrum-web-components/iconset/src/iconset-registry.js": "https://ga.jspm.io/npm:@spectrum-web-components/iconset@0.7.6/src/iconset-registry.js", 32 | "@spectrum-web-components/number-field/sp-number-field.js": "https://ga.jspm.io/npm:@spectrum-web-components/number-field@0.5.10/sp-number-field.js", 33 | "@spectrum-web-components/reactive-controllers/src/": "https://ga.jspm.io/npm:@spectrum-web-components/reactive-controllers@0.3.5/src/", 34 | "@spectrum-web-components/shared": "https://ga.jspm.io/npm:@spectrum-web-components/shared@0.15.5/src/index.js", 35 | "@spectrum-web-components/shared/src/": "https://ga.jspm.io/npm:@spectrum-web-components/shared@0.15.5/src/", 36 | "@spectrum-web-components/textfield": "https://ga.jspm.io/npm:@spectrum-web-components/textfield@0.13.10/src/index.js", 37 | "focus-visible": "https://ga.jspm.io/npm:focus-visible@5.2.0/dist/focus-visible.js", 38 | "lit": "https://ga.jspm.io/npm:lit@2.6.1/index.js", 39 | "lit-element/lit-element.js": "https://ga.jspm.io/npm:lit-element@3.2.2/lit-element.js", 40 | "lit-html": "https://ga.jspm.io/npm:lit-html@2.6.1/lit-html.js", 41 | "lit-html/": "https://ga.jspm.io/npm:lit-html@2.6.1/", 42 | "lit/": "https://ga.jspm.io/npm:lit@2.6.1/" 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /vanilla/camera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Radar 7 | 8 | 9 | 10 | 11 | 68 |
69 | 70 | 71 | 72 |
73 | 74 | 90 | 91 |

92 | 93 |
94 | 95 | 101 | 102 |

103 | Permission is required to access media input. No data is being uploaded. All data remains 104 | locally and processed in client's browser 105 |

106 | 107 |
108 | 123 |

124 | See the 125 | Github repository for the details 128 |

129 |
130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /vanilla/log.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 71 |
72 | 73 |
74 | 75 | 90 | 91 |

92 | 93 |
94 |

Move the Sliders!

95 | 96 | 97 | 98 | 99 |
100 | 101 |
102 | 117 |

118 | See the 119 | Github repository for the details 122 |

123 |
124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /vanilla/dist/histogram.js: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglStep } from "webgl-plot"; 2 | let randXSize = 10; 3 | //let maxY = 0; 4 | const xmin = 0; 5 | const xmax = 100; 6 | let numBins = 100; 7 | let Xmin = 40; 8 | let Xmax = 60; 9 | let Xskew = 1; 10 | const canvas = document.getElementById("my_canvas"); 11 | const devicePixelRatio = window.devicePixelRatio || 1; 12 | canvas.width = canvas.clientWidth * devicePixelRatio; 13 | canvas.height = canvas.clientHeight * devicePixelRatio; 14 | let scaleY = 1; 15 | let X; 16 | let xbins; 17 | let ybins; 18 | let wglp; 19 | let line; 20 | const randXSizeList = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000]; 21 | const binSizeNumber = [2, 5, 10, 20, 50, 100, 200, 500, 1000]; 22 | createUI(); 23 | init(); 24 | let resizeId; 25 | window.addEventListener("resize", () => { 26 | window.clearTimeout(resizeId); 27 | resizeId = window.setTimeout(doneResizing, 500); 28 | }); 29 | function newFrame() { 30 | update(); 31 | wglp.gScaleY = scaleY; 32 | wglp.update(); 33 | window.requestAnimationFrame(newFrame); 34 | } 35 | window.requestAnimationFrame(newFrame); 36 | function init() { 37 | wglp = new WebglPlot(canvas); 38 | xbins = new Float32Array(numBins); 39 | ybins = new Float32Array(numBins); 40 | wglp.gOffsetY = -1; 41 | wglp.gOffsetX = -1; 42 | wglp.gScaleX = 2 / numBins; 43 | for (let i = 0; i < xbins.length; i++) { 44 | xbins[i] = (i * (xmax - xmin)) / numBins + xmin; 45 | } 46 | const color = new ColorRGBA(1, 1, 0, 1); 47 | line = new WebglStep(color, numBins); 48 | // line.linespaceX(-1, 2 / numBins); 49 | // instead of line above we are applying offsetX and scaleX 50 | line.lineSpaceX(0, 1); 51 | wglp.addLine(line); 52 | } 53 | function update() { 54 | X = new Float32Array(randXSize); 55 | randnArray(X); 56 | for (let i = 0; i < ybins.length; i++) { 57 | ybins[i] = 0; 58 | } 59 | for (let i = 0; i < X.length; i++) { 60 | const bin = X[i]; 61 | if (bin < xmin) { 62 | ybins[0]++; 63 | } 64 | else { 65 | if (bin > xmax) { 66 | ybins[numBins - 1]++; 67 | } 68 | else { 69 | const index = (numBins * (bin - xmin)) / (xmax - xmin); 70 | ybins[Math.floor(index)]++; 71 | } 72 | } 73 | } 74 | // Normalize ? 75 | for (let i = 0; i < ybins.length; i++) { 76 | const y = (ybins[i] / randXSize) * numBins; 77 | line.setY(i, y * 0.02); 78 | } 79 | } 80 | /** https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve */ 81 | function randnBM(min, max, skew) { 82 | let u = 0; 83 | let v = 0; 84 | while (u === 0) { 85 | u = Math.random(); 86 | } // Converting [0,1) to (0,1) 87 | while (v === 0) { 88 | v = Math.random(); 89 | } 90 | let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v); 91 | num = num / 10.0 + 0.5; // Translate to 0 -> 1 92 | if (num > 1 || num < 0) { 93 | num = randnBM(min, max, skew); 94 | } // resample between 0 and 1 if out of range 95 | num = Math.pow(num, skew); // Skew 96 | num *= max - min; // Stretch to fill range 97 | num += min; // offset to min 98 | return num; 99 | } 100 | function randnArray(array) { 101 | for (let i = 0; i < array.length; i++) { 102 | array[i] = randnBM(Xmin, Xmax, Xskew); 103 | } 104 | } 105 | function doneResizing() { 106 | //wglp.viewport(0, 0, canv.width, canv.height); 107 | } 108 | function createUI() { 109 | const sliderXsize = document.getElementById("sliderXsize"); 110 | sliderXsize.addEventListener("input", (event) => { 111 | const slider = event.target; 112 | randXSize = randXSizeList[slider.value]; 113 | }); 114 | sliderXsize.addEventListener("change", (event) => { 115 | init(); 116 | }); 117 | sliderXsize.getAriaValueText = () => { 118 | return randXSize.toString(); 119 | }; 120 | const sliderXrange = document.getElementById("sliderXrange"); 121 | sliderXrange.addEventListener("input", (event) => { 122 | const slider = event.target; 123 | Xmin = slider.name === "min" ? slider.value : Xmin; 124 | Xmax = slider.name === "max" ? slider.value : Xmax; 125 | }); 126 | const sliderYscale = document.getElementById("sliderYscale"); 127 | sliderYscale.addEventListener("input", (event) => { 128 | const slider = event.target; 129 | scaleY = slider.value; 130 | }); 131 | const sliderBinNumber = document.getElementById("sliderBinNumber"); 132 | sliderBinNumber.addEventListener("input", (event) => { 133 | const slider = event.target; 134 | numBins = binSizeNumber[slider.value]; 135 | init(); 136 | }); 137 | sliderBinNumber.getAriaValueText = () => { 138 | return numBins.toString(); 139 | }; 140 | const sliderSkew = document.getElementById("sliderSkew"); 141 | sliderSkew.addEventListener("input", (event) => { 142 | const slider = event.target; 143 | Xskew = slider.value; 144 | }); 145 | } 146 | //# sourceMappingURL=histogram.js.map -------------------------------------------------------------------------------- /vanilla/axis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Webgl line plotting framework - Lines 7 | 8 | 9 | 10 | 11 | 68 | 69 |
78 |
79 | 80 |
81 |
82 | 83 |
84 |
85 |
86 | 87 |
88 |
89 | 90 |
91 | 92 | 108 | 109 |

110 | 111 |
112 | 113 |

Move the plot!

114 |
115 | 116 | 117 |

With Mouse: Right click and hold to pan

118 |

With Mouse: Left click hold & drag to zoom in the selected window

119 |

With Mouse: Double click to reset view

120 |

With Touch: pinch & zoom - drag

121 |

122 |

Refresh the page for a new random data set

123 | 124 |
125 | 140 |

141 | See the 142 | Github repository for the details 145 |

146 |
147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /vanilla/dist/histogram.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"histogram.js","sourceRoot":"","sources":["../src/histogram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAI7D,IAAI,SAAS,GAAG,EAAE,CAAC;AACnB,eAAe;AACf,MAAM,IAAI,GAAG,CAAC,CAAC;AACf,MAAM,IAAI,GAAG,GAAG,CAAC;AACjB,IAAI,OAAO,GAAG,GAAG,CAAC;AAClB,IAAI,IAAI,GAAG,EAAE,CAAC;AACd,IAAI,IAAI,GAAG,EAAE,CAAC;AACd,IAAI,KAAK,GAAG,CAAC,CAAC;AAEd,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAsB,CAAC;AAEzE,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;AACtD,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,GAAG,gBAAgB,CAAC;AACrD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEvD,IAAI,MAAM,GAAG,CAAC,CAAC;AAEf,IAAI,CAAe,CAAC;AACpB,IAAI,KAAmB,CAAC;AACxB,IAAI,KAAmB,CAAC;AAExB,IAAI,IAAe,CAAC;AACpB,IAAI,IAAe,CAAC;AAEpB,MAAM,aAAa,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACjG,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAE9D,QAAQ,EAAE,CAAC;AAEX,IAAI,EAAE,CAAC;AAEP,IAAI,QAAgB,CAAC;AACrB,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;IACrC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC9B,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,SAAS,QAAQ;IACf,MAAM,EAAE,CAAC;IACT,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,MAAM,EAAE,CAAC;IAEd,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AAEvC,SAAS,IAAI;IACX,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,KAAK,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAElC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IACnB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IACnB,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;KACjD;IAED,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACrC,oCAAoC;IACpC,2DAA2D;IAC3D,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,MAAM;IACb,CAAC,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IAChC,UAAU,CAAC,CAAC,CAAC,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;KACd;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjB,IAAI,GAAG,GAAG,IAAI,EAAE;YACd,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;SACZ;aAAM;YACL,IAAI,GAAG,GAAG,IAAI,EAAE;gBACd,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;aACtB;iBAAM;gBACL,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;gBACvD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;aAC5B;SACF;KACF;IAED,cAAc;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;KACxB;AACH,CAAC;AAED,kHAAkH;AAClH,SAAS,OAAO,CAAC,GAAW,EAAE,GAAW,EAAE,IAAY;IACrD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,KAAK,CAAC,EAAE;QACd,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;KACnB,CAAC,4BAA4B;IAC9B,OAAO,CAAC,KAAK,CAAC,EAAE;QACd,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;KACnB;IACD,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEtE,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,sBAAsB;IAC9C,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE;QACtB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;KAC/B,CAAC,2CAA2C;IAC7C,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO;IAClC,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,wBAAwB;IAC1C,GAAG,IAAI,GAAG,CAAC,CAAC,gBAAgB;IAC5B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,KAAmB;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACrC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;KACvC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,+CAA+C;AACjD,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAW,CAAC;IAErE,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;QACtC,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,WAAW,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAY,EAAE,EAAE;QACtD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,WAAW,CAAC,gBAAgB,GAAG,GAAG,EAAE;QAClC,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAW,CAAC;IAEvE,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;QACtC,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAW,CAAC;IAEvE,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAW,CAAC;IAE7E,eAAe,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QACzD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;QACtC,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,gBAAgB,GAAG,GAAG,EAAE;QACtC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAW,CAAC;IAEnE,UAAU,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QACpD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;QACtC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"} -------------------------------------------------------------------------------- /vanilla/src/histogram.ts: -------------------------------------------------------------------------------- 1 | import { WebglPlot, ColorRGBA, WebglStep } from "webgl-plot"; 2 | import { Slider } from "@spectrum-web-components/slider"; 3 | import { Button } from "@spectrum-web-components/button"; 4 | 5 | let randXSize = 10; 6 | //let maxY = 0; 7 | const xmin = 0; 8 | const xmax = 100; 9 | let numBins = 100; 10 | let Xmin = 40; 11 | let Xmax = 60; 12 | let Xskew = 1; 13 | 14 | const canvas = document.getElementById("my_canvas") as HTMLCanvasElement; 15 | 16 | const devicePixelRatio = window.devicePixelRatio || 1; 17 | canvas.width = canvas.clientWidth * devicePixelRatio; 18 | canvas.height = canvas.clientHeight * devicePixelRatio; 19 | 20 | let scaleY = 1; 21 | 22 | let X: Float32Array; 23 | let xbins: Float32Array; 24 | let ybins: Float32Array; 25 | 26 | let wglp: WebglPlot; 27 | let line: WebglStep; 28 | 29 | const randXSizeList = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000]; 30 | const binSizeNumber = [2, 5, 10, 20, 50, 100, 200, 500, 1000]; 31 | 32 | createUI(); 33 | 34 | init(); 35 | 36 | let resizeId: number; 37 | window.addEventListener("resize", () => { 38 | window.clearTimeout(resizeId); 39 | resizeId = window.setTimeout(doneResizing, 500); 40 | }); 41 | 42 | function newFrame(): void { 43 | update(); 44 | wglp.gScaleY = scaleY; 45 | wglp.update(); 46 | 47 | window.requestAnimationFrame(newFrame); 48 | } 49 | 50 | window.requestAnimationFrame(newFrame); 51 | 52 | function init(): void { 53 | wglp = new WebglPlot(canvas); 54 | xbins = new Float32Array(numBins); 55 | ybins = new Float32Array(numBins); 56 | 57 | wglp.gOffsetY = -1; 58 | wglp.gOffsetX = -1; 59 | wglp.gScaleX = 2 / numBins; 60 | 61 | for (let i = 0; i < xbins.length; i++) { 62 | xbins[i] = (i * (xmax - xmin)) / numBins + xmin; 63 | } 64 | 65 | const color = new ColorRGBA(1, 1, 0, 1); 66 | line = new WebglStep(color, numBins); 67 | // line.linespaceX(-1, 2 / numBins); 68 | // instead of line above we are applying offsetX and scaleX 69 | line.lineSpaceX(0, 1); 70 | wglp.addLine(line); 71 | } 72 | 73 | function update(): void { 74 | X = new Float32Array(randXSize); 75 | randnArray(X); 76 | 77 | for (let i = 0; i < ybins.length; i++) { 78 | ybins[i] = 0; 79 | } 80 | 81 | for (let i = 0; i < X.length; i++) { 82 | const bin = X[i]; 83 | 84 | if (bin < xmin) { 85 | ybins[0]++; 86 | } else { 87 | if (bin > xmax) { 88 | ybins[numBins - 1]++; 89 | } else { 90 | const index = (numBins * (bin - xmin)) / (xmax - xmin); 91 | ybins[Math.floor(index)]++; 92 | } 93 | } 94 | } 95 | 96 | // Normalize ? 97 | for (let i = 0; i < ybins.length; i++) { 98 | const y = (ybins[i] / randXSize) * numBins; 99 | line.setY(i, y * 0.02); 100 | } 101 | } 102 | 103 | /** https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve */ 104 | function randnBM(min: number, max: number, skew: number): number { 105 | let u = 0; 106 | let v = 0; 107 | while (u === 0) { 108 | u = Math.random(); 109 | } // Converting [0,1) to (0,1) 110 | while (v === 0) { 111 | v = Math.random(); 112 | } 113 | let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v); 114 | 115 | num = num / 10.0 + 0.5; // Translate to 0 -> 1 116 | if (num > 1 || num < 0) { 117 | num = randnBM(min, max, skew); 118 | } // resample between 0 and 1 if out of range 119 | num = Math.pow(num, skew); // Skew 120 | num *= max - min; // Stretch to fill range 121 | num += min; // offset to min 122 | return num; 123 | } 124 | 125 | function randnArray(array: Float32Array): void { 126 | for (let i = 0; i < array.length; i++) { 127 | array[i] = randnBM(Xmin, Xmax, Xskew); 128 | } 129 | } 130 | 131 | function doneResizing(): void { 132 | //wglp.viewport(0, 0, canv.width, canv.height); 133 | } 134 | 135 | function createUI(): void { 136 | const sliderXsize = document.getElementById("sliderXsize") as Slider; 137 | 138 | sliderXsize.addEventListener("input", (event: Event) => { 139 | const slider = event.target as Slider; 140 | randXSize = randXSizeList[slider.value]; 141 | }); 142 | sliderXsize.addEventListener("change", (event: Event) => { 143 | init(); 144 | }); 145 | 146 | sliderXsize.getAriaValueText = () => { 147 | return randXSize.toString(); 148 | }; 149 | 150 | const sliderXrange = document.getElementById("sliderXrange") as Slider; 151 | 152 | sliderXrange.addEventListener("input", (event: Event) => { 153 | const slider = event.target as Slider; 154 | Xmin = slider.name === "min" ? slider.value : Xmin; 155 | Xmax = slider.name === "max" ? slider.value : Xmax; 156 | }); 157 | 158 | const sliderYscale = document.getElementById("sliderYscale") as Slider; 159 | 160 | sliderYscale.addEventListener("input", (event: Event) => { 161 | const slider = event.target as Slider; 162 | scaleY = slider.value; 163 | }); 164 | 165 | const sliderBinNumber = document.getElementById("sliderBinNumber") as Slider; 166 | 167 | sliderBinNumber.addEventListener("input", (event: Event) => { 168 | const slider = event.target as Slider; 169 | numBins = binSizeNumber[slider.value]; 170 | init(); 171 | }); 172 | 173 | sliderBinNumber.getAriaValueText = () => { 174 | return numBins.toString(); 175 | }; 176 | 177 | const sliderSkew = document.getElementById("sliderSkew") as Slider; 178 | 179 | sliderSkew.addEventListener("input", (event: Event) => { 180 | const slider = event.target as Slider; 181 | Xskew = slider.value; 182 | }); 183 | } 184 | --------------------------------------------------------------------------------