{"id":20256306,"url":"https://github.com/devcybiko/glsmodel","last_synced_at":"2025-08-12T00:40:49.819Z","repository":{"id":99128040,"uuid":"473011653","full_name":"devcybiko/glsModel","owner":"devcybiko","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-19T15:20:25.000Z","size":56244,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-03T14:48:43.089Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devcybiko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-23T02:37:08.000Z","updated_at":"2022-03-23T02:39:16.000Z","dependencies_parsed_at":"2023-06-04T01:15:42.171Z","dependency_job_id":null,"html_url":"https://github.com/devcybiko/glsModel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/devcybiko/glsModel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devcybiko%2FglsModel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devcybiko%2FglsModel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devcybiko%2FglsModel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devcybiko%2FglsModel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devcybiko","download_url":"https://codeload.github.com/devcybiko/glsModel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devcybiko%2FglsModel/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269981677,"owners_count":24507279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T10:46:12.013Z","updated_at":"2025-08-12T00:40:49.791Z","avatar_url":"https://github.com/devcybiko.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# glsModel Demo\n\nI rewrote the excellent example by TL Ford to create a more declarative method of embedding models and clicking on them in the model viewer.\n\n## Model Files\n\nThe `glsModel` requires that the model files be created with names for each material. In Blender this is usually \"Model.001,\" \"Model.002,\" etc... But you can give more descriptive names if you like. \n\nOlder versions of this code used special values in the BCF (baseColorFactor). This is a tedious process and error prone. While `glsModel` still supports this mechanism, material \"names\" are the recommended route.\n\n## Model Viewer\n\nThe Model Viewer is a Google-supplied plugin and is documented here: https://modelviewer.dev/.\n\nThere is also an excellent model editor here: https://modelviewer.dev/editor/\n\nThe Model Viewer can be placed anywhere on the HTML page by specifying an `id=\"name\"` attribute on a tag. Any tag can be used, but the `\u003cdiv\u003e` is the best choice.\n\nAlso any `action` can be performed when a `material` is clicked. Currently, three actions exist:\n\n* `update` will send user-defined HTML to a user-specified `\u003cdiv\u003e`.\n* `debug` will report the material.name to the user-specificed `\u003cdiv\u003e`.\n* `error` will report errors in read to the user-specified `\u003cdiv\u003e`.\n\n## Running the example program\n\nSadly, modern browsers don't allow running local file examples. You'll need to run a `server` of some sort. Python and PHP servers are readily available but will need to be installed. Alternatively, there is a plugin for VSCode that will launch an HTML file on a local server. See this: https://www.youtube.com/watch?v=Wd7cVmtiFUU\n\n## HTML Code\n\nYou must include both the `model-viewer` and `glsModel` scripts in the `\u003chead\u003e` portion of your HTML.\n\n```html\n    \u003cscript type=\"module\" src=\"https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"./js/glsModel.js\"\u003e\u003c/script\u003e\n```\nTo facilitate inserting the `model-viewer` and its associated model into your HTML page, you must add `div` tags with appropriate `id=\"...\"` attributes. Here is a sample.\n\n* DIV WITH ID\n```html\n\u003cdiv id=\"buttonOnBox_div\"\u003e\u003c/div\u003e\n\u003cdiv id=\"buttonOnBox_output\"\u003e\u003c/div\u003e\n```\n\nYou must also add a call to the `glsModel.load()` function at **the very end** of your HTML.\n\n* glsModel.load()\n```html\n  \u003cscript\u003eglsModel.load(\"./data/buttonOnBox.json\");\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\nFinally, you can add as many `model-viewers` to your HTML page as you like. Just repeat the `DIV WITH ID` and `glsModel.load()` bits of HTML wherever you want the model to show up.\n\n## JSON data files\n\nThe definition of where to display a model and the actions to perform are defined in a JSON file. For more information on the format of a JSON file, visit: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON\n\nIt's not that scary, I promise. The file begins and ends with curly braces `{}`. Every element within the file is a set of key/value pairs enclosed in curly braces `{}`, separated by a colon, and ending with a comma. The format is recursive, so a value can be either a string in double-quotes or another \"object\" in curly braces.\n\nIn the following sub-sections I reference `./data/buttonOnBox.json`\n\n### model-viewer section\n\nThis section defines everything about the `model-viewer` including its `id`, `src`, and which `div` to insert it into.\n\n```json\n    \"model-viewer\": {\n        \"src\": \"./images/buttonOnBox.glb\",\n        \"id\": \"buttonOnBox\",\n        \"div\": \"#buttonOnBox_div\",\n        \"control-index\": 1,\n\n        \"alt\": \"alt text\",\n        \"auto-rotate\": \"\",\n        \"camera-controls\": \"\",\n        \"ar\": \"\",\n        \"ar-status\": \"\"\n    },\n\n...\n}\n```\n\n* src: the URL to the .glb file - I put all of mine in the `images` folder\n* id: the `id=\"...\"` name of this model-viewer - IT MUST BE UNIQUE (don't reuse model-viwer names in the same HTML page).\n* control-index: this is the 'index' into the baseColorFactor to extract the hidden (secret) values (defunct).\n* div: the id of the div to insert the `model-viewer` into. (You can use `query` specifiers `.` and `#` for class or id. If no query specifier is used, the `#` is assumed).\n\nThe following fields are passed to the `model-viewer`. For more information about these and other tags, see the model editor: https://modelviewer.dev/editor/\n\n* alt: the alternate text if the browser cannot display it\n* auto-rotate: whether the model will rotate automatically (remove this tag to stop rotation)\n* camera-controls: whether the model has camera controls\n* ar: disabilities info\n* ar-status: disabilities info\n* (there are many more options that are not documented here. see the model editor).\n\n### The mapping section\n\nFor each `material.name` in your .glb file, an entry is made in the `mapping` section. When the user clicks on the model, one of these mapping sections is invoked based on the `material.name` value as specified in your Blender file.\n\n* The `null` mapping is invoked if the user hits outside the defined model. \n* The `default` mapping is invoked if the user hits the model, but no mapping exists.\n\n```json\n    \"mapping\": {\n        \"default\": {\n            \"action\": \"error\",\n             \"div\": \"#buttonOnBox_output\"\n        },\n        \"null\": {\n            \"action\": \"update\",\n            \"html\": \"\u003ch2\u003eYou missed the target\u003c/h2\u003e\",\n            \"div\": \"#buttonOnBox_output\"\n        },\n        \"Material\": {\n            \"action\": \"update\",\n            \"html\": \"\u003ch2\u003eTry Again\u003c/h2\u003e\",\n            \"div\": \"#buttonOnBox_output\"\n        },\n        \"Material.001\": {\n            \"action\": \"update\",\n            \"html\": \"\u003ch1 style='color:red'\u003eThis is the top button.  It does nothing useful at all.\u003c/h1\u003e\",\n            \"color\": \"red\",\n            \"div\": \"#buttonOnBox_output\"\n        }\n    },\n```\n\nWithin each mapping is an action to take and some parameters to pass to it.\n\n* action: this is the action to take. It represents code in the `glsModel.js` file that will be invoked. Currently,three actions are defined: `update`, `debug`, and `error`.\n* div: this is the `id` of the div to send HTML to\n* html: this is HTML code to insert into the div\n* color: this is the color to \"flash\" the material that was clicked on.\n\n### Color section\n\nSince the `model-viewer` uses RGBA values to determine how things are colored, I've created a color map. The name (\"red\", \"orange\", etc...) can be used in the `color` definition of `actions` (see above). The four values represent red, green, blue, and alpha (brightness). They must be between 0.0 and 1.0. You can add as many color entries as you like and name them however you see fit.\n\n\n```json\n     \"colors\": {\n        \"red\": [1, 0, 0, 1.0],\n        \"orange\": [1, 0.45, 0.125, 1.0],\n        \"yellow\": [1, 1, 0, 1.0],\n        \"green\": [0, 1, 0, 1.0],\n        \"blue\": [0, 0, 1, 1.0],\n        \"cyan\": [0, 1, 1, 1.0],\n        \"violet\": [1, 0, 1, 1.0],\n        \"black\": [0, 0, 0, 1.0],\n        \"white\": [1, 1, 1, 1.0]\n     }\n}\n```\n\n## Actions\n\nThe `mapping` section defines what action is performed on a mouse-click. Each `action` takes its own set of parameters. Actions are invoked as a result of a user clicking on some portion of a model.\n\n### The `update` Action\n\nThe `update` action will display some HTML on the screen whenever the user clicks a bit of material in the model. The material will also change color to give visual feedback to the user.\n\n```json\n    \"mapping\": {\n        \"Material.001\": {\n            \"action\": \"update\",\n            \"html\": \"\u003ch1 style='color:red'\u003eThis is the top button.  It does nothing useful at all.\u003c/h1\u003e\",\n            \"color\": \"red\",\n            \"div\": \"#buttonOnBox_output\"\n        },\n```\n\nIn this example, when the user clicks on the `Material.001` object , the `update` action will be invoked with the following parameters:\n\n* html: a line of HTML to be inserted into a div. This can be as simple as some text, or as complex as HTML formatted text, images, styles, and classes. Special care must be taken to avoid double-quotes in the HTML string. If double quotes are needed a backslash-double-quote `\\\"` can be used, or the HTML glyph code `\u0026quot;`.\n* color: this is the color you want the `material` object to flash when the user clicks it. (If no color is specified, the `material` will not change color.)\n* div: this is the `\u003cdiv\u003e` tag to update. The `div` in question must have an `id=\"...\"` attribute. \n\nTo recap, when the user clicks on the `material` with the `name` in the key (`\"Material.001\"` in this case), the `red H1` text \"This is the top button.  It does nothing useful at all.\" will be inserted at the `div` with an `id=\"buttonOnBox_output\"` and the `material` will flash `red`.\n\n### The `debug` Action\n\nThe `debug` action is used to display the `material.name` whenever the user clicks on a material. It is used when you don't know the `material.name` of materials in your model. This is most useful in the `default` mapping while you're testing the model.\n\n```json\n    \"mapping\": {\n        \"default\": {\n            \"action\": \"debug\",\n            \"color\": \"red\",\n            \"div\": \"#buttonOnBox_output\"\n        },\n```\n\nIn this example, when the user clicks on an unknown object, the `debug` action will be invoked with the following parameters:\n\n* color: this is the color you want the `material` object to flash when the user clicks it. (If no color is specified, the `material` will not change color.)\n* div: this is the `\u003cdiv\u003e` tag to update. The `div` in question must have an `id=\"...\"` attribute. It will be updated with the `material.name` of the object.\n\nTo recap, when the user clicks on the `material` the `debug` action will show the material's name in the specified div.\n\n### The `error` Action\n\nThe `error` action is used to display the `material.name` in red. It is similar to the `debug` action but generates red text as if it were an error. It is used inside the `default` mapping.\n\n```json\n    \"mapping\": {\n        \"default\": {\n            \"action\": \"error\",\n            \"color\": \"red\",\n            \"div\": \"#buttonOnBox_output\"\n        },\n```\n\nIn this example, when the user clicks on an unknown object, the `error` action will be invoked with the following parameters:\n\n* color: this is the color you want the `material` object to flash when the user clicks it. (If no color is specified, the `material` will not change color.)\n* div: this is the `\u003cdiv\u003e` tag to update. The `div` in question must have an `id=\"...\"` attribute. It will be updated with the `material.name` of the object in `red`.\n\nTo recap, when the user clicks on the `material` the `error` action will show the material's name in red in the specified div.\n\n\n## Naming Conventions\n\nI tend to name objects in the HTML and JSON files after the `.glb` file to be displayed. So, if the name of the .glb file is `ATK02_JOB_2.glb`, I will do the following:\n\n1. Name my JSON file `ATK02_JOB_2.json`\n2. Append the `id` of the `div` where the model is displayed with `_div`: `\u003cdiv id='ATK02_JOB_2_div'\u003e\u003c/div\u003e`\n3. Append the `id` of the `div` where the output is displayed with `_output`: `\u003cdiv id='ATK_JOB_2_output'\u003e\u003c/div\u003e`\n4. In the .json file, set the `id` of the `model-viewer` equal to the name of the file. This helps to keep the `id` names unique.\n\n```json\n    \"model-viewer\": {\n        \"src\": \"./images/buttonOnBox.glb\",\n        \"id\": \"buttonOnBox\",\n        \"div\": \"#buttonOnBox_div\",\n        \"control-index\": 1,\n```\n\n## Conclusions\n\nI hope this script will make it easier to embed models and the `model-viewer` into your code. \n\nIf you need more `actions` than currently supplied, please feel free to reach out to me and suggest add-ons.\n\nGreg Smith\ngreg@agilefrontiers.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevcybiko%2Fglsmodel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevcybiko%2Fglsmodel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevcybiko%2Fglsmodel/lists"}