working version but taking a snapshot of added emoji code before removing for handoff
|
@ -1,7 +0,0 @@
|
|||
Image {
|
||||
width: 36
|
||||
height: 36
|
||||
anchors.centerIn: parent
|
||||
source: emojiBaseURL + EmojiList.emojiList[0].code[0] + ".png"
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
//
|
||||
// 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);
|
||||
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
//
|
||||
// EmoteAppBar.qml
|
||||
//
|
||||
// Created by Zach Fox on 2019-07-08
|
||||
// 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 TabletScriptingInterface 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
color: simplifiedUI.colors.white
|
||||
anchors.fill: parent
|
||||
|
||||
property int originalWidth: 48
|
||||
property int hoveredWidth: 480
|
||||
property int requestedWidth
|
||||
|
||||
property bool overEmoteButton: false
|
||||
property bool overEmojiButton: false
|
||||
|
||||
onRequestedWidthChanged: {
|
||||
root.requestNewWidth(root.requestedWidth);
|
||||
}
|
||||
|
||||
Behavior on requestedWidth {
|
||||
enabled: true
|
||||
SmoothedAnimation { duration: 220 }
|
||||
}
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
}
|
||||
|
||||
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 {
|
||||
id: mainEmojiContainer
|
||||
z: 2
|
||||
color: simplifiedUI.colors.darkBackground
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
height: parent.height
|
||||
width: root.originalWidth
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "😊"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenterOffset: -2
|
||||
anchors.verticalCenterOffset: -2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
size: 26
|
||||
color: simplifiedUI.colors.text.almostWhite
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: drawerContainer
|
||||
z: 1
|
||||
color: simplifiedUI.colors.white
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
height: parent.height
|
||||
width: root.hoveredWidth
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
text: "Emotes go here."
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
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) {
|
||||
switch (message.method) {
|
||||
default:
|
||||
console.log('EmoteAppBar.qml: Unrecognized message from JS');
|
||||
break;
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
signal requestNewWidth(int newWidth);
|
||||
}
|
|
@ -18,6 +18,7 @@ import PerformanceEnums 1.0
|
|||
|
||||
Flickable {
|
||||
property string avatarNametagMode: Settings.getValue("simplifiedNametag/avatarNametagMode", "on")
|
||||
property bool emoteIndicatorVisible: true;
|
||||
id: root
|
||||
contentWidth: parent.width
|
||||
contentHeight: generalColumnLayout.height
|
||||
|
@ -27,6 +28,10 @@ Flickable {
|
|||
sendNameTagInfo({method: 'handleAvatarNametagMode', avatarNametagMode: root.avatarNametagMode, source: "SettingsApp.qml"});
|
||||
}
|
||||
|
||||
onEmoteIndicatorVisible: {
|
||||
sendEmoteVisible({method: 'emoteIndicatorVisible', emoteIndicatorVisible: root.emoteIndicatorVisible, source: "SettingsApp.qml"})
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.contentX = 0;
|
||||
|
@ -197,20 +202,62 @@ Flickable {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Camera
|
||||
Connections {
|
||||
target: Camera
|
||||
|
||||
onModeUpdated: {
|
||||
if (Camera.mode === "first person") {
|
||||
firstPerson.checked = true
|
||||
} else if (Camera.mode === "third person") {
|
||||
thirdPerson.checked = true
|
||||
onModeUpdated: {
|
||||
if (Camera.mode === "first person") {
|
||||
firstPerson.checked = true
|
||||
} else if (Camera.mode === "third person") {
|
||||
thirdPerson.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: emoteContainer
|
||||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
ColumnLayout {
|
||||
id: emoteRadioButtonGroup
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
|
||||
|
||||
HifiStylesUit.GraphikSemiBold {
|
||||
id: emoteTitle
|
||||
text: "Emote"
|
||||
Layout.maximumWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
color: simplifiedUI.colors.text.white
|
||||
}
|
||||
|
||||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: emoteOn
|
||||
text: "Emote On"
|
||||
checked: root.emoteIndicatorVisible
|
||||
onClicked: {
|
||||
root.emoteIndicatorVisible = !root.emoteIndicatorVisible;
|
||||
}
|
||||
}
|
||||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: emoteOff
|
||||
text: "Emote Off"
|
||||
checked: !root.emoteIndicatorVisible
|
||||
onClicked: {
|
||||
root.emoteIndicatorVisible = !root.emoteIndicatorVisible;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: logoutContainer
|
||||
Layout.preferredWidth: parent.width
|
||||
|
@ -248,4 +295,5 @@ Flickable {
|
|||
}
|
||||
|
||||
signal sendNameTagInfo(var message);
|
||||
signal sendEmoteVisible(var message);
|
||||
}
|
||||
|
|
|
@ -1,463 +0,0 @@
|
|||
/*
|
||||
|
||||
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
|
||||
// *************************************
|
||||
|
||||
})();
|
|
@ -1,4 +0,0 @@
|
|||
emojis/png1024
|
||||
emojis/svg-original
|
||||
emojis/svg-variations
|
||||
emojis/svgFiltered
|
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 28 KiB |