working UI

This commit is contained in:
milad 2019-08-04 15:11:55 -07:00
parent 7322ad78f5
commit d1efbc051a
1315 changed files with 255266 additions and 3 deletions

View file

@ -0,0 +1,7 @@
Image {
width: 36
height: 36
anchors.centerIn: parent
source: emojiBaseURL + EmojiList.emojiList[0].code[0] + ".png"
fillMode: Image.PreserveAspectFit
}

View file

@ -0,0 +1,162 @@
//
// EmojiApp.qml
//
// Created by Milad Nazeri on 2019-08-03
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../simplifiedConstants" as SimplifiedConstants
import "../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import "./emojiList.js" as EmojiList
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
import TabletScriptingInterface 1.0
Rectangle {
id: root
color: simplifiedUI.colors.darkBackground
// color: simplifiedUI.colors.darkBackground
anchors.fill: parent
readonly property string emojiBaseURL: "./images/emojis/png1024/"
readonly property string emojiSpriteBaseURL: "./images/emojis/"
property string currentCode: ""
property bool emojiRunning: false
onCurrentCodeChanged: {
console.log("CURRENT CODE IS BEING CHANGED");
mainEmojiImage.source = emojiBaseURL + currentCode + ".png";
console.log("new main emoji image source:", mainEmojiImage.source);
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
focus: true
ListModel {
id: mainModel
}
Component.onCompleted: {
root.forceActiveFocus();
EmojiList.emojiList
.filter( emoji => {
return emoji.mainCategory === "Smileys & Emotion" ||
emoji.mainCategory === "People & Body" ||
emoji.mainCategory === "Animals & Nature" ||
emoji.mainCategory === "Food & Drink";
})
.forEach(function(item, index){
item.code = { utf: item.code[0] }
item.keywords = { keywords: item.keywords }
mainModel.append(item);
});
root.currentCode = mainModel.get(0).code.utf;
console.log("CURRENT CODE", root.currentCode);
}
Rectangle {
id: emojiIndicatorContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 200
clip: true
color: simplifiedUI.colors.darkBackground
Image {
id: mainEmojiImage
width: 180
height: 180
anchors.centerIn: parent
source: emojiBaseURL + root.currentCode + ".png"
fillMode: Image.PreserveAspectFit
}
}
Rectangle {
id: emojiIconListContainer
anchors.top: emojiIndicatorContainer.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 415
clip: true
color: simplifiedUI.colors.darkBackground
// color: "#DDFF33"
// TODO: Fix the margin in the emoji, you can tell from the highlight
Component {
id: emojiDelegate
Item {
width: grid.cellWidth; height: grid.cellHeight
Column {
Rectangle {
id: imageContainer
// anchors.centerIn: emojiDelegate.centerIn
clip: true;
z:1
width: 36
height: 36
x: 2
y: -2
color: Qt.rgba(1, 1, 1, 0.0)
Image {
source: emojiSpriteBaseURL + normal.source
z: 2
fillMode: Image.Pad
x: -normal.frame.x
y: -normal.frame.y
MouseArea {
hoverEnabled: enabled
anchors.fill: parent
onEntered: {
// Tablet.playSound(TabletEnums.ButtonClick);
grid.currentIndex = index
console.log("model.get(grid.currentIndex).code.utf", mainModel.get(index).code.utf)
root.currentCode = mainModel.get(index).code.utf;
}
onClicked: {
console.log("GOT THE CLICK on emoji");
sendToScript({
"source": "EmoteAppBar.qml",
"method": "selectedEmoji",
"code": code.utf
});
}
onExited: {
}
}
}
}
}
}
}
GridView {
id: grid
anchors.fill: parent
anchors.centerIn: parent
anchors.leftMargin: 0
anchors.rightMargin: 0
width: 480
height: 415
cellWidth: 40
cellHeight: 40
model: mainModel
delegate: emojiDelegate
focus: true
highlight: Rectangle { color: Qt.rgba(1, 1, 1, 0.4); radius: 0 }
}
}
signal sendToScript(var message);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
emojis/png1024
emojis/svg-original
emojis/svg-variations
emojis/svgFiltered

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

View file

@ -0,0 +1,6 @@
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" preserveAspectRatio="xMidYMid" viewBox="0 0 63 78.75" version="1.1" x="0px" y="0px"><defs><style>
.cls-3 {
fill: #000000;
}
</style></defs><path style="" d="M 31.160156 0.01171875 C 13.985156 0.01171875 0.013671875 13.987016 0.013671875 31.166016 C 0.013671875 48.344016 13.985156 62.320312 31.160156 62.320312 C 48.334156 62.320312 62.306641 48.344016 62.306641 31.166016 C 62.306641 13.987016 48.334156 0.01171875 31.160156 0.01171875 z M 31.160156 3.0117188 C 46.681156 3.0117188 59.306641 15.642016 59.306641 31.166016 C 59.306641 46.690016 46.681156 59.320312 31.160156 59.320312 C 15.640156 59.320312 3.0136719 46.690016 3.0136719 31.166016 C 3.0136719 15.642016 15.640156 3.0117187 31.160156 3.0117188 z M 21.660156 18.306641 C 19.951281 18.286766 18.248188 18.902203 16.992188 20.158203 C 16.406188 20.744203 16.406188 21.69525 16.992188 22.28125 C 17.578187 22.86725 18.527281 22.86725 19.113281 22.28125 C 20.477281 20.91825 22.826047 20.969625 24.248047 22.390625 C 24.541047 22.683625 24.926547 22.830078 25.310547 22.830078 C 25.693547 22.830078 26.076141 22.683625 26.369141 22.390625 C 26.955141 21.805625 26.955141 20.854531 26.369141 20.269531 C 25.083641 18.983031 23.369031 18.326516 21.660156 18.306641 z M 42.0625 18.306641 C 40.353625 18.286766 38.652484 18.902203 37.396484 20.158203 C 36.811484 20.744203 36.811484 21.69525 37.396484 22.28125 C 37.982484 22.86725 38.932578 22.86725 39.517578 22.28125 C 40.881578 20.91825 43.230344 20.969625 44.652344 22.390625 C 44.945344 22.683625 45.330844 22.830078 45.714844 22.830078 C 46.098844 22.830078 46.480438 22.683625 46.773438 22.390625 C 47.359438 21.805625 47.359437 20.854531 46.773438 20.269531 C 45.487938 18.983031 43.771375 18.326516 42.0625 18.306641 z M 18.857422 34.193359 C 18.029422 34.193359 17.357422 34.865359 17.357422 35.693359 C 17.357422 42.478359 22.758344 47.792969 29.652344 47.792969 L 35.052734 47.792969 C 41.946734 47.792969 47.347656 42.566531 47.347656 35.894531 C 47.347656 35.065531 46.675656 34.394531 45.847656 34.394531 C 45.018656 34.394531 44.347656 35.065531 44.347656 35.894531 C 44.347656 40.883531 40.265734 44.791016 35.052734 44.791016 L 29.652344 44.791016 C 24.439344 44.791016 20.357422 40.795359 20.357422 35.693359 C 20.357422 34.865359 19.685422 34.193359 18.857422 34.193359 z " fill="#000000" fill-rule="evenodd"/><text x="0" y="78" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">Created by Shital Patel</text><text x="0" y="83" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">from the Noun Project</text></svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="Layer_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 63 78.8"
style="enable-background:new 0 0 63 78.8;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st1{fill:#FFFFFF;}
.st2{font-family:'Arial-BoldMT';}
.st3{font-size:5px;}
</style>
<path class="st0" d="M31.2,0C14,0,0,14,0,31.2c0,17.2,14,31.2,31.1,31.2c17.2,0,31.1-14,31.1-31.2C62.3,14,48.3,0,31.2,0z M31.2,3
c15.5,0,28.1,12.6,28.1,28.2S46.7,59.3,31.2,59.3C15.6,59.3,3,46.7,3,31.2S15.6,3,31.2,3z M21.7,18.3c-1.7,0-3.4,0.6-4.7,1.9
c-0.6,0.6-0.6,1.5,0,2.1s1.5,0.6,2.1,0c1.4-1.4,3.7-1.3,5.1,0.1c0.3,0.3,0.7,0.4,1.1,0.4c0.4,0,0.8-0.1,1.1-0.4
c0.6-0.6,0.6-1.5,0-2.1C25.1,19,23.4,18.3,21.7,18.3z M42.1,18.3c-1.7,0-3.4,0.6-4.7,1.9c-0.6,0.6-0.6,1.5,0,2.1
c0.6,0.6,1.5,0.6,2.1,0c1.4-1.4,3.7-1.3,5.1,0.1c0.3,0.3,0.7,0.4,1.1,0.4s0.8-0.1,1.1-0.4c0.6-0.6,0.6-1.5,0-2.1
C45.5,19,43.8,18.3,42.1,18.3z M18.9,34.2c-0.8,0-1.5,0.7-1.5,1.5c0,6.8,5.4,12.1,12.3,12.1h5.4c6.9,0,12.3-5.2,12.3-11.9
c0-0.8-0.7-1.5-1.5-1.5c-0.8,0-1.5,0.7-1.5,1.5c0,5-4.1,8.9-9.3,8.9h-5.4c-5.2,0-9.3-4-9.3-9.1C20.4,34.9,19.7,34.2,18.9,34.2z"/>
<text transform="matrix(1 0 0 1 0 78)" class="st1 st2 st3">Created by Shital Patel</text>
<text transform="matrix(1 0 0 1 0 83)" class="st1 st2 st3">from the Noun Project</text>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -0,0 +1 @@
<svg width="72px" height="72px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-rolling" style="background: none;"><circle cx="50" cy="50" fill="none" ng-attr-stroke="{{config.color}}" ng-attr-stroke-width="{{config.width}}" ng-attr-r="{{config.radius}}" ng-attr-stroke-dasharray="{{config.dasharray}}" stroke="#00b4ef" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138" transform="rotate(239.933 50 50)"><animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 50 50;360 50 50" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform></circle></svg>

After

Width:  |  Height:  |  Size: 685 B

View file

@ -24,6 +24,9 @@ Rectangle {
property int hoveredWidth: 480
property int requestedWidth
property bool overEmoteButton: false
property bool overEmojiButton: false
onRequestedWidthChanged: {
root.requestNewWidth(root.requestedWidth);
}
@ -38,16 +41,24 @@ Rectangle {
}
MouseArea {
id: emoteMouseArea
anchors.fill: parent
hoverEnabled: enabled
propagateComposedEvents: true;
onEntered: {
console.log("in mouseArea 1");
Tablet.playSound(TabletEnums.ButtonHover);
root.requestedWidth = root.hoveredWidth;
emojiMouseArea.hoverEnabled = true;
root.overEmoteButton = true;
}
onExited: {
console.log("MOUSE 1 EXIT");
root.overEmoteButton = false;
Tablet.playSound(TabletEnums.ButtonClick);
root.requestedWidth = root.originalWidth;
}
z: 2
}
Rectangle {
@ -69,6 +80,7 @@ Rectangle {
size: 26
color: simplifiedUI.colors.text.almostWhite
}
}
Rectangle {
@ -87,6 +99,48 @@ Rectangle {
size: 20
color: simplifiedUI.colors.text.black
}
Rectangle {
id: emojiButtonBackground
z: 3
width: root.originalWidth
height: parent.height
anchors.right: parent.right
color: simplifiedUI.colors.darkBackground
HifiStylesUit.GraphikRegular {
id: emojiButton
text: "😊"
z: 3
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 1
anchors.verticalCenterOffset: -2
horizontalAlignment: Text.AlignHCenter
size: 26
color: simplifiedUI.colors.text.almostWhite
}
MouseArea {
id: emojiMouseArea
anchors.fill: parent
hoverEnabled: false
propagateComposedEvents: true;
z: 4
onClicked: {
console.log("GOT THE CLICK");
sendToScript({
"source": "EmoteAppBar.qml",
"method": "toggleEmojiApp"
});
}
onEntered: {
console.log("OVER EMOJI BUTTON");
}
}
}
}
function fromScript(message) {

View file

@ -0,0 +1,463 @@
/*
Avimoji
avimoji_app.js
Created by Milad Nazeri on 2019-04-25
Copyright 2019 High Fidelity, Inc.
Distributed under the Apache License, Version 2.0.
See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
*/
(function () {
// *************************************
// START dependencies
// *************************************
// #region dependencies
// Custom module for handling entities
var EntityMaker = Script.require("./resources/modules/entityMaker.js?" + Date.now());
// Add nice smoothing functions to the animations
var EasingFunctions = Script.require("./resources/modules/easing.js");
// The information needed to properly use the sprite sheets and get the general information
// about the emojis
var emojiList = Script.require("./resources/node/emojiList.json?" + Date.now());
// The location to find where the individual emoji icons are
var CONFIG = Script.require("./resources/config.json?" + Date.now());
// Where to load the images from taken from the Config above
var imageURLBase = CONFIG.baseImagesURL;
// #endregion
// *************************************
// END dependencies
// *************************************
// *************************************
// START utility
// *************************************
// #region utility
// CONSTS
// UTF-Codes are stored on the first index of one of the keys on a returned emoji object.
// Just makes the code a little easier to read
var UTF_CODE = 0;
// Make the emoji groups
var MAX_PER_GROUP = 250;
var emojiChunks = [];
function makeEmojiChunks() {
for (var i = 0, len = emojiList.length; i < len; i += MAX_PER_GROUP) {
emojiChunks.push(emojiList.slice(i, i + MAX_PER_GROUP));
}
}
// Play sound borrowed from bingo app:
// Plays the specified sound at the specified position, volume, and localOnly
// Only plays a sound if it is downloaded.
// Only plays one sound at a time.
var soundUrl = Script.resolvePath('./resources/sounds/emojiPopSound.wav');
var popSound = SoundCache.getSound(soundUrl);
var injector;
var DEFAULT_VOLUME = 0.0003;
var local = false;
function playSound(sound, volume, position, localOnly) {
sound = sound || popSound;
volume = volume || DEFAULT_VOLUME;
position = position || MyAvatar.position;
localOnly = localOnly || local;
if (sound.downloaded) {
if (injector) {
injector.stop();
}
injector = Audio.playSound(sound, {
position: position,
volume: volume,
localOnly: localOnly
});
}
}
// prune old emojis on you
function pruneOldAvimojis() {
MyAvatar.getAvatarEntitiesVariant()
.forEach(function (avatarEntity) {
if (avatarEntity && avatarEntity.properties.name.toLowerCase().indexOf("avimoji") > -1) {
Entities.deleteEntity(avatarEntity.id);
}
});
}
// help send an emoji chunk to load up faster in the tablet
var INTERVAL = 200;
var currentChunk = 0;
function sendEmojiChunks() {
if (currentChunk >= emojiChunks.length) {
currentChunk = 0;
return;
} else {
var chunk = emojiChunks[currentChunk];
ui.sendMessage({
app: "avimoji",
method: "sendChunk",
chunkNumber: currentChunk,
totalChunks: emojiChunks.length,
chunk: chunk
});
currentChunk++;
Script.setTimeout(function () {
sendEmojiChunks();
}, INTERVAL);
}
}
// #endregion
// *************************************
// END utility
// *************************************
// *************************************
// START ui_handlers
// *************************************
// #region ui_handlers
// what to do when someone selects an emoji in the tablet
var selectedEmoji = null;
var lastEmoji = null;
function handleSelectedEmoji(data) {
var emoji = data.emoji;
if (selectedEmoji && selectedEmoji.code[UTF_CODE] === emoji.code[UTF_CODE]) {
maybePlayPop("off");
selectedEmoji = null;
return;
} else {
selectedEmoji = emoji;
lastEmoji = emoji;
addEmoji(selectedEmoji);
}
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji
});
}
// handle what happens when unselect an emoji
function handleSelectedRemoved() {
maybePlayPop("off");
selectedEmoji = null;
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji
});
}
function onDomainChanged() {
pruneOldAvimojis();
maybeClearPop();
if (currentEmoji && currentEmoji.id) {
currentEmoji.destroy();
selectedEmoji = null;
}
maybeClearPop();
if (ui.isOpen) {
ui.close();
}
}
// #endregion
// *************************************
// END ui_handlers
// *************************************
// *************************************
// START avimoji
// *************************************
// #region avimoji
// what happens when we need to add an emoji over a user
var billboardMode = "full";
var currentSelectedDimensions = null;
function addEmoji(emoji) {
if (currentEmoji && currentEmoji.id) {
maybePlayPop("offThenOn");
} else {
createEmoji(emoji);
}
}
// creating the actual emoji that isn't an animation
var ABOVE_HEAD = 0.60;
var EMOJI_CONST_SCALER = 0.27;
var currentEmoji = new EntityMaker("avatar");
var EMOJI_X_OFFSET = -0.01;
var DEFAULT_EMOJI_SIZE = 0.27;
var emojiSize = Settings.getValue("avimoji/emojiSize", DEFAULT_EMOJI_SIZE);
function createEmoji(emoji) {
var neckPosition, avatarScale, aboveNeck, emojiPosition;
avatarScale = MyAvatar.scale;
aboveNeck = ABOVE_HEAD;
neckPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position);
emojiPosition = Vec3.sum(
neckPosition,
[
EMOJI_X_OFFSET,
avatarScale * aboveNeck * (1 + emojiSize * EMOJI_CONST_SCALER),
0
]);
var IMAGE_SIZE = avatarScale * emojiSize;
var dimensions = { x: IMAGE_SIZE, y: IMAGE_SIZE, z: IMAGE_SIZE };
currentSelectedDimensions = dimensions;
var parentID = MyAvatar.sessionUUID;
var imageURL = imageURLBase + emoji.code[UTF_CODE] + ".png";
currentEmoji
.add('type', "Image")
.add('name', 'AVIMOJI')
.add('localPosition', emojiPosition)
.add('dimensions', [0, 0, 0])
.add('parentID', parentID)
.add('emissive', true)
.add('collisionless', true)
.add('imageURL', imageURL)
.add('billboardMode', billboardMode)
.add('ignorePickIntersection', true)
.add('alpha', 1)
.add('grab', {grabbable: false})
.create();
maybePlayPop("on");
}
// #endregion
// *************************************
// END avimoji
// *************************************
// *************************************
// START animation
// *************************************
// #region animation
// see what we need to do when an emoji gets clicked
var DURATION = POP_ANIMATION_DURATION_MS + 100;
function maybePlayPop(type) {
maybeClearPop();
popType = type;
playPopInterval = Script.setInterval(playPopAnimation, POP_DURATION_PER_STEP);
}
// maybe clear a pop up animation not in animation mode
function maybeClearPop() {
if (playPopInterval) {
Script.clearTimeout(playPopInterval);
playPopInterval = null;
currentPopScale = null;
currentPopStep = 1;
isPopPlaying = false;
popType = null;
}
}
// play an animation pop in
var currentPopStep = 1;
var POP_ANIMATION_DURATION_MS = 170;
var POP_ANIMATION_STEPS = 10;
var POP_DURATION_PER_STEP = POP_ANIMATION_DURATION_MS / POP_ANIMATION_STEPS;
var currentPopScale = null;
var MAX_POP_SCALE = 1;
var MIN_POP_SCALE = 0.0;
var POP_SCALE_DISTANCE = MAX_POP_SCALE - MIN_POP_SCALE;
var POP_PER_STEP = POP_SCALE_DISTANCE / POP_ANIMATION_STEPS;
var isPopPlaying = false;
var popType = null;
var playPopInterval = null;
function playPopAnimation() {
var dimensions;
// Handle if this is the first step of the animation
if (currentPopStep === 1) {
isPopPlaying = true;
if (popType === "in") {
currentPopScale = MIN_POP_SCALE;
} else {
currentPopScale = MAX_POP_SCALE;
playSound();
}
}
// Setup the animation step
if (popType === "in") {
currentPopScale += POP_PER_STEP;
dimensions = Vec3.multiply(currentSelectedDimensions, EasingFunctions.easeInCubic(currentPopScale));
} else {
currentPopScale -= POP_PER_STEP;
dimensions = Vec3.multiply(currentSelectedDimensions, EasingFunctions.easeOutCubic(currentPopScale));
}
currentPopStep++;
currentEmoji.edit("dimensions", dimensions);
// Handle if it's the end of the animation step
if (currentPopStep === POP_ANIMATION_STEPS) {
if (popType === "in") {
playSound();
} else {
if (currentEmoji && currentEmoji.id) {
currentEmoji.destroy();
currentEmoji = new EntityMaker("avatar");
if (popType === "out") {
selectedEmoji = null;
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji
});
}
if (popType === "offThenOn") {
Script.setTimeout(function () {
createEmoji(selectedEmoji);
}, DURATION);
}
}
}
maybeClearPop();
}
}
// #endregion
// *************************************
// END animation
// *************************************
// *************************************
// START messages
// *************************************
// #region messages
// handle getting a message from the tablet
function onMessage(message) {
if (message.app !== "avimoji") {
return;
}
switch (message.method) {
case "eventBridgeReady":
ui.sendMessage({
app: "avimoji",
method: "updateUI",
selectedEmoji: selectedEmoji
});
sendEmojiChunks();
break;
case "handleSelectedEmoji":
handleSelectedEmoji(message.data);
break;
case "handleSelectedRemoved":
handleSelectedRemoved();
break;
default:
console.log("Unhandled message from avimoji_ui.js", message);
break;
}
}
// #endregion
// *************************************
// END messages
// *************************************
// *************************************
// START main
// *************************************
// #region main
// startup the app
var BUTTON_NAME = "AVIMOJI";
var APP_UI_URL = Script.resolvePath('./resources/avimoji_ui.html');
var AppUI = Script.require('./resources/modules/appUi.js?' + Date.now());
var ui;
var emojiCodeMap;
function startup() {
// make a map of just the utf codes to help with accesing
emojiCodeMap = emojiList.reduce(function (previous, current, index) {
if (current && current.code && current.code.length > 0 && current.code[UTF_CODE]) {
previous[current.code[UTF_CODE]] = index;
return previous;
}
}, {});
ui = new AppUI({
buttonName: BUTTON_NAME,
home: APP_UI_URL,
onMessage: onMessage,
graphicsDirectory: Script.resolvePath("./resources/images/icons/")
});
pruneOldAvimojis();
makeEmojiChunks();
Script.scriptEnding.connect(scriptEnding);
}
startup();
// #endregion
// *************************************
// END main
// *************************************
// *************************************
// START cleanup
// *************************************
// #region cleanup
function scriptEnding() {
if (ui.isOpen) {
ui.onClosed();
}
pruneOldAvimojis();
Window.domainChanged.disconnect(onDomainChanged);
if (currentEmoji && currentEmoji.id) {
currentEmoji.destroy();
}
maybeClearPop();
}
// #endregion
// *************************************
// END cleanup
// *************************************
})();

