diff --git a/doc/spritesheet-generation.md b/doc/spritesheet-generation.md index 752854e510..f44335506b 100644 --- a/doc/spritesheet-generation.md +++ b/doc/spritesheet-generation.md @@ -1,18 +1,21 @@ ## intro -In Hubs, we use texture atlassing to improve rendering efficiency. This document explains how to generate and use the spritesheet that is read by the SpriteSystem. +We use texture atlassing to improve rendering and loading efficiency. This document explains how to generate the spritesheets used by the SpriteSystem and the page's css. -Information about what spritesheets are and how to use them is outside the scope of this document, as there are many good resources about this on the web. +## generating spritesheets -## generate a spritesheet - -After installing the project dependencies, the spritesheet can be generated with the command `npm run spritesheet`. The exact parameters used by this script can be inspected in the `package.json` where it is defined. More information about the tool we use, `spritesheet-js`, can be found on its [github page](https://github.com/krzysztof-o/spritesheet.js/). +After installing the project dependencies, spritesheets can be generated with the command `npm run spritesheet`. The exact parameters used by this script can be inspected in the `package.json` where it is defined. More information about the tool we use, `spritesheet-js`, can be found on the [github page](https://github.com/mozillareality/spritesheet.js/). The steps to generate a spritesheet are : -1. Move all the sprites you want to include in the spritesheet into `src/assets/images/sprites/`. -1. Type `npm run spritesheet`. This will generate `sprite-system-spritesheet.json` and `sprite-system-spritesheet.png` in the directory `src/assets/images/spritesheets/`. +1. Move sprites you want in the sprite-system-spritesheet to `src/assets/images/sprites/`. +1. Move sprites you want in the css-spritesheet to `src/assets/images/css-sprites/`. +1. Type `npm run spritesheet`. This will generate + `sprite-system-spritesheet.json` with `sprite-system-spritesheet.png` for the + sprite system and + `css-spritesheet.css` with `css-spritesheet.png` in the directory `src/assets/images/spritesheets/`. -The name of the sprite that is used in the generated `json` file is the same as the name of original image file in `src/assets/images/sprites/`. Hence we refer to the image within a spritesheet by its associated filename. This may lead to some confusion, but should be clear when inspecting the `json` file. +## Notes -Note for hubs devs: Most of the source images in `src/assets/images/sprites` were exported from Figma. If you want to alter these images, it is probably best to do so in Figma, then re-export at the desired size. +The name of the sprite that is used in the generated `json` file is the same as its source filename; When a sprite component has the name `foo.png`, the sprite system looks for that name in the `json` file. It does not use the `foo.png` source file. +The source images are exported from Figma. If you want to alter these images, it is probably best to do so in Figma, then re-export at the desired size. It is a good idea to stack all of the icons you want to export on top of one another in figma, because otherwise Figma produces surprisingly different results for similar icons when exporting at low resolution. diff --git a/package-lock.json b/package-lock.json index af31ba6a58..0e82881862 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3522,8 +3522,7 @@ "array-find-index": { "version": "1.0.2", "resolved": "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" }, "array-flatten": { "version": "2.1.2", @@ -5332,8 +5331,7 @@ "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" }, "batch": { "version": "0.6.1", @@ -5717,8 +5715,7 @@ "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, "builtin-status-codes": { "version": "3.0.0", @@ -5847,14 +5844,12 @@ "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, "camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" @@ -6781,7 +6776,6 @@ "version": "0.4.1", "resolved": "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, "requires": { "array-find-index": "^1.0.1" } @@ -6860,8 +6854,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decamelize-keys": { "version": "1.1.0", @@ -7596,7 +7589,6 @@ "version": "1.3.2", "resolved": "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -9453,8 +9445,7 @@ "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" }, "get-stream": { "version": "3.0.0", @@ -9895,8 +9886,7 @@ "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=", - "dev": true + "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=" }, "hpack.js": { "version": "2.1.6", @@ -10195,8 +10185,7 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "iferr": { "version": "0.1.5", @@ -10340,7 +10329,6 @@ "version": "2.1.0", "resolved": "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, "requires": { "repeating": "^2.0.0" } @@ -10559,8 +10547,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "1.0.1", @@ -10580,7 +10567,6 @@ "version": "1.0.0", "resolved": "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, "requires": { "builtin-modules": "^1.0.0" } @@ -10685,7 +10671,6 @@ "version": "1.0.2", "resolved": "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -10872,8 +10857,7 @@ "is-utf8": { "version": "0.2.1", "resolved": "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, "is-whitespace-character": { "version": "1.0.2", @@ -11375,7 +11359,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -11387,8 +11370,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, @@ -11589,7 +11571,6 @@ "version": "1.6.0", "resolved": "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, "requires": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" @@ -11676,8 +11657,7 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" }, "map-visit": { "version": "1.0.0", @@ -11813,7 +11793,6 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, "requires": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", @@ -12476,7 +12455,6 @@ "version": "2.4.0", "resolved": "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", @@ -12554,8 +12532,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "oauth-sign": { "version": "0.9.0", @@ -13063,7 +13040,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, "requires": { "error-ex": "^1.2.0" } @@ -13114,7 +13090,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, "requires": { "pinkie-promise": "^2.0.0" } @@ -13188,14 +13163,12 @@ "pinkie": { "version": "2.0.4", "resolved": "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "^2.0.0" } @@ -14602,7 +14575,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", @@ -14613,7 +14585,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", @@ -14623,8 +14594,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, @@ -14632,7 +14602,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" @@ -14642,7 +14611,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" @@ -14745,7 +14713,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, "requires": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" @@ -15065,7 +15032,6 @@ "version": "2.0.1", "resolved": "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, "requires": { "is-finite": "^1.0.0" } @@ -15459,8 +15425,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz", - "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", - "dev": true + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=" }, "semver-diff": { "version": "2.1.0", @@ -15653,8 +15618,7 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-concat": { "version": "1.0.0", @@ -15846,7 +15810,6 @@ "version": "3.0.0", "resolved": "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -15855,14 +15818,12 @@ "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=", - "dev": true + "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -15871,8 +15832,7 @@ "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=", - "dev": true + "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=" }, "spdy": { "version": "4.0.0", @@ -15997,9 +15957,8 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "spritesheet-js": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/spritesheet-js/-/spritesheet-js-1.2.6.tgz", - "integrity": "sha1-BwnN0yIE1bj1A87xCOFbNuMbCBg=", + "version": "git+https://github.com/MozillaReality/spritesheet.js.git#c9895d5f2a3105a64d5d024e5b2946333c07c972", + "from": "git+https://github.com/MozillaReality/spritesheet.js.git", "dev": true, "requires": { "async": "~0.2.9", @@ -16229,7 +16188,6 @@ "version": "2.0.0", "resolved": "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, "requires": { "is-utf8": "^0.2.0" } @@ -16253,7 +16211,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, "requires": { "get-stdin": "^4.0.1" } @@ -17510,8 +17467,7 @@ "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, "trim-off-newlines": { "version": "1.0.1", @@ -17552,6 +17508,41 @@ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "ts-ebml": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ts-ebml/-/ts-ebml-2.0.2.tgz", + "integrity": "sha512-V/HdlCn3FITQrFHQlVE02XtfMiRLab2QB/YOCfkbJWqiFYG/j5v7gHKV+wem6g0PD6/uxXs5oxMQfDXILmts/Q==", + "requires": { + "buffer": "^5.0.7", + "commander": "^2.11.0", + "ebml": "^2.2.1", + "ebml-block": "^1.1.0", + "events": "^1.1.1", + "int64-buffer": "^0.1.9", + "matroska": "^2.2.3" + }, + "dependencies": { + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "int64-buffer": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", + "integrity": "sha1-J3siiofZWtd30HwTgyAiQGpHNCM=" + } + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz", @@ -18075,7 +18066,6 @@ "version": "3.0.3", "resolved": "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" diff --git a/package.json b/package.json index 17fb4a2510..a7ef8c5b6c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test": "npm run lint && npm run test:unit && npm run build", "test:unit": "ava", "stats": "rimraf ./dist && webpack --mode=production --json", - "spritesheet": "spritesheet-js -f json -p src/assets/images/spritesheets/ --padding 8 --divisibleByTwo -n sprite-system-spritesheet --powerOfTwo src/assets/images/sprites/*" + "spritesheet": "spritesheet-js -f custom-scale-css-modules -p src/assets/images/spritesheets/ --padding 4 --divisibleByTwo -n css-spritesheet src/assets/images/css-sprites/* --hubsFlag anything --customHeight 40 --customWidth 40 && spritesheet-js -f json -p src/assets/images/spritesheets/ --padding 8 --divisibleByTwo -n sprite-system-spritesheet --powerOfTwo src/assets/images/sprites/*" }, "ava": { "files": [ @@ -128,7 +128,7 @@ "sass-loader": "^6.0.7", "selfsigned": "^1.10.2", "shelljs": "^0.8.1", - "spritesheet-js": "^1.2.6", + "spritesheet-js": "github:mozillareality/spritesheet.js#hubs/master", "style-loader": "^0.20.2", "stylelint": "^9.10.1", "stylelint-config-recommended-scss": "^3.2.0", diff --git a/src/assets/images/css-sprites/mic-0.png b/src/assets/images/css-sprites/mic-0.png new file mode 100644 index 0000000000..f38c83ad2d Binary files /dev/null and b/src/assets/images/css-sprites/mic-0.png differ diff --git a/src/assets/images/css-sprites/mic-0_hover.png b/src/assets/images/css-sprites/mic-0_hover.png new file mode 100644 index 0000000000..d9c1df3fc1 Binary files /dev/null and b/src/assets/images/css-sprites/mic-0_hover.png differ diff --git a/src/assets/images/css-sprites/mic-1.png b/src/assets/images/css-sprites/mic-1.png new file mode 100644 index 0000000000..d7feb6090a Binary files /dev/null and b/src/assets/images/css-sprites/mic-1.png differ diff --git a/src/assets/images/css-sprites/mic-1_hover.png b/src/assets/images/css-sprites/mic-1_hover.png new file mode 100644 index 0000000000..6f6fe53f98 Binary files /dev/null and b/src/assets/images/css-sprites/mic-1_hover.png differ diff --git a/src/assets/images/css-sprites/mic-2.png b/src/assets/images/css-sprites/mic-2.png new file mode 100644 index 0000000000..2ae1665bae Binary files /dev/null and b/src/assets/images/css-sprites/mic-2.png differ diff --git a/src/assets/images/css-sprites/mic-2_hover.png b/src/assets/images/css-sprites/mic-2_hover.png new file mode 100644 index 0000000000..880b96e867 Binary files /dev/null and b/src/assets/images/css-sprites/mic-2_hover.png differ diff --git a/src/assets/images/css-sprites/mic-3.png b/src/assets/images/css-sprites/mic-3.png new file mode 100644 index 0000000000..b777d9a51e Binary files /dev/null and b/src/assets/images/css-sprites/mic-3.png differ diff --git a/src/assets/images/css-sprites/mic-3_hover.png b/src/assets/images/css-sprites/mic-3_hover.png new file mode 100644 index 0000000000..dbeb59c650 Binary files /dev/null and b/src/assets/images/css-sprites/mic-3_hover.png differ diff --git a/src/assets/images/css-sprites/mic-4.png b/src/assets/images/css-sprites/mic-4.png new file mode 100644 index 0000000000..02761c562f Binary files /dev/null and b/src/assets/images/css-sprites/mic-4.png differ diff --git a/src/assets/images/css-sprites/mic-4_hover.png b/src/assets/images/css-sprites/mic-4_hover.png new file mode 100644 index 0000000000..90a1b07465 Binary files /dev/null and b/src/assets/images/css-sprites/mic-4_hover.png differ diff --git a/src/assets/images/css-sprites/mic-5.png b/src/assets/images/css-sprites/mic-5.png new file mode 100644 index 0000000000..5b06ae4473 Binary files /dev/null and b/src/assets/images/css-sprites/mic-5.png differ diff --git a/src/assets/images/css-sprites/mic-5_hover.png b/src/assets/images/css-sprites/mic-5_hover.png new file mode 100644 index 0000000000..f8a0f35eef Binary files /dev/null and b/src/assets/images/css-sprites/mic-5_hover.png differ diff --git a/src/assets/images/css-sprites/mic-6.png b/src/assets/images/css-sprites/mic-6.png new file mode 100644 index 0000000000..3d5db4dcb7 Binary files /dev/null and b/src/assets/images/css-sprites/mic-6.png differ diff --git a/src/assets/images/css-sprites/mic-6_hover.png b/src/assets/images/css-sprites/mic-6_hover.png new file mode 100644 index 0000000000..9bd98bc460 Binary files /dev/null and b/src/assets/images/css-sprites/mic-6_hover.png differ diff --git a/src/assets/images/css-sprites/mic-7.png b/src/assets/images/css-sprites/mic-7.png new file mode 100644 index 0000000000..2caa135f6d Binary files /dev/null and b/src/assets/images/css-sprites/mic-7.png differ diff --git a/src/assets/images/css-sprites/mic-7_hover.png b/src/assets/images/css-sprites/mic-7_hover.png new file mode 100644 index 0000000000..0f0f41a4e3 Binary files /dev/null and b/src/assets/images/css-sprites/mic-7_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-0.png b/src/assets/images/css-sprites/mic-off-0.png new file mode 100644 index 0000000000..d7c1c3f7a1 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-0.png differ diff --git a/src/assets/images/css-sprites/mic-off-0_hover.png b/src/assets/images/css-sprites/mic-off-0_hover.png new file mode 100644 index 0000000000..8843866698 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-0_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-1.png b/src/assets/images/css-sprites/mic-off-1.png new file mode 100644 index 0000000000..72b814f43c Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-1.png differ diff --git a/src/assets/images/css-sprites/mic-off-1_hover.png b/src/assets/images/css-sprites/mic-off-1_hover.png new file mode 100644 index 0000000000..241044dd55 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-1_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-2.png b/src/assets/images/css-sprites/mic-off-2.png new file mode 100644 index 0000000000..87f27ae90a Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-2.png differ diff --git a/src/assets/images/css-sprites/mic-off-2_hover.png b/src/assets/images/css-sprites/mic-off-2_hover.png new file mode 100644 index 0000000000..cde4201b6d Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-2_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-3.png b/src/assets/images/css-sprites/mic-off-3.png new file mode 100644 index 0000000000..704270986f Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-3.png differ diff --git a/src/assets/images/css-sprites/mic-off-3_hover.png b/src/assets/images/css-sprites/mic-off-3_hover.png new file mode 100644 index 0000000000..fc4eb1579f Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-3_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-4.png b/src/assets/images/css-sprites/mic-off-4.png new file mode 100644 index 0000000000..9524904eb3 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-4.png differ diff --git a/src/assets/images/css-sprites/mic-off-4_hover.png b/src/assets/images/css-sprites/mic-off-4_hover.png new file mode 100644 index 0000000000..1c9a17e429 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-4_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-5.png b/src/assets/images/css-sprites/mic-off-5.png new file mode 100644 index 0000000000..a2cb7bee1c Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-5.png differ diff --git a/src/assets/images/css-sprites/mic-off-5_hover.png b/src/assets/images/css-sprites/mic-off-5_hover.png new file mode 100644 index 0000000000..c9f08e3987 Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-5_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-6.png b/src/assets/images/css-sprites/mic-off-6.png new file mode 100644 index 0000000000..d986ef00fc Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-6.png differ diff --git a/src/assets/images/css-sprites/mic-off-6_hover.png b/src/assets/images/css-sprites/mic-off-6_hover.png new file mode 100644 index 0000000000..b7046f223c Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-6_hover.png differ diff --git a/src/assets/images/css-sprites/mic-off-7.png b/src/assets/images/css-sprites/mic-off-7.png new file mode 100644 index 0000000000..d9d2c7822b Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-7.png differ diff --git a/src/assets/images/css-sprites/mic-off-7_hover.png b/src/assets/images/css-sprites/mic-off-7_hover.png new file mode 100644 index 0000000000..be55cb769a Binary files /dev/null and b/src/assets/images/css-sprites/mic-off-7_hover.png differ diff --git a/src/assets/images/sprites/mic-0.png b/src/assets/images/sprites/mic-0.png new file mode 100644 index 0000000000..f38c83ad2d Binary files /dev/null and b/src/assets/images/sprites/mic-0.png differ diff --git a/src/assets/images/sprites/mic-0_hover.png b/src/assets/images/sprites/mic-0_hover.png new file mode 100644 index 0000000000..d9c1df3fc1 Binary files /dev/null and b/src/assets/images/sprites/mic-0_hover.png differ diff --git a/src/assets/images/sprites/mic-1.png b/src/assets/images/sprites/mic-1.png new file mode 100644 index 0000000000..d7feb6090a Binary files /dev/null and b/src/assets/images/sprites/mic-1.png differ diff --git a/src/assets/images/sprites/mic-1_hover.png b/src/assets/images/sprites/mic-1_hover.png new file mode 100644 index 0000000000..6f6fe53f98 Binary files /dev/null and b/src/assets/images/sprites/mic-1_hover.png differ diff --git a/src/assets/images/sprites/mic-2.png b/src/assets/images/sprites/mic-2.png new file mode 100644 index 0000000000..2ae1665bae Binary files /dev/null and b/src/assets/images/sprites/mic-2.png differ diff --git a/src/assets/images/sprites/mic-2_hover.png b/src/assets/images/sprites/mic-2_hover.png new file mode 100644 index 0000000000..880b96e867 Binary files /dev/null and b/src/assets/images/sprites/mic-2_hover.png differ diff --git a/src/assets/images/sprites/mic-3.png b/src/assets/images/sprites/mic-3.png new file mode 100644 index 0000000000..b777d9a51e Binary files /dev/null and b/src/assets/images/sprites/mic-3.png differ diff --git a/src/assets/images/sprites/mic-3_hover.png b/src/assets/images/sprites/mic-3_hover.png new file mode 100644 index 0000000000..dbeb59c650 Binary files /dev/null and b/src/assets/images/sprites/mic-3_hover.png differ diff --git a/src/assets/images/sprites/mic-4.png b/src/assets/images/sprites/mic-4.png new file mode 100644 index 0000000000..02761c562f Binary files /dev/null and b/src/assets/images/sprites/mic-4.png differ diff --git a/src/assets/images/sprites/mic-4_hover.png b/src/assets/images/sprites/mic-4_hover.png new file mode 100644 index 0000000000..90a1b07465 Binary files /dev/null and b/src/assets/images/sprites/mic-4_hover.png differ diff --git a/src/assets/images/sprites/mic-5.png b/src/assets/images/sprites/mic-5.png new file mode 100644 index 0000000000..5b06ae4473 Binary files /dev/null and b/src/assets/images/sprites/mic-5.png differ diff --git a/src/assets/images/sprites/mic-5_hover.png b/src/assets/images/sprites/mic-5_hover.png new file mode 100644 index 0000000000..f8a0f35eef Binary files /dev/null and b/src/assets/images/sprites/mic-5_hover.png differ diff --git a/src/assets/images/sprites/mic-6.png b/src/assets/images/sprites/mic-6.png new file mode 100644 index 0000000000..3d5db4dcb7 Binary files /dev/null and b/src/assets/images/sprites/mic-6.png differ diff --git a/src/assets/images/sprites/mic-6_hover.png b/src/assets/images/sprites/mic-6_hover.png new file mode 100644 index 0000000000..9bd98bc460 Binary files /dev/null and b/src/assets/images/sprites/mic-6_hover.png differ diff --git a/src/assets/images/sprites/mic-7.png b/src/assets/images/sprites/mic-7.png new file mode 100644 index 0000000000..2caa135f6d Binary files /dev/null and b/src/assets/images/sprites/mic-7.png differ diff --git a/src/assets/images/sprites/mic-7_hover.png b/src/assets/images/sprites/mic-7_hover.png new file mode 100644 index 0000000000..0f0f41a4e3 Binary files /dev/null and b/src/assets/images/sprites/mic-7_hover.png differ diff --git a/src/assets/images/sprites/mic-off-0.png b/src/assets/images/sprites/mic-off-0.png new file mode 100644 index 0000000000..d7c1c3f7a1 Binary files /dev/null and b/src/assets/images/sprites/mic-off-0.png differ diff --git a/src/assets/images/sprites/mic-off-0_hover.png b/src/assets/images/sprites/mic-off-0_hover.png new file mode 100644 index 0000000000..8843866698 Binary files /dev/null and b/src/assets/images/sprites/mic-off-0_hover.png differ diff --git a/src/assets/images/sprites/mic-off-1.png b/src/assets/images/sprites/mic-off-1.png new file mode 100644 index 0000000000..72b814f43c Binary files /dev/null and b/src/assets/images/sprites/mic-off-1.png differ diff --git a/src/assets/images/sprites/mic-off-1_hover.png b/src/assets/images/sprites/mic-off-1_hover.png new file mode 100644 index 0000000000..241044dd55 Binary files /dev/null and b/src/assets/images/sprites/mic-off-1_hover.png differ diff --git a/src/assets/images/sprites/mic-off-2.png b/src/assets/images/sprites/mic-off-2.png new file mode 100644 index 0000000000..87f27ae90a Binary files /dev/null and b/src/assets/images/sprites/mic-off-2.png differ diff --git a/src/assets/images/sprites/mic-off-2_hover.png b/src/assets/images/sprites/mic-off-2_hover.png new file mode 100644 index 0000000000..cde4201b6d Binary files /dev/null and b/src/assets/images/sprites/mic-off-2_hover.png differ diff --git a/src/assets/images/sprites/mic-off-3.png b/src/assets/images/sprites/mic-off-3.png new file mode 100644 index 0000000000..704270986f Binary files /dev/null and b/src/assets/images/sprites/mic-off-3.png differ diff --git a/src/assets/images/sprites/mic-off-3_hover.png b/src/assets/images/sprites/mic-off-3_hover.png new file mode 100644 index 0000000000..fc4eb1579f Binary files /dev/null and b/src/assets/images/sprites/mic-off-3_hover.png differ diff --git a/src/assets/images/sprites/mic-off-4.png b/src/assets/images/sprites/mic-off-4.png new file mode 100644 index 0000000000..9524904eb3 Binary files /dev/null and b/src/assets/images/sprites/mic-off-4.png differ diff --git a/src/assets/images/sprites/mic-off-4_hover.png b/src/assets/images/sprites/mic-off-4_hover.png new file mode 100644 index 0000000000..1c9a17e429 Binary files /dev/null and b/src/assets/images/sprites/mic-off-4_hover.png differ diff --git a/src/assets/images/sprites/mic-off-5.png b/src/assets/images/sprites/mic-off-5.png new file mode 100644 index 0000000000..a2cb7bee1c Binary files /dev/null and b/src/assets/images/sprites/mic-off-5.png differ diff --git a/src/assets/images/sprites/mic-off-5_hover.png b/src/assets/images/sprites/mic-off-5_hover.png new file mode 100644 index 0000000000..c9f08e3987 Binary files /dev/null and b/src/assets/images/sprites/mic-off-5_hover.png differ diff --git a/src/assets/images/sprites/mic-off-6.png b/src/assets/images/sprites/mic-off-6.png new file mode 100644 index 0000000000..d986ef00fc Binary files /dev/null and b/src/assets/images/sprites/mic-off-6.png differ diff --git a/src/assets/images/sprites/mic-off-6_hover.png b/src/assets/images/sprites/mic-off-6_hover.png new file mode 100644 index 0000000000..b7046f223c Binary files /dev/null and b/src/assets/images/sprites/mic-off-6_hover.png differ diff --git a/src/assets/images/sprites/mic-off-7.png b/src/assets/images/sprites/mic-off-7.png new file mode 100644 index 0000000000..d9d2c7822b Binary files /dev/null and b/src/assets/images/sprites/mic-off-7.png differ diff --git a/src/assets/images/sprites/mic-off-7_hover.png b/src/assets/images/sprites/mic-off-7_hover.png new file mode 100644 index 0000000000..be55cb769a Binary files /dev/null and b/src/assets/images/sprites/mic-off-7_hover.png differ diff --git a/src/assets/images/sprites/mute-action.png b/src/assets/images/sprites/mute-action.png index 0af9609fef..6c1a62f31d 100644 Binary files a/src/assets/images/sprites/mute-action.png and b/src/assets/images/sprites/mute-action.png differ diff --git a/src/assets/images/sprites/mute_off-hover.png b/src/assets/images/sprites/mute_off-hover.png index 22b7c131b2..7d221aebbc 100644 Binary files a/src/assets/images/sprites/mute_off-hover.png and b/src/assets/images/sprites/mute_off-hover.png differ diff --git a/src/assets/images/sprites/mute_off.png b/src/assets/images/sprites/mute_off.png index 829d904e34..72e545da04 100644 Binary files a/src/assets/images/sprites/mute_off.png and b/src/assets/images/sprites/mute_off.png differ diff --git a/src/assets/images/sprites/mute_on-hover.png b/src/assets/images/sprites/mute_on-hover.png index 5f9e8baecb..f77f327573 100644 Binary files a/src/assets/images/sprites/mute_on-hover.png and b/src/assets/images/sprites/mute_on-hover.png differ diff --git a/src/assets/images/sprites/mute_on.png b/src/assets/images/sprites/mute_on.png index 166214aacb..f33da7cde8 100644 Binary files a/src/assets/images/sprites/mute_on.png and b/src/assets/images/sprites/mute_on.png differ diff --git a/src/assets/images/sprites/unmute-action.png b/src/assets/images/sprites/unmute-action.png index 624bdf8f12..f2adb3cc59 100644 Binary files a/src/assets/images/sprites/unmute-action.png and b/src/assets/images/sprites/unmute-action.png differ diff --git a/src/assets/images/spritesheets/css-spritesheet.css b/src/assets/images/spritesheets/css-spritesheet.css new file mode 100644 index 0000000000..e8c3ceec65 --- /dev/null +++ b/src/assets/images/spritesheets/css-spritesheet.css @@ -0,0 +1,320 @@ +:local(.mic-0) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -1.25px; + background-size: 255px 255px; +} +:local(.mic-0:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -1.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -1.25px; + background-size: 255px 255px; + } +} +:local(.mic-1) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -43.75px; + background-size: 255px 255px; +} +:local(.mic-1:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -43.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -43.75px; + background-size: 255px 255px; + } +} +:local(.mic-2) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -43.75px; + background-size: 255px 255px; +} +:local(.mic-2:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -1.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -43.75px; + background-size: 255px 255px; + } +} +:local(.mic-3) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -86.25px; + background-size: 255px 255px; +} +:local(.mic-3:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -86.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -86.25px; + background-size: 255px 255px; + } +} +:local(.mic-4) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -1.25px; + background-size: 255px 255px; +} +:local(.mic-4:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -86.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -1.25px; + background-size: 255px 255px; + } +} +:local(.mic-5) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -86.25px; + background-size: 255px 255px; +} +:local(.mic-5:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -43.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -86.25px; + background-size: 255px 255px; + } +} +:local(.mic-6) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -128.75px; + background-size: 255px 255px; +} +:local(.mic-6:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -128.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -128.75px; + background-size: 255px 255px; + } +} +:local(.mic-7) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -128.75px; + background-size: 255px 255px; +} +:local(.mic-7:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -128.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -128.75px; + background-size: 255px 255px; + } +} +:local(.mic-off-0) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -43.75px; + background-size: 255px 255px; +} +:local(.mic-off-0:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -1.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -43.75px; + background-size: 255px 255px; + } +} +:local(.mic-off-1) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -128.75px; + background-size: 255px 255px; +} +:local(.mic-off-1:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -86.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -128.75px; + background-size: 255px 255px; + } +} +:local(.mic-off-2) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -171.25px; + background-size: 255px 255px; +} +:local(.mic-off-2:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -171.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -171.25px; + background-size: 255px 255px; + } +} +:local(.mic-off-3) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -171.25px; + background-size: 255px 255px; +} +:local(.mic-off-3:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -86.25px -171.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -128.75px -171.25px; + background-size: 255px 255px; + } +} +:local(.mic-off-4) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -1.25px; + background-size: 255px 255px; +} +:local(.mic-off-4:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -171.25px -171.25px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -1.25px; + background-size: 255px 255px; + } +} +:local(.mic-off-5) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -86.25px; + background-size: 255px 255px; +} +:local(.mic-off-5:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -43.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -86.25px; + background-size: 255px 255px; + } +} +:local(.mic-off-6) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -171.25px; + background-size: 255px 255px; +} +:local(.mic-off-6:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -128.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -213.75px -171.25px; + background-size: 255px 255px; + } +} +:local(.mic-off-7) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -213.75px; + background-size: 255px 255px; +} +:local(.mic-off-7:hover){ + @media (pointer: fine) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -1.25px -213.75px; + background-size: 255px 255px; + } + @media (pointer: coarse) { + width: 40px; + height: 40px; + background: url("css-spritesheet.png") -43.75px -213.75px; + background-size: 255px 255px; + } +} diff --git a/src/assets/images/spritesheets/css-spritesheet.png b/src/assets/images/spritesheets/css-spritesheet.png new file mode 100644 index 0000000000..fb48965003 Binary files /dev/null and b/src/assets/images/spritesheets/css-spritesheet.png differ diff --git a/src/assets/images/spritesheets/sprite-system-spritesheet.json b/src/assets/images/spritesheets/sprite-system-spritesheet.json index 66c5c135be..28a3b3852a 100644 --- a/src/assets/images/spritesheets/sprite-system-spritesheet.json +++ b/src/assets/images/spritesheets/sprite-system-spritesheet.json @@ -1,27 +1,27 @@ { "meta": { "image": "sprite-system-spritesheet.png", - "size": {"w":1024,"h":1024}, + "size": {"w":2048,"h":2048}, "scale": "1" }, "frames": { - "freeze_on.png": + "create_object-hover.png": { - "frame": {"x":156,"y":8,"w":132,"h":132}, + "frame": {"x":8,"y":8,"w":132,"h":132}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":132,"h":132}, "sourceSize": {"w":132,"h":132} }, - "create_object-hover.png": + "create_object.png": { - "frame": {"x":8,"y":8,"w":132,"h":132}, + "frame": {"x":156,"y":8,"w":132,"h":132}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":132,"h":132}, "sourceSize": {"w":132,"h":132} }, - "freeze_on-hover.png": + "freeze_off-hover.png": { "frame": {"x":8,"y":156,"w":132,"h":132}, "rotated": false, @@ -37,7 +37,7 @@ "spriteSourceSize": {"x":0,"y":0,"w":132,"h":132}, "sourceSize": {"w":132,"h":132} }, - "freeze_off-hover.png": + "freeze_on-hover.png": { "frame": {"x":304,"y":8,"w":132,"h":132}, "rotated": false, @@ -45,7 +45,7 @@ "spriteSourceSize": {"x":0,"y":0,"w":132,"h":132}, "sourceSize": {"w":132,"h":132} }, - "create_object.png": + "freeze_on.png": { "frame": {"x":304,"y":156,"w":132,"h":132}, "rotated": false, @@ -53,9 +53,129 @@ "spriteSourceSize": {"x":0,"y":0,"w":132,"h":132}, "sourceSize": {"w":132,"h":132} }, - "spawn-disabled.png": + "mic-0.png": { - "frame": {"x":8,"y":304,"w":128,"h":128}, + "frame": {"x":152,"y":304,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-1.png": + { + "frame": {"x":452,"y":8,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-2.png": + { + "frame": {"x":452,"y":296,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-3.png": + { + "frame": {"x":152,"y":448,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-4.png": + { + "frame": {"x":440,"y":448,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-5.png": + { + "frame": {"x":596,"y":152,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-6.png": + { + "frame": {"x":596,"y":440,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-7.png": + { + "frame": {"x":152,"y":592,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-0.png": + { + "frame": {"x":440,"y":592,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-1.png": + { + "frame": {"x":740,"y":8,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-2.png": + { + "frame": {"x":740,"y":296,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-3.png": + { + "frame": {"x":740,"y":584,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-4.png": + { + "frame": {"x":152,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-5.png": + { + "frame": {"x":440,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-6.png": + { + "frame": {"x":728,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-7.png": + { + "frame": {"x":884,"y":152,"w":128,"h":128}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, @@ -63,7 +183,7 @@ }, "mod-badge.png": { - "frame": {"x":152,"y":304,"w":128,"h":128}, + "frame": {"x":884,"y":296,"w":128,"h":128}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, @@ -71,15 +191,15 @@ }, "recording-badge.png": { - "frame": {"x":296,"y":304,"w":128,"h":128}, + "frame": {"x":884,"y":440,"w":128,"h":128}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, "sourceSize": {"w":128,"h":128} }, - "spawn.png": + "spawn-disabled.png": { - "frame": {"x":452,"y":8,"w":128,"h":128}, + "frame": {"x":884,"y":584,"w":128,"h":128}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, @@ -87,7 +207,15 @@ }, "spawn-hover.png": { - "frame": {"x":452,"y":152,"w":128,"h":128}, + "frame": {"x":884,"y":728,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "spawn.png": + { + "frame": {"x":8,"y":880,"w":128,"h":128}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, @@ -95,7 +223,7 @@ }, "Background.png": { - "frame": {"x":452,"y":296,"w":128,"h":48}, + "frame": {"x":152,"y":880,"w":128,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":128,"h":48}, @@ -103,95 +231,103 @@ }, "Oval Copy.png": { - "frame": {"x":8,"y":448,"w":124,"h":124}, + "frame": {"x":1028,"y":8,"w":124,"h":124}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":124,"h":124}, "sourceSize": {"w":124,"h":124} }, - "share_camera_off.png": + "camera_off-disabled.png": { - "frame": {"x":452,"y":360,"w":68,"h":68}, + "frame": {"x":1028,"y":148,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "mute_off.png": + "camera_off-hover.png": { - "frame": {"x":148,"y":448,"w":68,"h":68}, + "frame": {"x":1028,"y":232,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "mute_on-hover.png": + "camera_off.png": { - "frame": {"x":232,"y":448,"w":68,"h":68}, + "frame": {"x":1028,"y":316,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "mute_on.png": + "camera_on-hover.png": { - "frame": {"x":316,"y":448,"w":68,"h":68}, + "frame": {"x":1028,"y":400,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "pen_off-disabled.png": + "camera_on.png": { - "frame": {"x":400,"y":448,"w":68,"h":68}, + "frame": {"x":1028,"y":484,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "pen_off-hover.png": + "mute_off-hover.png": { - "frame": {"x":484,"y":448,"w":68,"h":68}, + "frame": {"x":1028,"y":568,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "camera_off-disabled.png": + "mute_off.png": { - "frame": {"x":596,"y":8,"w":68,"h":68}, + "frame": {"x":1028,"y":652,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "pen_on-hover.png": + "pen_off-disabled.png": { - "frame": {"x":596,"y":92,"w":68,"h":68}, + "frame": {"x":1028,"y":736,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "pen_on.png": + "pen_off-hover.png": { - "frame": {"x":596,"y":176,"w":68,"h":68}, + "frame": {"x":1028,"y":820,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "camera_on.png": + "pen_off.png": { - "frame": {"x":596,"y":260,"w":68,"h":68}, + "frame": {"x":1028,"y":904,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "camera_on-hover.png": + "pen_on-hover.png": + { + "frame": {"x":8,"y":1024,"w":68,"h":68}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, + "sourceSize": {"w":68,"h":68} + }, + "pen_on.png": { - "frame": {"x":596,"y":344,"w":68,"h":68}, + "frame": {"x":92,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -199,15 +335,15 @@ }, "share_camera_off-hover.png": { - "frame": {"x":596,"y":428,"w":68,"h":68}, + "frame": {"x":176,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "mute_off-hover.png": + "share_camera_off.png": { - "frame": {"x":8,"y":588,"w":68,"h":68}, + "frame": {"x":260,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -215,7 +351,7 @@ }, "share_camera_on-hover.png": { - "frame": {"x":92,"y":588,"w":68,"h":68}, + "frame": {"x":344,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -223,7 +359,7 @@ }, "share_camera_on.png": { - "frame": {"x":176,"y":588,"w":68,"h":68}, + "frame": {"x":428,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -231,7 +367,7 @@ }, "share_screen_off.png": { - "frame": {"x":260,"y":588,"w":68,"h":68}, + "frame": {"x":512,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -239,7 +375,7 @@ }, "share_screen_on-hover.png": { - "frame": {"x":344,"y":588,"w":68,"h":68}, + "frame": {"x":596,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -247,7 +383,7 @@ }, "share_screen_on.png": { - "frame": {"x":428,"y":588,"w":68,"h":68}, + "frame": {"x":680,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -255,7 +391,7 @@ }, "share_window_off-hover.png": { - "frame": {"x":512,"y":588,"w":68,"h":68}, + "frame": {"x":764,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -263,7 +399,7 @@ }, "share_window_off.png": { - "frame": {"x":596,"y":588,"w":68,"h":68}, + "frame": {"x":848,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -271,7 +407,7 @@ }, "share_window_on-hover.png": { - "frame": {"x":680,"y":8,"w":68,"h":68}, + "frame": {"x":932,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, @@ -279,191 +415,191 @@ }, "share_window_on.png": { - "frame": {"x":680,"y":92,"w":68,"h":68}, + "frame": {"x":1016,"y":1024,"w":68,"h":68}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, "sourceSize": {"w":68,"h":68} }, - "camera_off.png": + "mute_on-hover.png": { - "frame": {"x":680,"y":176,"w":68,"h":68}, + "frame": {"x":152,"y":944,"w":66,"h":64}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, - "sourceSize": {"w":68,"h":68} + "spriteSourceSize": {"x":0,"y":0,"w":66,"h":64}, + "sourceSize": {"w":66,"h":64} }, - "volume_up.png": + "camera-action.png": { - "frame": {"x":484,"y":532,"w":32,"h":32}, + "frame": {"x":234,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, - "sourceSize": {"w":32,"h":32} + "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, + "sourceSize": {"w":64,"h":64} }, - "pen_off.png": + "close-action.png": { - "frame": {"x":680,"y":344,"w":68,"h":68}, + "frame": {"x":314,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, - "sourceSize": {"w":68,"h":68} + "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, + "sourceSize": {"w":64,"h":64} }, - "next.png": + "close-white.png": { - "frame": {"x":680,"y":428,"w":64,"h":64}, + "frame": {"x":394,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "remove-action.png": + "drop-action.png": { - "frame": {"x":680,"y":508,"w":64,"h":64}, + "frame": {"x":474,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "rotate-action.png": + "mute_on.png": { - "frame": {"x":680,"y":588,"w":64,"h":64}, + "frame": {"x":554,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "rotate-cursor.png": + "next.png": { - "frame": {"x":8,"y":672,"w":64,"h":64}, + "frame": {"x":634,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "scale-action.png": + "pause-hover.png": { - "frame": {"x":88,"y":672,"w":64,"h":64}, + "frame": {"x":714,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "unmute-action.png": + "pause.png": { - "frame": {"x":168,"y":672,"w":64,"h":64}, + "frame": {"x":794,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "stop-action.png": + "pin-action.png": { - "frame": {"x":248,"y":672,"w":64,"h":64}, + "frame": {"x":874,"y":944,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "spawn_message_dark.png": + "play-hover.png": { - "frame": {"x":328,"y":672,"w":64,"h":64}, + "frame": {"x":1168,"y":8,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "spawn_message_dark-hover.png": + "play.png": { - "frame": {"x":408,"y":672,"w":64,"h":64}, + "frame": {"x":1168,"y":88,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "pause-hover.png": + "prev.png": { - "frame": {"x":488,"y":672,"w":64,"h":64}, + "frame": {"x":1168,"y":168,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "pause.png": + "recenter-action.png": { - "frame": {"x":568,"y":672,"w":64,"h":64}, + "frame": {"x":1168,"y":248,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "drop-action.png": + "record-action-alpha.png": { - "frame": {"x":648,"y":672,"w":64,"h":64}, + "frame": {"x":1168,"y":328,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "mute-action.png": + "record-action.png": { - "frame": {"x":764,"y":8,"w":64,"h":64}, + "frame": {"x":1168,"y":408,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "close-action.png": + "remove-action.png": { - "frame": {"x":764,"y":88,"w":64,"h":64}, + "frame": {"x":1168,"y":488,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "close-white.png": + "rotate-action.png": { - "frame": {"x":764,"y":168,"w":64,"h":64}, + "frame": {"x":1168,"y":568,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "camera-action.png": + "rotate-cursor.png": { - "frame": {"x":764,"y":248,"w":64,"h":64}, + "frame": {"x":1168,"y":648,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "pin-action.png": + "scale-action.png": { - "frame": {"x":764,"y":328,"w":64,"h":64}, + "frame": {"x":1168,"y":728,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "play-hover.png": + "snap_camera.png": { - "frame": {"x":764,"y":408,"w":64,"h":64}, + "frame": {"x":1168,"y":808,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "play.png": + "spawn_message_dark-hover.png": { - "frame": {"x":764,"y":488,"w":64,"h":64}, + "frame": {"x":1168,"y":888,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "prev.png": + "spawn_message_dark.png": { - "frame": {"x":764,"y":568,"w":64,"h":64}, + "frame": {"x":1168,"y":968,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, @@ -471,55 +607,55 @@ }, "spawn_message.png": { - "frame": {"x":764,"y":648,"w":64,"h":64}, + "frame": {"x":8,"y":1108,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "recenter-action.png": + "stop-action.png": { - "frame": {"x":8,"y":752,"w":64,"h":64}, + "frame": {"x":88,"y":1108,"w":64,"h":64}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, "sourceSize": {"w":64,"h":64} }, - "snap_camera.png": + "unmute-action.png": { - "frame": {"x":88,"y":752,"w":64,"h":64}, + "frame": {"x":296,"y":880,"w":48,"h":48}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, - "sourceSize": {"w":64,"h":64} + "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, + "sourceSize": {"w":48,"h":48} }, - "record-action-alpha.png": + "mute-action.png": { - "frame": {"x":168,"y":752,"w":64,"h":64}, + "frame": {"x":1112,"y":148,"w":26,"h":46}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, - "sourceSize": {"w":64,"h":64} + "spriteSourceSize": {"x":0,"y":0,"w":26,"h":46}, + "sourceSize": {"w":26,"h":46} }, - "record-action.png": + "seek_back-hover.png": { - "frame": {"x":248,"y":752,"w":64,"h":64}, + "frame": {"x":1168,"y":1048,"w":32,"h":32}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":64,"h":64}, - "sourceSize": {"w":64,"h":64} + "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, + "sourceSize": {"w":32,"h":32} }, - "snap.png": + "seek_back.png": { - "frame": {"x":596,"y":512,"w":32,"h":32}, + "frame": {"x":1112,"y":232,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "snap-hover.png": + "seek_fwd-hover.png": { - "frame": {"x":536,"y":360,"w":32,"h":32}, + "frame": {"x":1112,"y":316,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, @@ -527,67 +663,187 @@ }, "seek_fwd.png": { - "frame": {"x":148,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":400,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "seek_fwd-hover.png": + "snap-hover.png": { - "frame": {"x":196,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":484,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "seek_back.png": + "snap.png": { - "frame": {"x":244,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":568,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "seek_back-hover.png": + "volume_down-hover.png": { - "frame": {"x":292,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":652,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "volume_down-hover.png": + "volume_down.png": { - "frame": {"x":340,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":736,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "volume_down.png": + "volume_up-hover.png": { - "frame": {"x":388,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":820,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "volume_up-hover.png": + "volume_up.png": { - "frame": {"x":436,"y":532,"w":32,"h":32}, + "frame": {"x":1112,"y":904,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, "sourceSize": {"w":32,"h":32} }, - "camera_off-hover.png": + "mic-0_hover.png": { - "frame": {"x":680,"y":260,"w":68,"h":68}, + "frame": {"x":8,"y":304,"w":128,"h":128}, "rotated": false, "trimmed": false, - "spriteSourceSize": {"x":0,"y":0,"w":68,"h":68}, - "sourceSize": {"w":68,"h":68} + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-1_hover.png": + { + "frame": {"x":296,"y":304,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-2_hover.png": + { + "frame": {"x":452,"y":152,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-3_hover.png": + { + "frame": {"x":8,"y":448,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-4_hover.png": + { + "frame": {"x":296,"y":448,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-5_hover.png": + { + "frame": {"x":596,"y":8,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-6_hover.png": + { + "frame": {"x":596,"y":296,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-7_hover.png": + { + "frame": {"x":8,"y":592,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-0_hover.png": + { + "frame": {"x":296,"y":592,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-1_hover.png": + { + "frame": {"x":584,"y":592,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-2_hover.png": + { + "frame": {"x":740,"y":152,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-3_hover.png": + { + "frame": {"x":740,"y":440,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-4_hover.png": + { + "frame": {"x":8,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-5_hover.png": + { + "frame": {"x":296,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-6_hover.png": + { + "frame": {"x":584,"y":736,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} + }, + "mic-off-7_hover.png": + { + "frame": {"x":884,"y":8,"w":128,"h":128}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128}, + "sourceSize": {"w":128,"h":128} } } } \ No newline at end of file diff --git a/src/assets/images/spritesheets/sprite-system-spritesheet.png b/src/assets/images/spritesheets/sprite-system-spritesheet.png index 73b4b821e0..3fbdc9d632 100644 Binary files a/src/assets/images/spritesheets/sprite-system-spritesheet.png and b/src/assets/images/spritesheets/sprite-system-spritesheet.png differ diff --git a/src/assets/stylesheets/2d-hud.scss b/src/assets/stylesheets/2d-hud.scss index f982a9c670..817202a16a 100644 --- a/src/assets/stylesheets/2d-hud.scss +++ b/src/assets/stylesheets/2d-hud.scss @@ -209,32 +209,6 @@ position: relative; } -// This roundabout pattern is the only way I can get hovers to not happen on touch devices -:local(.iconButton.mute) { - background-image: url(../hud/mute_off.png); -} -:local(.iconButton.mute:hover) { - @media (pointer: fine) { - background-image: url(../hud/mute_off-hover.png); - } - - @media (pointer: coarse) { - background-image: url(../hud/mute_off.png); - } -} - -:local(.iconButton.mute.active) { - background-image: url(../hud/mute_on.png); -} -:local(.iconButton.mute.active:hover) { - @media (pointer: fine) { - background-image: url(../hud/mute_on-hover.png); - } - - @media (pointer: coarse) { - background-image: url(../hud/mute_on.png); - } -} :local(.iconButton.pen) { background-image: url(../hud/pen_off.png); diff --git a/src/components/audio-feedback.js b/src/components/audio-feedback.js index 26b85d67d4..08a27ada8e 100644 --- a/src/components/audio-feedback.js +++ b/src/components/audio-feedback.js @@ -6,17 +6,16 @@ const DISABLE_AT_VOLUME_THRESHOLD = 0.00001; const DISABLE_GRACE_PERIOD_MS = 10000; const MIN_VOLUME_THRESHOLD = 0.01; -const getVolume = (levels, smoothing, prevVolume) => { +const calculateVolume = (analyser, levels) => { + // take care with compatibility, e.g. safari doesn't support getFloatTimeDomainData + analyser.getByteTimeDomainData(levels); let sum = 0; for (let i = 0; i < levels.length; i++) { const amplitude = (levels[i] - 128) / 128; sum += amplitude * amplitude; } - let currVolume = Math.sqrt(sum / levels.length); - if (currVolume < MIN_VOLUME_THRESHOLD) { - currVolume = 0; - } - return smoothing * currVolume + (1 - smoothing) * prevVolume; + const currVolume = Math.sqrt(sum / levels.length); + return currVolume < MIN_VOLUME_THRESHOLD ? 0 : currVolume; }; const tempScaleFromPosition = new THREE.Vector3(); @@ -38,7 +37,6 @@ AFRAME.registerComponent("networked-audio-analyser", { async init() { this.volume = 0; this.prevVolume = 0; - this.smoothing = 0.3; this._updateAnalysis = this._updateAnalysis.bind(this); this._runScheduledWork = this._runScheduledWork.bind(this); this.el.sceneEl.systems["frame-scheduler"].schedule(this._updateAnalysis, "audio-analyser"); @@ -74,9 +72,9 @@ AFRAME.registerComponent("networked-audio-analyser", { _updateAnalysis: function(t) { if (!this.analyser) return; - // take care with compatibility, e.g. safari doesn't support getFloatTimeDomainData - this.analyser.getByteTimeDomainData(this.levels); - this.volume = getVolume(this.levels, this.smoothing, this.prevVolume); + const currentVolume = calculateVolume(this.analyser, this.levels); + const s = 0.3; + this.volume = s * currentVolume + (1 - s) * this.prevVolume; this.prevVolume = this.volume; if (this.volume < DISABLE_AT_VOLUME_THRESHOLD) { @@ -93,43 +91,39 @@ AFRAME.registerComponent("networked-audio-analyser", { } }); +function connectAnalyser(mediaStream) { + const ctx = THREE.AudioContext.getContext(); + const source = ctx.createMediaStreamSource(mediaStream); + const analyser = ctx.createAnalyser(); + analyser.fftSize = 32; + const levels = new Uint8Array(analyser.frequencyBinCount); + source.connect(analyser); + return { analyser, levels }; +} + /** - * Performs local audio analysis, currently used to scale head when using video recording from camera. + * Calculates volume of the local audio stream. */ AFRAME.registerSystem("local-audio-analyser", { - schema: { - analyze: { default: false } - }, - - async init() { + init() { this.volume = 0; - this.prevVolume = 0; - this.smoothing = 0.3; - }, - - async update() { - if (!this.data.analyze) { - this.stream = this.analyser = null; - } else if (!this.stream) { - this.stream = await NAF.connection.adapter.getMediaStream(NAF.clientId, "audio"); - if (!this.stream || this.stream.getAudioTracks().length === 0) return; - const ctx = THREE.AudioContext.getContext(); - const source = ctx.createMediaStreamSource(this.stream); - this.analyser = ctx.createAnalyser(); - this.analyser.fftSize = 32; - this.levels = new Uint8Array(this.analyser.frequencyBinCount); - source.connect(this.analyser); - } + this.el.addEventListener("local-media-stream-created", e => { + const mediaStream = e.detail.mediaStream; + if (this.stream) { + console.warn("media stream changed", this.stream, mediaStream); + // TODO: cleanup? + } + this.stream = mediaStream; + const { analyser, levels } = connectAnalyser(mediaStream); + this.analyser = analyser; + this.levels = levels; + }); }, tick: function() { - if (!this.analyser || !this.data.analyze || !this.stream) return; - - // take care with compatibility, e.g. safari doesn't support getFloatTimeDomainData - this.analyser.getByteTimeDomainData(this.levels); - this.volume = getVolume(this.levels, this.smoothing, this.prevVolume); - this.prevVolume = this.volume; + if (!this.analyser) return; + this.volume = calculateVolume(this.analyser, this.levels); } }); @@ -167,3 +161,128 @@ AFRAME.registerComponent("scale-audio-feedback", { object3D.matrixNeedsUpdate = true; } }); + +const SPRITE_NAMES = { + MIC: ["mic-0.png", "mic-1.png", "mic-2.png", "mic-3.png", "mic-4.png", "mic-5.png", "mic-6.png", "mic-7.png"], + MIC_HOVER: [ + "mic-0_hover.png", + "mic-1_hover.png", + "mic-2_hover.png", + "mic-3_hover.png", + "mic-4_hover.png", + "mic-5_hover.png", + "mic-6_hover.png", + "mic-7_hover.png" + ], + MIC_OFF: [ + "mic-off-0.png", + "mic-off-1.png", + "mic-off-2.png", + "mic-off-3.png", + "mic-off-4.png", + "mic-off-5.png", + "mic-off-6.png", + "mic-off-7.png" + ], + MIC_OFF_HOVER: [ + "mic-off-0_hover.png", + "mic-off-1_hover.png", + "mic-off-2_hover.png", + "mic-off-3_hover.png", + "mic-off-4_hover.png", + "mic-off-5_hover.png", + "mic-off-6_hover.png", + "mic-off-7_hover.png" + ] +}; + +export function micLevelForVolume(volume, max) { + return max === 0 + ? 0 + : volume < max * 0.02 + ? 0 + : volume < max * 0.03 + ? 1 + : volume < max * 0.06 + ? 2 + : volume < max * 0.08 + ? 3 + : volume < max * 0.16 + ? 4 + : volume < max * 0.32 + ? 5 + : volume < max * 0.5 + ? 6 + : 7; +} + +AFRAME.registerComponent("mic-button", { + schema: { + active: { type: "boolean" }, + tooltip: { type: "selector" }, + tooltipText: { type: "string" }, + activeTooltipText: { type: "string" } + }, + + init() { + this.loudest = 0; + this.prevSpriteName = ""; + this.decayingVolume = 0; + this.el.object3D.matrixNeedsUpdate = true; + this.hovering = false; + this.onHover = () => { + this.hovering = true; + this.data.tooltip.setAttribute("visible", true); + }; + this.onHoverOut = () => { + this.hovering = false; + this.data.tooltip.setAttribute("visible", false); + }; + }, + + play() { + this.el.object3D.addEventListener("hovered", this.onHover); + this.el.object3D.addEventListener("unhovered", this.onHoverOut); + }, + + pause() { + this.el.object3D.removeEventListener("hovered", this.onHover); + this.el.object3D.removeEventListener("unhovered", this.onHoverOut); + }, + + update() { + if (this.data.tooltip) { + this.textEl = this.data.tooltip.querySelector("[text]"); + } + }, + + tick() { + const audioAnalyser = this.el.sceneEl.systems["local-audio-analyser"]; + let volume; + if (audioAnalyser.volume > this.decayingVolume) { + this.decayingVolume = audioAnalyser.volume; + volume = audioAnalyser.volume; + this.loudest = Math.max(this.loudest, volume); + } else { + const s = 0.8; + volume = this.decayingVolume * s > 0.001 ? this.decayingVolume * s : 0; + this.decayingVolume = volume; + } + + const active = this.data.active; + const hovering = this.hovering; + const spriteNames = + SPRITE_NAMES[!active ? (hovering ? "MIC_HOVER" : "MIC") : hovering ? "MIC_OFF_HOVER" : "MIC_OFF"]; + const level = micLevelForVolume(volume, this.loudest); + const spriteName = spriteNames[level]; + if (spriteName !== this.prevSpriteName) { + this.prevSpriteName = spriteName; + this.el.setAttribute("sprite", "name", spriteName); + } + + if (this.data.tooltip && hovering) { + this.textEl = this.textEl || this.data.tooltip.querySelector("[text]"); + this.textEl.setAttribute("text", "value", active ? this.data.activeTooltipText : this.data.tooltipText); + } + } +}); diff --git a/src/components/camera-tool.js b/src/components/camera-tool.js index 74066c5b00..ed3b48d160 100644 --- a/src/components/camera-tool.js +++ b/src/components/camera-tool.js @@ -320,9 +320,6 @@ AFRAME.registerComponent("camera-tool", { this.videoImageData.data.set(this.videoPixels); } - // Begin sampling local audio so we can perform head scaling - this.el.sceneEl.setAttribute("local-audio-analyser", { analyze: true }); - const stream = new MediaStream(); const track = this.videoCanvas.captureStream(VIDEO_FPS).getVideoTracks()[0]; @@ -438,7 +435,6 @@ AFRAME.registerComponent("camera-tool", { this.videoCountdownInterval = null; this.el.setAttribute("camera-tool", "label", ""); this.el.setAttribute("camera-tool", { isRecording: false, isSnapping: false }); - this.el.sceneEl.setAttribute("local-audio-analyser", { analyze: false }); }, tick() { @@ -539,9 +535,12 @@ AFRAME.registerComponent("camera-tool", { // We want to scale our own head in between frames now that we're taking a video/photo. let scale = 1; + // TODO: The local-audio-analyser has the non-networked media stream, which is active + // even while the user is muted. This should be looking at a different analyser that + // has the networked media stream instead. const analyser = this.el.sceneEl.systems["local-audio-analyser"]; - if (analyser && analyser.data.analyze && this.playerHead.el.components["scale-audio-feedback"]) { + if (analyser && this.playerHead.el.components["scale-audio-feedback"]) { scale = getAudioFeedbackScale(this.el.object3D, this.playerHead, 1, 2, analyser.volume); } diff --git a/src/components/icon-button.js b/src/components/icon-button.js index 38fb9299a2..dc76e270b0 100644 --- a/src/components/icon-button.js +++ b/src/components/icon-button.js @@ -9,6 +9,7 @@ AFRAME.registerComponent("icon-button", { hoverImage: { type: "string" }, activeImage: { type: "string" }, activeHoverImage: { type: "string" }, + disabledImage: { type: "string" }, active: { type: "boolean" }, disabled: { type: "boolean" }, tooltip: { type: "selector" }, @@ -20,10 +21,16 @@ AFRAME.registerComponent("icon-button", { this.el.object3D.matrixNeedsUpdate = true; this.onHover = () => { this.hovering = true; + if (this.data.tooltip) { + this.data.tooltip.object3D.visible = true; + } this.updateButtonState(); }; this.onHoverOut = () => { this.hovering = false; + if (this.data.tooltip) { + this.data.tooltip.object3D.visible = false; + } this.updateButtonState(); }; }, @@ -70,7 +77,6 @@ AFRAME.registerComponent("icon-button", { if (this.data.tooltip && hovering) { const tooltipText = (this.data.active ? this.data.activeTooltipText : this.data.tooltipText) + (disabled ? " Disabled" : ""); - this.data.tooltip.object3D.visible = this.hovering; this.data.tooltip.querySelector("[text]").setAttribute("text", "value", tooltipText); } } diff --git a/src/components/in-world-hud.js b/src/components/in-world-hud.js index d78ca973dd..03a27ec86a 100644 --- a/src/components/in-world-hud.js +++ b/src/components/in-world-hud.js @@ -14,7 +14,7 @@ AFRAME.registerComponent("in-world-hud", { this.background = this.el.querySelector(".bg"); this.updateButtonStates = () => { - this.mic.setAttribute("icon-button", "active", this.el.sceneEl.is("muted")); + this.mic.setAttribute("mic-button", "active", this.el.sceneEl.is("muted")); this.pen.setAttribute("icon-button", "active", this.el.sceneEl.is("pen")); this.cameraBtn.setAttribute("icon-button", "active", this.el.sceneEl.is("camera")); if (window.APP.hubChannel) { diff --git a/src/hub.html b/src/hub.html index f70ab6bc42..75d6dfab77 100644 --- a/src/hub.html +++ b/src/hub.html @@ -49,7 +49,7 @@ physics="debug: false; driver: ammo; debugDrawMode: 1; iterations: 4;" hubs-systems capture-system - local-audio-analyser="analyze: false" + local-audio-analyser class="grab-cursor" renderer="antialias: true; colorManagement: true; sortObjects: true; physicallyCorrectLights: true; alpha: false; webgl2: true; multiview: false;" shadow="type: pcfsoft" @@ -594,7 +594,7 @@ tags="singleActionButton: true; isHoverMenuChild: true;" sprite icon-button="image: snap.png; hoverImage: snap-hover.png; activeImage: snap.png; activeHoverImage: snap-hover.png" - visibility-on-content-type="contentType: video/mp4; contentSubtype: video-camera; visible: false;" + visibility-on-content-type="contentType: video/mp4; contentSubtype: video-camera; visible: false;" scale="0.075 0.075 0.075" position="0 0.225 0" class="video-snap-button" @@ -862,14 +862,7 @@ is-remote-hover-target tags="singleActionButton: true" sprite - icon-button=" - tooltip: #hud-tooltip; - tooltipText: Mute Mic; - activeTooltipText: Unmute Mic; - image: mute_off.png; - hoverImage: mute_off-hover.png; - activeImage: mute_on.png; - activeHoverImage: mute_on-hover.png;" + mic-button="tooltip: #hud-tooltip; tooltipText: Mute Mic; activeTooltipText: Unmute Mic;" scale="0.1 0.1 0.1" position="-0.17 0 0.001" class="hud mic" diff --git a/src/react-components/2d-hud.js b/src/react-components/2d-hud.js index 62039429b7..25b299a941 100644 --- a/src/react-components/2d-hud.js +++ b/src/react-components/2d-hud.js @@ -5,15 +5,40 @@ import cx from "classnames"; const { detect } = require("detect-browser"); import styles from "../assets/stylesheets/2d-hud.scss"; import uiStyles from "../assets/stylesheets/ui-root.scss"; +import spritesheet from "../assets/images/spritesheets/css-spritesheet.css"; import { FormattedMessage } from "react-intl"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faTimes } from "@fortawesome/free-solid-svg-icons/faTimes"; +import { micLevelForVolume } from "../components/audio-feedback"; +const SPRITESHEET_ICONS = { + MIC: [ + spritesheet.mic0, + spritesheet.mic1, + spritesheet.mic2, + spritesheet.mic3, + spritesheet.mic4, + spritesheet.mic5, + spritesheet.mic6, + spritesheet.mic7 + ], + MIC_OFF: [ + spritesheet.micOff0, + spritesheet.micOff1, + spritesheet.micOff2, + spritesheet.micOff3, + spritesheet.micOff4, + spritesheet.micOff5, + spritesheet.micOff6, + spritesheet.micOff7 + ] +}; const browser = detect(); const noop = () => {}; class TopHUD extends Component { static propTypes = { + scene: PropTypes.object, muted: PropTypes.bool, isCursorHoldingPen: PropTypes.bool, hasActiveCamera: PropTypes.bool, @@ -41,6 +66,7 @@ class TopHUD extends Component { state = { showVideoShareOptions: false, lastActiveMediaSource: null, + micLevel: 0, cameraDisabled: false, penDisabled: false, mediaDisabled: false @@ -53,14 +79,6 @@ class TopHUD extends Component { this.state.mediaDisabled = !window.APP.hubChannel.can("spawn_and_move_media"); } - componentDidMount() { - window.APP.hubChannel.addEventListener("permissions_updated", this.onPermissionsUpdated); - } - - componentWillUnMount() { - window.APP.hubChannel.removeEventListener("permissions_updated", this.onPermissionsUpdated); - } - onPermissionsUpdated = () => { this.setState({ cameraDisabled: !window.APP.hubChannel.can("spawn_camera"), @@ -69,6 +87,29 @@ class TopHUD extends Component { }); }; + componentDidMount = () => { + let max = 0; + if (this.micUpdateInterval) { + clearInterval(this.micUpdateInterval); + } + this.micUpdateInterval = setInterval(() => { + const volume = this.props.scene.systems["local-audio-analyser"].volume; + max = Math.max(volume, max); + const micLevel = micLevelForVolume(volume, max); + if (micLevel !== this.state.micLevel) { + this.setState({ micLevel }); + } + }, 50); + window.APP.hubChannel.addEventListener("permissions_updated", this.onPermissionsUpdated); + }; + + componentWillUnmount = () => { + if (this.micUpdateInterval) { + clearInterval(this.micUpdateInterval); + } + window.APP.hubChannel.removeEventListener("permissions_updated", this.onPermissionsUpdated); + }; + handleVideoShareClicked = source => { if ((source === "screen" || source === "window") && browser.name !== "firefox") { this.props.onShareVideoNotCapable(); @@ -204,6 +245,8 @@ class TopHUD extends Component { tip = tipDivForType(this.props.activeTip); } + const micLevel = this.state.micLevel; + const micIconClass = this.props.muted ? SPRITESHEET_ICONS.MIC_OFF[micLevel] : SPRITESHEET_ICONS.MIC[micLevel]; // Hide buttons when frozen. return (
@@ -214,7 +257,7 @@ class TopHUD extends Component { {tip} {videoSharingButtons}
diff --git a/src/react-components/mic-level-widget.js b/src/react-components/mic-level-widget.js index 307083b9b5..df9be7dedc 100644 --- a/src/react-components/mic-level-widget.js +++ b/src/react-components/mic-level-widget.js @@ -3,80 +3,55 @@ import PropTypes from "prop-types"; import { FormattedMessage } from "react-intl"; import MovingAverage from "moving-average"; -const AudioContext = window.AudioContext || window.webkitAudioContext; - export default class MicLevelWidget extends Component { static propTypes = { - mediaStream: PropTypes.object, hasAudioTrack: PropTypes.bool, - muteOnEntry: PropTypes.bool + muteOnEntry: PropTypes.bool, + scene: PropTypes.object }; state = { - micLevel: 0 + volume: 0 }; componentDidMount() { - if (this.props.mediaStream != null && this.props.hasAudioTrack) { - this.startAnalyzer(this.props.mediaStream); - } - } - - componentDidUpdate(prevProps) { - if (this.props.mediaStream !== prevProps.mediaStream || this.props.hasAudioTrack !== prevProps.hasAudioTrack) { - this.stopAnalyzer(); - if (this.props.mediaStream != null && this.props.hasAudioTrack) { - this.startAnalyzer(this.props.mediaStream); - } - } + this.startAnalyser(); } componentWillUnmount() { - this.stopAnalyzer(); + this.stopAnalyser(); } - stopAnalyzer() { + stopAnalyser() { if (this.micUpdateInterval != null) { clearInterval(this.micUpdateInterval); } - if (this.micLevelAudioContext != null) { - this.micLevelAudioContext.close(); - } } - startAnalyzer(mediaStream) { - this.micLevelAudioContext = new AudioContext(); - const micSource = this.micLevelAudioContext.createMediaStreamSource(mediaStream); - const analyser = this.micLevelAudioContext.createAnalyser(); - analyser.fftSize = 32; - const levels = new Uint8Array(analyser.frequencyBinCount); - micSource.connect(analyser); + startAnalyser() { + if (this.micUpdateInterval) { + clearInterval(this.micUpdateInterval); + } const micLevelMovingAverage = MovingAverage(100); + let max = 0; this.micUpdateInterval = setInterval(() => { - analyser.getByteTimeDomainData(levels); - let v = 0; - for (let x = 0; x < levels.length; x++) { - v = Math.max(levels[x] - 128, v); - } - const level = v / 128.0; - // Multiplier to increase visual indicator. - const multiplier = 6; + const analyser = this.props.scene.systems["local-audio-analyser"]; + max = Math.max(analyser.volume, max); // We use a moving average to smooth out the visual animation or else it would twitch too fast for // the css renderer to keep up. - micLevelMovingAverage.push(Date.now(), level * multiplier); + micLevelMovingAverage.push(Date.now(), analyser.volume); const average = micLevelMovingAverage.movingAverage(); - this.setState(state => { - if (Math.abs(average - state.micLevel) > 0.0001) { - return { micLevel: average }; - } - }); + const volume = max === 0 ? 0 : average / max; + if (Math.abs(this.state.volume - volume) > 0.05) { + this.setState({ volume }); + } }, 50); } render() { const maxLevelHeight = 111; const micClip = { - clip: `rect(${maxLevelHeight - Math.floor(this.state.micLevel * maxLevelHeight)}px, 111px, 111px, 0px)` + clip: `rect(${maxLevelHeight - Math.floor(this.state.volume * maxLevelHeight)}px, 111px, 111px, 0px)` }; return ( diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js index b5853c93fe..e1881a3dab 100644 --- a/src/react-components/ui-root.js +++ b/src/react-components/ui-root.js @@ -595,6 +595,9 @@ class UIRoot extends Component { if (micDeviceId) { this.props.store.update({ settings: { lastUsedMicDeviceId: micDeviceId } }); } + const mediaStreamForMicAnalysis = new MediaStream(); + mediaStreamForMicAnalysis.addTrack(this.state.audioTrack.clone()); + this.props.scene.emit("local-media-stream-created", { mediaStream: mediaStreamForMicAnalysis }); } this.setState({ mediaStream }); @@ -1167,9 +1170,9 @@ class UIRoot extends Component {
@@ -1830,6 +1833,7 @@ class UIRoot extends Component { {enteredOrWatching && (