diff --git a/applications/appreciate/README.md b/applications/appreciate/README.md
index b3f9a36..b98401d 100644
--- a/applications/appreciate/README.md
+++ b/applications/appreciate/README.md
@@ -6,6 +6,13 @@ Show someone else that you like what they're doing. Open the app to see usage in
## Releases
+### v1.6 (By Alezia Kurdis for Overte, August 12th, 2023)
+
+- Replace the Color Picker Component (sadly GPLv3) by a simple hue selector.
+- Add a Install button
+- Keep the icon active if the switch is on.
+- The appreciation dodecahedron is now emissive, and glows as the intensity grows.
+
### v1.5 | [48d8247](https://github.com/highfidelity/hifi-content/commit/48d8247)
- Fixed an issue where Appreciate app users wearing avatars without a specific joint wouldn't hear the Appreciate sound or see the Appreciation Dodecahedron
diff --git a/applications/appreciate/appreciate_app.js b/applications/appreciate/appreciate_app.js
index df2cd33..4f45bf1 100644
--- a/applications/appreciate/appreciate_app.js
+++ b/applications/appreciate/appreciate_app.js
@@ -8,20 +8,10 @@
"Appreciate" application.
Show someone else that you like what they're doing.
Open the app to see usage instructions and some options!
- (version 1.5.0)
+ (version 1.6.0)
- * This program ("Appreciate" application) is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ Distributed under the Apache License, Version 2.0
+ See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
*/
(function () {
@@ -71,30 +61,11 @@
return minOutput + (maxOutput - minOutput) *
(factor - minInput) / (maxInput - minInput);
}
-
-
- // Linearly scales an RGB color between 0 and 1 based on RGB color values
- // between 0 and 255.
- function linearScaleColor(intensity, min, max) {
- var output = {
- "red": 0,
- "green": 0,
- "blue": 0
- };
-
- output.red = linearScale(intensity, 0, 1, min.red, max.red);
- output.green = linearScale(intensity, 0, 1, min.green, max.green);
- output.blue = linearScale(intensity, 0, 1, min.blue, max.blue);
-
- return output;
- }
-
function randomFloat(min, max) {
return Math.random() * (max - min) + min;
}
-
// Updates the Current Intensity Meter UI element. Called when intensity changes.
function updateCurrentIntensityUI() {
ui.sendMessage({method: "updateCurrentIntensityUI", currentIntensity: currentIntensity});
@@ -117,6 +88,7 @@
if (intensityEntity) {
Entities.deleteEntity(intensityEntity);
intensityEntity = false;
+ intensityEntityMaterial = Uuid.NULL;
}
}
@@ -179,6 +151,7 @@
// current intensity of their appreciation.
// Many of these property values are empirically determined.
var intensityEntity = false;
+ var intensityEntityMaterial = Uuid.NULL;
var INTENSITY_ENTITY_MAX_DIMENSIONS = {
"x": 0.24,
"y": 0.24,
@@ -205,6 +178,7 @@
"blue": 5
};
var MIN_COLOR_MULTIPLIER = 0.4;
+ var MAX_GLOW = 3;
var intensityEntityColorMax = JSON.parse(Settings.getValue("appreciate/entityColor",
JSON.stringify(INTENSITY_ENTITY_COLOR_MAX_DEFAULT)));
var ANGVEL_ENTITY_MULTIPLY_FACTOR = 62;
@@ -225,35 +199,12 @@
},
"angularDamping": 0,
"grab": {
- "grabbable": false,
- "equippableLeftRotation": {
- "x": -0.0000152587890625,
- "y": -0.0000152587890625,
- "z": -0.0000152587890625,
- "w": 1
- },
- "equippableRightRotation": {
- "x": -0.0000152587890625,
- "y": -0.0000152587890625,
- "z": -0.0000152587890625,
- "w": 1
- }
+ "grabbable": false
},
"collisionless": true,
"ignoreForCollisions": true,
- "queryAACube": {
- "x": -0.17320507764816284,
- "y": -0.17320507764816284,
- "z": -0.17320507764816284,
- "scale": 0.3464101552963257
- },
"damping": 0,
- "color": intensityEntityColorMin,
- "clientOnly": false,
- "avatarEntity": true,
- "localEntity": false,
- "faceCamera": false,
- "isFacingAvatar": false
+ "color": intensityEntityColorMin
};
var currentInitialAngularVelocity = {
"x": 0,
@@ -266,12 +217,22 @@
}
if (currentIntensity > 0) {
+ var matData = {
+ "materialVersion": 1,
+ "materials": [
+ {
+ "name": "intensity",
+ "albedo": [intensityEntityColorMax.red/255, intensityEntityColorMax.green/255, intensityEntityColorMax.blue/255],
+ "metallic": 0.001,
+ "roughness": 0.9,
+ "emissive": [(intensityEntityColorMax.red/255) * (MAX_GLOW * currentIntensity), (intensityEntityColorMax.green/255) * (MAX_GLOW * currentIntensity), (intensityEntityColorMax.blue/255) * (MAX_GLOW * currentIntensity)],
+ "cullFaceMode": "CULL_BACK",
+ "model": "hifi_pbr"
+ }
+ ]
+ };
+
if (intensityEntity) {
- intensityEntityColorMin.red = intensityEntityColorMax.red * MIN_COLOR_MULTIPLIER;
- intensityEntityColorMin.green = intensityEntityColorMax.green * MIN_COLOR_MULTIPLIER;
- intensityEntityColorMin.blue = intensityEntityColorMax.blue * MIN_COLOR_MULTIPLIER;
-
- var color = linearScaleColor(currentIntensity, intensityEntityColorMin, intensityEntityColorMax);
var propsToUpdate = {
position: getAppreciationPosition()
@@ -290,13 +251,8 @@
lastAngularVelocity = currentAngularVelocity;
}
- var currentColor = color;
- if (colorChangedEnough(currentColor, lastColor, COLOR_DISTANCE_THRESHOLD_PERCENT_CHANGE)) {
- propsToUpdate.color = currentColor;
- lastColor = currentColor;
- }
-
Entities.editEntity(intensityEntity, propsToUpdate);
+ Entities.editEntity(intensityEntityMaterial, {"materialData": JSON.stringify(matData)});
} else {
var props = INTENSITY_ENTITY_PROPERTIES;
props.position = getAppreciationPosition();
@@ -310,11 +266,21 @@
props.angularVelocity = currentInitialAngularVelocity;
intensityEntity = Entities.addEntity(props, "avatar");
+ intensityEntityMaterial = Entities.addEntity({
+ "type": "Material",
+ "name": "Intensity Entity Material",
+ "parentID": intensityEntity,
+ "materialURL": "materialData",
+ "materialData": JSON.stringify(matData),
+ "priority": 2,
+ "parentMaterialName": "0"
+ }, "avatar");
}
} else {
if (intensityEntity) {
Entities.deleteEntity(intensityEntity);
intensityEntity = false;
+ intensityEntityMaterial = Uuid.NULL;
}
maybeClearUpdateIntensityEntityInterval();
@@ -327,6 +293,13 @@
updateCurrentIntensityUI();
}
+ function onClosed() {
+ if (appreciateEnabled) {
+ ui.buttonActive(true);
+ } else {
+ ui.buttonActive(false);
+ }
+ }
// Locally pre-caches all of the sounds in the sounds/claps and sounds/whistles
// directories.
@@ -1018,7 +991,11 @@
intensityEntityColorMax = message.entityColor;
Settings.setValue("appreciate/entityColor", JSON.stringify(intensityEntityColorMax));
break;
-
+
+ case "uninstall":
+ ScriptDiscoveryService.stopScript(Script.resolvePath(''), false);
+ break;
+
case "zKeyDown":
var pressEvent = {
"text": "Z",
@@ -1088,12 +1065,12 @@
if (intensityEntity) {
Entities.deleteEntity(intensityEntity);
intensityEntity = false;
+ intensityEntityMaterial = Uuid.NULL;
}
HMD.displayModeChanged.disconnect(enableOrDisableAppreciate);
}
-
// When called, this function will stop the versions of this script that are
// baked into the client installation IF there's another version of the script
// running that ISN'T the baked version.
@@ -1121,7 +1098,6 @@
}
}
-
// Called when the script starts up
var BUTTON_NAME = "APPRECIATE";
var APP_UI_URL = Script.resolvePath('resources/appreciate_ui.html');
@@ -1135,7 +1111,8 @@
// clap by Rena from the Noun Project
graphicsDirectory: Script.resolvePath("./resources/images/icons/"),
onOpened: onOpened,
- onMessage: onMessage
+ onMessage: onMessage,
+ onClosed: onClosed
});
cleanupOldIntensityEntities();
@@ -1146,6 +1123,12 @@
getAnimations();
HMD.displayModeChanged.connect(enableOrDisableAppreciate);
maybeStopBakedScriptVersions();
+
+ if (appreciateEnabled) {
+ ui.buttonActive(true);
+ } else {
+ ui.buttonActive(false);
+ }
}
diff --git a/applications/appreciate/resources/appreciate_ui.html b/applications/appreciate/resources/appreciate_ui.html
index f89504e..9034efb 100644
--- a/applications/appreciate/resources/appreciate_ui.html
+++ b/applications/appreciate/resources/appreciate_ui.html
@@ -8,18 +8,8 @@
UI for the "Appreciate" application.
- * This program ("Appreciate" application) is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ Distributed under the Apache License, Version 2.0
+ See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-->
@@ -27,8 +17,6 @@
Appreciate
-
-
@@ -38,7 +26,7 @@
- Appreciate v1.5
+ Appreciate v1.6
-
+
-
-
+
Dodecahedron Color
+
+
-
Desktop Mode: Tap or hold the Z key on your keyboard!
@@ -89,8 +76,12 @@
VR Mode: Raise your hands above your head and shake them!
+
+
+
+
diff --git a/applications/appreciate/resources/css/style.css b/applications/appreciate/resources/css/style.css
index 8ac3f48..127deb4 100644
--- a/applications/appreciate/resources/css/style.css
+++ b/applications/appreciate/resources/css/style.css
@@ -26,7 +26,7 @@ body {
#mainContainer {
width: 100vw;
- height: 100vh;
+ height: 96vh;
}
#loadingContainer {
@@ -151,7 +151,7 @@ input:checked + .slider:before {
#currentIntensityDisplay {
width: 100%;
- height: 175px;
+ height: 100px;
margin-top: 8px;
background: #FFFFFF;
background-image: linear-gradient(to right, #EEE 0, #EEE 55%, #FFF 55%, #FFF 100%);
@@ -180,22 +180,31 @@ input:checked + .slider:before {
#optionsContainer {
display: flex;
flex-direction: column;
- height: 150px;
+ height: 100px;
width: calc(100vw - 24px);
margin: 12px 12px 0 12px;
position: absolute;
}
#colorPickerContainer {
- margin: 8px 0 0 0;
- visibility: hidden;
+ text-align: left;
+ width: 100%;
}
-#colorPickerContainer > input {
+#colorPicker {
font-family: Raleway;
+ color: #000000;
height: 34px;
- font-size: 18px;
- min-width: 185px;
+ font-size: 24px;
+ width: 360px;
+ border: 1px solid #000000;
+ vertical-align: middle;
+ text-align: center;
+}
+
+#hueSelector {
+ width: 360px;
+ border: 1px solid #000000;
}
.checkmark {
@@ -277,7 +286,7 @@ input:checked + .slider:before {
#instructions {
position: fixed;
height: 150px;
- bottom: 0;
+ bottom: 20px;
left: 0;
right: 0;
margin: 0 12px;
@@ -287,3 +296,33 @@ input:checked + .slider:before {
#instructions > div {
margin-top: 16px;
}
+
+#uninstall {
+ font-family: Raleway;
+ background-color: #222222;
+ font-size: 9px;
+ color: #cccccc;
+ border-radius: 3px;
+ border: 0px solid #000000;
+ transition-duration: 0.2s;
+ width: 140px;
+ padding: 3px;
+}
+
+#uninstall:hover {
+ background-color: #000000;
+ color: #ffffff;
+}
+
+#uninstall:focus {
+ outline: none;
+}
+
+#uninstallBar {
+ text-align: right;
+ background-color: #121212;
+ width: 100vw;
+ height: 4vh;
+ padding-right: 8px;
+ padding-top: 2px;
+}
diff --git a/applications/appreciate/resources/images/hueBar.jpg b/applications/appreciate/resources/images/hueBar.jpg
new file mode 100644
index 0000000..8215cdb
Binary files /dev/null and b/applications/appreciate/resources/images/hueBar.jpg differ
diff --git a/applications/appreciate/resources/js/appreciate_ui.js b/applications/appreciate/resources/js/appreciate_ui.js
index 2732ce4..bafcc8d 100644
--- a/applications/appreciate/resources/js/appreciate_ui.js
+++ b/applications/appreciate/resources/js/appreciate_ui.js
@@ -7,18 +7,8 @@
Javascript code for the UI of the "Appreciate" application.
- * This program ("Appreciate" application) is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ Distributed under the Apache License, Version 2.0
+ See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
*/
/* globals document EventBridge setTimeout */
@@ -67,14 +57,15 @@ function showAppreciationEntityCheckboxClicked(checkbox) {
}
}
-// Called when the user changes the entity's color using the jscolor picker.
+// Called when the user changes the entity's color using the hue selector.
// Modifies the color of the Intensity Meter gradient and sends a message to the App JS.
var START_COLOR_MULTIPLIER = 0.2;
-function setEntityColor(jscolor) {
+function setEntityColor(colorArray) {
+
var newEntityColor = {
- "red": jscolor.rgb[0],
- "green": jscolor.rgb[1],
- "blue": jscolor.rgb[2]
+ "red": colorArray[0],
+ "green": colorArray[1],
+ "blue": colorArray[2]
};
var startColor = {
@@ -86,8 +77,10 @@ function setEntityColor(jscolor) {
var currentIntensityDisplayWidth = document.getElementById("currentIntensityDisplay").offsetWidth;
var bgString = "linear-gradient(to right, rgb(" + startColor.red + ", " +
startColor.green + ", " + startColor.blue + ") 0, " +
- jscolor.toHEXString() + " " + currentIntensityDisplayWidth + "px)";
+ "rgb(" + newEntityColor.red + ", " + newEntityColor.green + ", " + newEntityColor.blue + ") " +
+ currentIntensityDisplayWidth + "px)";
document.getElementById("currentIntensity").style.backgroundImage = bgString;
+ document.getElementById("colorPicker").style.backgroundColor = "rgb(" + newEntityColor.red + ", " + newEntityColor.green + ", " + newEntityColor.blue + ")";
EventBridge.emitWebEvent(JSON.stringify({
app: "appreciate",
@@ -96,6 +89,59 @@ function setEntityColor(jscolor) {
}));
}
+var hueSelector = document.getElementById('hueSelector');
+hueSelector.addEventListener("click", function(event) {
+ var rect = hueSelector.getBoundingClientRect();
+ var hue = event.clientX - rect.left;
+ if (hue >= 0 || hue <= 360) {
+ setEntityColor(hslToRgb(hue/360, 1, 0.65)); //.65 is adding just a bit of white in the saturated color (0.5) to get a brighter glow effect.
+ }
+});
+
+/*
+ * Converts an HSL color value to RGB. Conversion formula
+ * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
+ * Assumes h, s, and l are contained in the set [0, 1] and
+ * returns r, g, and b in the set [0, 255].
+ *
+ * @param {number} h The hue
+ * @param {number} s The saturation
+ * @param {number} l The lightness
+ * @return {Array} The RGB representation
+ */
+function hslToRgb(h, s, l){
+ var r, g, b;
+
+ if(s == 0){
+ r = g = b = l; // achromatic
+ }else{
+ var hue2rgb = function hue2rgb(p, q, t){
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ }
+
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3);
+ }
+
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
+}
+
+function uninstall() {
+ var message = {
+ "app": "appreciate",
+ "method": "uninstall"
+ };
+ EventBridge.emitWebEvent(JSON.stringify(message));
+}
+
// Handle EventBridge messages from *_app.js.
function onScriptEventReceived(message) {
try {
@@ -133,19 +179,8 @@ function onScriptEventReceived(message) {
document.getElementById("loadingContainer").style.display = "none";
- var color = document.getElementById("colorPicker").jscolor;
- color.fromRGB(message.entityColor.red, message.entityColor.green, message.entityColor.blue);
-
- var startColor = {
- "red": Math.floor(color.rgb[0] * START_COLOR_MULTIPLIER),
- "green": Math.floor(color.rgb[1] * START_COLOR_MULTIPLIER),
- "blue": Math.floor(color.rgb[2] * START_COLOR_MULTIPLIER)
- };
- var currentIntensityDisplayWidth = document.getElementById("currentIntensityDisplay").offsetWidth;
- document.getElementById("currentIntensity").style.backgroundImage =
- "linear-gradient(to right, rgb(" + startColor.red + ", " +
- startColor.green + ", " + startColor.blue + ") 0, " +
- color.toHEXString() + " " + currentIntensityDisplayWidth + "px)";
+ setEntityColor([message.entityColor.red, message.entityColor.green, message.entityColor.blue]);
+
break;
case "updateCurrentIntensityUI":