View file

@ -0,0 +1,736 @@
/*
- Built with same tech as settings screen. Use SettingsApp.qml as template to create the app page
- On hover or select, each emoji icon highlights. Add function for on hover to swap inactive icon with active
- Has scrolling field of emoji icons to choose from called emoji icon list. Add rows of emoji icons
- On hover or select, each emoji icon highlights. Add function for on hover to swap inactive icon with active
- Has emoji indicator at top to show current emoji icon selection
- Emoji indicator will initially be empty
- When user clicks emoji icon, an entity image of the selected emoji appears over their avatar's head.
- Create a function called 'addEmoji'. The 'addEmoji' fn will call 'createEmoji' and several other functions.
- In 'createEmoji' use entity API to add an avatar entity parented to head or fall back to neck if no head joint, hips if no neck joint.
- A 5 second timer begins Set 5 second timeout in 'addEmoji' function
- After 5 seconds, the emoji entity image shrinks and disappears over an 2 second interval When the timeout is up, start an interval for every 200ms to shrink the entity icon. After 10 intervals entity icon should be very small. Delete it and clear the interval by calling 'removeEmoji'.
- The emoji indicator and emote indicator display the time remaining until the entity icon will disappear as a highlighted pie section of the circular emoji image. Use a QML pieSeries over the emoji and emote indicators. The image for the pieSeries can be a 10% opacity white overlaycircle. Update the values of the pie slices on the 200ms interval to show the time left before the emoji disappears.
- The emote indicator is replaced with the current emoji icon (with timer display) while the emoji entity image appears over the user's head. In the 'addEmoji' function call a function that swaps the icon on the emote indicator.
- After the 7 seconds, the emoji entity image has disappeared
- The emote indicator returns to default. In 'removeEmoji', restore the default image for the emote indicator.
- The emoji indicator returns to empty. In 'removeEmoji', restore the default image for the emoji indicator.
- Emoji icon highlight is removed if not hovered. In 'removeEmoji', restore the default icon for the emoji that just ended.
*/
// NOTE: play Last emoji from keypress
// Open up on ctrl + enter
var ENTER_KEY = 16777220;
var SEMI_COLON_KEY = 59;
function keyPress(event) {
if (event.key === ENTER_KEY && event.isControl) {
if (ui.isOpen) {
ui.close();
} else {
ui.open();
}
} if (event.key === SEMI_COLON_KEY) {
playEmojiAgain();
}
}
// NOTE: turn the favorites object into an array of top 10 favorites
var MAX_FAVORITES = 10;
function makeFavoritesArray() {
var i = 0, favoritesArray = [];
for (var emoji in favorites ) {
favoritesArray[i++] = favorites[emoji];
}
favoritesArray.sort(function (a, b) {
if (a.count > b.count) {
return -1;
}
if (a.count < b.count) {
return 1;
}
return 0;
});
favoritesArray = favoritesArray.slice(0, MAX_FAVORITES);
return favoritesArray;
}
// NOTE: grab an emoji in a looping ring
function findValue(index, array, offset) {
offset = offset || 0;
return array[(index + offset) % array.length];
}
// NOTE: Wear emoji like a mask
// choose to wear a mask or above their head
var mask = Settings.getValue("avimoji/mask", false);
function handleMask(data) {
mask = data.mask;
if (currentEmoji && currentEmoji.id) {
addEmojiToUser(selectedEmoji);
}
if (mask) {
shouldTimeoutDelete = false;
} else {
shouldTimeoutDelete = true;
}
Settings.setValue("avimoji/mask", mask);
Settings.setValue("avimoji/shouldDefaultDelete", shouldTimeoutDelete);
}
// NOTE: Render the emojis locally
// don't render the emojis for anyone else
var local = Settings.getValue("avimoji/local", false);
var entityType = Settings.getValue("avimoji/entityType", "avatar");
function handleLocal(data) {
local = data.local;
Settings.setValue("avimoji/local", local);
if (local) {
entityType = "local";
Settings.setValue("avimoji/entityType", "local");
} else {
entityType = "avatar";
Settings.setValue("avimoji/entityType", "avatar");
}
if (!advanced && currentEmoji && currentEmoji.id) {
addEmojiToUser(selectedEmoji);
}
maybeRedrawAnimation();
}
// NOTE: Favorite emojis shown as overlays
// show the favorite emojis as overlays
var ezFavorites = Settings.getValue("avimoji/ezFavorites", false);
function handleEZFavorites(data) {
ezFavorites = data.ezFavorites;
log("EZ FAVORITES", ezFavorites, PRINT);
Settings.setValue("avimoji/ezFavorites", ezFavorites);
if (ezFavorites) {
maybeClearEZFavoritesTimer();
renderEZFavoritesOverlays();
} else {
deleteEZFavoritesOverlays();
maybeClearEZFavoritesTimer();
}
}
// NOTE: Handle playing emojis in sequence
// handle moving to sequence mode
var sequenceMode = Settings.getValue("avimoji/sequenceMode", false);
function handleSequenceMode(data) {
sequenceMode = data.sequenceMode;
Settings.setValue("avimoji/sequenceMode", sequenceMode);
if (!sequenceMode) {
maybeClearPlayEmojiSequenceInterval();
}
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji,
emojiSequence: emojiSequence
});
}
// NOTE: Original Handling of all the emojis
// what to do when someone selects an emoji in the tablet
var MAX_EMOJI_SEQUENCE = 40;
var emojiSequence = Settings.getValue("avimoji/emojiSequence", []);
var selectedEmoji = null;
function handleSelectedEmoji(data) {
var emoji = data.emoji;
if (advanced) {
if (!sequenceMode) {
selectedEmoji = emoji;
lastEmoji = emoji;
maybeClearTimeoutDelete();
addEmojiToUser(selectedEmoji);
} else {
emojiSequence.push(emoji);
emojiSequence = emojiSequence.slice(0, MAX_EMOJI_SEQUENCE);
Settings.setValue("avimoji/emojiSequence", emojiSequence);
}
} else {
if (selectedEmoji && selectedEmoji.code[0] === emoji.code[0]) {
maybePlayPop("off");
selectedEmoji = null;
return;
} else {
selectedEmoji = emoji;
lastEmoji = emoji;
maybeClearTimeoutDelete();
addEmojiToUser(selectedEmoji);
}
}
addToFavorites(emoji);
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji,
emojiSequence: emojiSequence
});
}
// NOTE: Changing the size of an emoji
// dynamically update the emoji size
function handleEmojiSize(data) {
emojiSize = data.emojiSize;
if (currentEmoji && currentEmoji.id) {
addEmojiToUser(selectedEmoji);
}
Settings.setValue("avimoji/emojiSize", emojiSize);
maybeRedrawAnimation();
}
// NOTE: Change the distance traveled in an emoji sequence
// handle a user changing the start and end distance of an emoji animation
var DEFAULT_ANIMATION_DISTANCE = 0.5;
var animationDistance = Settings.getValue("avimoji/animationDistance", DEFAULT_ANIMATION_DISTANCE);
function handleAnimationDistance(data) {
animationDistance = data.animationDistance;
Settings.setValue("avimoji/animationDistance", animationDistance);
maybeRedrawAnimation();
}
// NOTE: Change the speed of emoji sequence
// handle a user changing the speed of the emoji sequence animation
var DEFAULT_ANIMATION_SPEED = 1.2;
var animationSpeed = Settings.getValue("avimoji/animationSpeed", DEFAULT_ANIMATION_SPEED);
function handleAnimationSpeed(data) {
animationSpeed = data.animationSpeed;
Settings.setValue("avimoji/animationDistance", animationSpeed);
maybeRedrawAnimation();
}
// NOTE: Update the play state
// Update the play state
var isPlaying = false;
function handleUpdateIsPlaying(data) {
isPlaying = data.isPlaying;
if (isPlaying) {
playEmojiSequence();
} else {
stopEmojiSequence();
}
ui.sendMessage({
app: "avimoji",
method: "updatePlay",
isPlaying: isPlaying
});
}
// NOTE: Delete an Emoji from a sequence
// remove an emoji from the sequence
function deleteSequenceEmoji(data) {
emojiSequence.splice(data.index, 1);
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji,
emojiSequence: emojiSequence
});
if (emojiSequence.length === 0) {
maybeClearPlayEmojiSequenceInterval();
}
}
// NOTE: Handle emoji advanced selected
// handle if you change to move to advanced mode
var advanced = Settings.getValue("avimoji/advanced", false);
function handleAdvanced(data) {
advanced = data.advanced;
Settings.setValue("avimoji/advanced", advanced);
if (isPlaying) {
maybeClearPlayEmojiSequenceInterval();
isPlaying = false;
}
}
// NOTE: Reset the current emoji sequence to build a new one
function handleResetSequenceList() {
maybeClearPlayEmojiSequenceInterval();
emojiSequence = [];
Settings.setValue("avimoji/emojiSequence", emojiSequence);
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji,
emojiSequence: emojiSequence
});
ui.sendMessage({
app: "avimoji",
method: "updatePlay",
isPlaying: isPlaying
});
}
//
// NOTE: Empty out the favorites object to start tracking them again
function handleResetFavoritesList() {
favorites = {};
Settings.setValue("avimoji/favorites", favorites);
ui.sendMessage({
app: "avimoji",
method: "updateFavorites",
favorites: makeFavoritesArray(favorites)
});
deleteEZFavoritesOverlays();
}
//
// NOTE: toggles the emoji deleting by default
var shouldTimeoutDelete = Settings.getValue("avimoji/shouldTimeoutDelete", true);
function handleShouldTimeoutDelete(data) {
shouldTimeoutDelete = data.shouldTimeoutDelete;
Settings.setValue("avimoji/shouldTimeoutDelete", shouldTimeoutDelete);
if (shouldTimeoutDelete && currentEmoji) {
startTimeoutDelete();
} else {
maybeClearTimeoutDelete();
}
}
//
// NOTE: play the emoji again when we hit the ";" key
var lastEmoji = null;
function playEmojiAgain(){
if (currentEmoji && currentEmoji.id) {
maybePlayPop("offThenOn");
} else {
createEmoji(lastEmoji);
}
}
//
// NOTE: see if we need to clear the timeout delete that is currently there
function maybeClearTimeoutDelete() {
if (defaultTimeout) {
Script.clearTimeout(defaultTimeout);
defaultTimeout = null;
}
}
//
// NOTE: add a new emoji to your favorites list
var favorites = Settings.getValue("avimoji/favorites", {});
function addToFavorites(emoji) {
if (!favorites[emoji.code[UTF_CODE]]) {
favorites[emoji.code[UTF_CODE]] = { count: 1, code: emoji.code[UTF_CODE] };
} else {
favorites[emoji.code[UTF_CODE]].count++;
}
var newFavoritesArray = makeFavoritesArray(favorites);
Settings.setValue("avimoji/favorites", favorites);
ui.sendMessage({
app: "avimoji",
method: "updateFavorites",
favorites: newFavoritesArray
});
if (newFavoritesArray.length === 1 && ezFavorites) {
var data = {ezFavorites: ezFavorites};
handleEZFavorites(data);
// renderEZFavoritesOverlays();
}
}
// dynammically create the above the head properties in case of resize
var ABOVE_NECK_DEFAULT = 0.2;
var setupAboveNeck = ABOVE_NECK_DEFAULT;
setupAvatarScale = MyAvatar.scale;
function setupAboveHeadAnimationProperties() {
billboardMode = "full";
setupNeckPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position);
setupEmojiPosition1 =
Vec3.sum(setupNeckPosition, [(END_X + START_X) / 2,
setupAvatarScale * setupAboveNeck * (1 + emojiSize * EMOJI_CONST_SCALER), 0]);
setupEmojiPosition1 = Vec3.sum(setupEmojiPosition1, [nextPostionXOffset, nextPostionYOffset, nextPostionZOffset]);
setupEmojiPosition2 =
Vec3.sum(setupNeckPosition,
[START_X, setupAvatarScale * setupAboveNeck * (1 + emojiSize * EMOJI_CONST_SCALER), 0]);
setupEmojiPosition2 = Vec3.sum(setupEmojiPosition2, [nextPostionXOffset, nextPostionYOffset, nextPostionZOffset]);
}
// check to see if we need to redraw an animation
function maybeRedrawAnimation() {
if (isPlaying) {
setupAnimationVariables();
maybeClearPlayEmojiSequenceInterval();
playEmojiSequence();
}
}
// stop playing the emoji sequence
function stopEmojiSequence() {
maybeClearPlayEmojiSequenceInterval();
isPlaying = false;
currentIndex = 0;
}
// play the actual emoji sequence
var animationEmoji1 = new EntityMaker(entityType);
var animationEmoji2 = new EntityMaker(entityType);
var animationInitialDimensions = null;
function playEmojiSequence(){
setupAnimationVariables();
if (animationEmoji1 && animationEmoji1.id) {
animationEmoji1.destroy();
animationEmoji1 = new EntityMaker(entityType);
}
if (animationEmoji2 && animationEmoji2.id) {
animationEmoji2.destroy();
animationEmoji2 = new EntityMaker(entityType);
}
maybeClearPlayEmojiSequenceInterval();
if (mask) {
setupMaskAnimationProperties();
} else {
setupAboveHeadAnimationProperties();
}
animationEmoji1.add("parentJointIndex", MyAvatar.getJointIndex("Head"));
animationEmoji2.add("parentJointIndex", MyAvatar.getJointIndex("Head"));
var IMAGE_SIZE = setupAvatarScale * emojiSize;
var dimensions = { x: IMAGE_SIZE, y: IMAGE_SIZE, z: IMAGE_SIZE };
animationInitialDimensions = dimensions;
var parentID = MyAvatar.sessionUUID;
var imageURL1 = "";
var imageURL2 = "";
animationEmoji1
.add('type', "Image")
.add('name', 'AVIMOJI')
.add('localPosition', setupEmojiPosition1)
.add('dimensions', dimensions)
.add('parentID', parentID)
.add('emissive', true)
.add('imageURL', imageURL1)
.add('ignorePickIntersection', true)
.add('billboard', billboardMode)
.add('alpha', 1)
.add('userData', "{ \"grabbableKey\": { \"grabbable\": true, \"kinematic\": false } }")
.create(true);
animationEmoji2
.add('type', "Image")
.add('name', 'AVIMOJI')
.add('localPosition', setupEmojiPosition2)
.add('dimensions', dimensions)
.add('parentID', parentID)
.add('emissive', true)
.add('imageURL', imageURL2)
.add('billboard', billboardMode)
.add('ignorePickIntersection', true)
.add('alpha', 1)
.add('userData', "{ \"grabbableKey\": { \"grabbable\": true, \"kinematic\": false } }")
.create(true);
playEmojiInterval = Script.setInterval(onPlayEmojiInterval, DURATION_PER_STEP);
onPlayEmojiInterval();
isPlaying = true;
}
// dynamicly setup the animation properties
var DEFAULT_ANIMATION_DURATION = 1750;
var ANIMATION_DURATION = DEFAULT_ANIMATION_DURATION * animationSpeed;
var HOLD_STEPS = 40;
var ANIMATION_STEPS = 60;
var DURATION_PER_STEP = ANIMATION_DURATION / (ANIMATION_STEPS + HOLD_STEPS * 2);
var HALF_POINT = Math.ceil(ANIMATION_STEPS * 0.5);
var currentStep = HALF_POINT;
var MAX_SCALE = 1;
var MIN_SCALE = 0.0;
var SCALE_DISTANCE = MAX_SCALE - MIN_SCALE;
var MAX_ALPHA = 1;
var MIN_ALPHA = 0;
var ALPHA_DISTANCE = MAX_ALPHA - MIN_ALPHA;
var THRESHOLD_MIN_ALPHA = 0.001;
var THRESHHOLD_MAX_ALPHA = 0.999;
var DISTANCE_0_THRESHHOLD = 0.015;
var currentScale1 = MIN_SCALE;
var currentScale2 = MAX_SCALE;
var currentIndex = 0;
var playEmojiInterval = null;
var currentAlpha1 = 1;
var currentAlpha2 = 1;
var middleHOLD = 0;
var lastHOLD = 0;
var SCALE_INCREASE_PER_STEP = SCALE_DISTANCE / HALF_POINT;
var ALPHA_PER_STEP = ALPHA_DISTANCE / HALF_POINT;
function setupAnimationVariables() {
ANIMATION_DURATION = DEFAULT_ANIMATION_DURATION * animationSpeed;
DURATION_PER_STEP = ANIMATION_DURATION / (ANIMATION_STEPS + HOLD_STEPS * 2);
START_X = -1 * animationDistance;
END_X = 1 * animationDistance;
POSITION_DISTANCE = END_X - START_X;
POSITION_PER_STEP = POSITION_DISTANCE / ANIMATION_STEPS;
currentPosition1 = START_X;
currentPosition2 = (END_X + START_X) / 2;
}
// interval for playing an emoji animation
var START_X = -0.25 * animationDistance;
var END_X = 0.25 * animationDistance;
var POSITION_DISTANCE = END_X - START_X;
var POSITION_PER_STEP = POSITION_DISTANCE / ANIMATION_STEPS;
var currentPosition1 = START_X;
var currentPosition2 = (END_X + START_X) / 2;
var lastCurrent1Before0 = 0;
var lastCurrent2Before0 = 0;
function onPlayEmojiInterval() {
var emoji, imageURL;
if (currentStep === 1) {
middleHOLD = 0;
lastHOLD = 0;
currentPosition1 = 0;
currentScale1 = MAX_SCALE;
currentAlpha1 = MAX_ALPHA;
}
if (currentStep < HALF_POINT) {
currentScale1 += SCALE_INCREASE_PER_STEP;
currentScale2 -= SCALE_INCREASE_PER_STEP;
currentAlpha1 += ALPHA_PER_STEP;
currentAlpha2 -= ALPHA_PER_STEP;
}
if (currentStep === HALF_POINT) {
if (middleHOLD <= HOLD_STEPS) {
middleHOLD++;
return;
}
currentPosition2 = START_X;
currentScale2 = MIN_SCALE;
currentAlpha2 = MIN_ALPHA;
emoji = findValue(currentIndex, emojiSequence);
imageURL = imageURLBase + emoji.code[UTF_CODE] + ".png";
animationEmoji2.edit("imageURL", imageURL);
currentIndex++;
ui.sendMessage({
app: "avimoji",
method: "updateCurrentEmoji",
selectedEmoji: emoji
});
}
if (currentStep === ANIMATION_STEPS) {
if (lastHOLD <= HOLD_STEPS) {
lastHOLD++;
return;
}
currentStep = 1;
currentPosition1 = START_X;
currentScale1 = MIN_SCALE;
currentAlpha1 = MIN_ALPHA;
middleHOLD = 0;
lastHOLD = 0;
emoji = findValue(currentIndex, emojiSequence);
imageURL = imageURLBase + emoji.code[UTF_CODE] + ".png";
animationEmoji1.edit("imageURL", imageURL);
currentIndex++;
ui.sendMessage({
app: "avimoji",
method: "updateCurrentEmoji",
selectedEmoji: emoji
});
}
if (currentStep > HALF_POINT) {
currentScale1 -= SCALE_INCREASE_PER_STEP;
currentScale2 += SCALE_INCREASE_PER_STEP;
currentAlpha1 -= ALPHA_PER_STEP;
currentAlpha2 += ALPHA_PER_STEP;
}
var animationEmoji1Position = animationEmoji1.get("localPosition", true);
if (currentPosition1 === 0) {
currentPosition1 = lastCurrent1Before0;
}
if (currentPosition2 === 0) {
currentPosition2 = lastCurrent2Before0;
}
currentPosition1 += POSITION_PER_STEP;
currentPosition2 += POSITION_PER_STEP;
if (Math.abs(currentPosition1) < DISTANCE_0_THRESHHOLD) {
lastCurrent1Before0 = currentPosition1;
currentPosition1 = 0;
}
if (Math.abs(currentPosition2) < DISTANCE_0_THRESHHOLD) {
lastCurrent2Before0 = currentPosition2;
currentPosition2 = 0;
}
animationEmoji1Position.x = currentPosition1;
var animationEmoji2Position = animationEmoji2.get("localPosition", true);
animationEmoji2Position.x = currentPosition2;
var emojiPosition1 = animationEmoji1Position;
var emojiPosition2 = animationEmoji2Position;
var newDimensions1 = Vec3.multiply(animationInitialDimensions, EasingFunctions.easeInOutQuad(currentScale1));
var newDimensions2 = Vec3.multiply(animationInitialDimensions, EasingFunctions.easeInOutQuad(currentScale2));
var newAlpha1 = EasingFunctions.easeInOutQuint(currentAlpha1);
var newAlpha2 = EasingFunctions.easeInOutQuint(currentAlpha2);
if (newAlpha1 > THRESHHOLD_MAX_ALPHA) {
newAlpha1 = 1.0;
}
if (newAlpha1 < THRESHOLD_MIN_ALPHA) {
newAlpha1 = 0.0;
}
if (newAlpha2 > THRESHHOLD_MAX_ALPHA) {
newAlpha2 = 1.0;
}
if (newAlpha2 < THRESHOLD_MIN_ALPHA) {
newAlpha2 = 0.0;
}
animationEmoji1
.add("localPosition", emojiPosition1)
.add("dimensions", newDimensions1)
.add("alpha", newAlpha1)
.edit();
animationEmoji2
.add("localPosition", emojiPosition2)
.add("dimensions", newDimensions2)
.add("alpha", newAlpha2)
.edit();
currentStep++;
}
// Star the delete process and handle the right animation path for turning off
var DEFAULT_TIMEOUT_MS = 7000;
var defaultTimeout = null;
function startTimeoutDelete() {
defaultTimeout = Script.setTimeout(function () {
maybePlayPop("off");
selectedEmoji = null;
}, DEFAULT_TIMEOUT_MS);
}
// check to see if we need to clear the emoji interval
function maybeClearPlayEmojiSequenceInterval() {
if (animationEmoji1 && animationEmoji1.id) {
animationEmoji1.destroy();
}
if (animationEmoji2 && animationEmoji2.id) {
animationEmoji2.destroy();
}
if (currentEmoji && currentEmoji.id) {
currentEmoji.destroy();
currentEmoji = new EntityMaker("avatar");
deleteEmojiPreviewOverlay();
}
if (playEmojiInterval) {
Script.clearInterval(playEmojiInterval);
playEmojiInterval = null;
currentIndex = 0;
isPlaying = false;
}
}
// custom logging function
var PREPEND = "\n##Logger:Avimoji:Web::\n";
var DEBUG = false;
// var OFF = "off";
// var ON = "on";
// var PRINT = "PRINT";
var PRETTY_SPACES = 4;
function log(label, data, overrideDebug) {
if (!DEBUG) {
if (overrideDebug !== "PRINT") {
return;
}
} else {
if (overrideDebug === "off") {
return;
}
}
data = typeof data === "undefined" ? "" : data;
data = typeof data === "string" ? data : (JSON.stringify(data, null, PRETTY_SPACES) || "");
data = data + " " || "";
console.log(PREPEND + label + ": " + data + "\n");
}
function playPopAnimationIn() {
var dimensions;
if (currentPopStep === 1) {
isPopPlaying = true;
currentPopScale = MIN_POP_SCALE;
}
currentPopScale += POP_PER_STEP;
dimensions = Vec3.multiply(currentSelectedDimensions, EasingFunctions.easeInCubic(currentPopScale));
currentEmoji.edit("dimensions", dimensions);
currentPopStep++;
if (currentPopStep === POP_ANIMATION_STEPS) {
playSound();
maybeClearPop();
}
}
// play an animation pop out
function playPopAnimationOut() {
var dimensions;
if (currentPopStep === 1) {
isPopPlaying = true;
currentPopScale = MAX_POP_SCALE;
playSound();
}
currentPopScale -= POP_PER_STEP;
dimensions = Vec3.multiply(currentSelectedDimensions, EasingFunctions.easeOutCubic(currentPopScale));
currentEmoji.edit("dimensions", dimensions);
currentPopStep++;
if (currentPopStep === POP_ANIMATION_STEPS) {
if (currentEmoji && currentEmoji.id) {
// currentEmoji.destroy();
// currentEmoji = new EntityMaker("avatar");
selectedEmoji = null;
ui.sendMessage({
app: "avimoji",
method: "updateEmojiPicks",
selectedEmoji: selectedEmoji
});
}
maybeClearPop();
}
}
// play an animatino coming in and then going out
function playPopAnimationInAndOut() {
var dimensions;
if (currentPopStep === 1) {
isPopPlaying = true;
currentPopScale = MAX_POP_SCALE;
playSound();
}
currentPopScale -= POP_PER_STEP;
dimensions = Vec3.multiply(currentSelectedDimensions, EasingFunctions.easeOutCubic(currentPopScale));
currentEmoji.edit("dimensions", dimensions);
currentPopStep++;
if (currentPopStep === POP_ANIMATION_STEPS) {
if (currentEmoji && currentEmoji.id) {
currentEmoji.destroy();
currentEmoji = new EntityMaker("avatar");
}
maybeClearPop();
Script.setTimeout(function () {
createEmoji(selectedEmoji);
}, DURATION);
}
}
// show all of the emojis instead of just the basic set
var allEmojis = Settings.getValue("avimoji/allEmojis", false);
function handleAllEmojis(data) {
allEmojis = data.allEmojis;
Settings.setValue("avimoji/allEmojis", allEmojis);
}

View file

@ -0,0 +1,3 @@
{
"baseImagesURL": "https://hifi-content.s3.amazonaws.com/milad/ROLC/mnt/d/ROLC_High-Fidelity/02_Organize/O_Projects/Repos/hifi-content/Prototyping/avimoji/appResources/appData/resources/images/emojis/png1024/"
}

View file

@ -0,0 +1,4 @@
emojis/png1024
emojis/svg-original
emojis/svg-variations
emojis/svgFiltered

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Some files were not shown because too many files have changed in this diff Show more