hooking up loading, flow, audio
This commit is contained in:
@@ -10,16 +10,23 @@ AFRAME.registerComponent('beat-loader', {
|
||||
},
|
||||
|
||||
update: function () {
|
||||
var challengeId = this.data.challengeId;
|
||||
if (!this.data.challengeId || !this.data.difficulty) { return; }
|
||||
this.loadBeats(this.data.challengeId, this.data.difficulty);
|
||||
},
|
||||
|
||||
/**
|
||||
* XHR.
|
||||
*/
|
||||
loadBeats: function (id, difficulty) {
|
||||
var el = this.el;
|
||||
var xhr;
|
||||
|
||||
if (!challengeId || !diffjculty) { return; }
|
||||
|
||||
// Load beats.
|
||||
let url = utils.getS3FileUrl(this.data.challengeId, `${this.data.difficulty}.json`);
|
||||
xhr = new XMLHttpRequest();
|
||||
el.emit('beatloaderstart');
|
||||
xhr.open('GET', utils.getS3FileUrl(challengeId, `${this.data.difficulty}.json`));
|
||||
console.log(`Fetching ${url}...`);
|
||||
xhr.open('GET', url);
|
||||
xhr.addEventListener('load', () => {
|
||||
this.handleBeats(JSON.parse(xhr.responseText));
|
||||
});
|
||||
@@ -30,16 +37,7 @@ AFRAME.registerComponent('beat-loader', {
|
||||
* TODO: Load the beat data into the game.
|
||||
*/
|
||||
handleBeats: function (beatData) {
|
||||
var el = this.el;
|
||||
|
||||
history.pushState(
|
||||
'',
|
||||
challenge.songName,
|
||||
updateQueryParam(window.location.href, 'challenge', this.data.challengeId)
|
||||
);
|
||||
|
||||
document.title = `Super Saber - ${challenge.songName}`;
|
||||
el.emit('beatloaderfinish');
|
||||
this.el.sceneEl.emit('beatloaderfinish', beatData, false);
|
||||
console.log('Finished loading challenge data.');
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
AFRAME.registerComponent('console-shortcuts', {
|
||||
play: function() {
|
||||
play: function () {
|
||||
window.$ = val => document.querySelector(val);
|
||||
window.$$ = val => document.querySelectorAll(val);
|
||||
window.$$$ = val => document.querySelector(`[${val}]`).getAttribute(val);
|
||||
window.$$$$ = val => document.querySelector(`[${val}]`).components[val];
|
||||
window.scene = this.el;
|
||||
window.state = this.el.systems.state.state;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
AFRAME.registerComponent('discolight', {
|
||||
schema: {
|
||||
color: { type: 'color' },
|
||||
speed: { default: 1.0 },
|
||||
},
|
||||
init: function() {
|
||||
this.color = new THREE.Color(this.data.color);
|
||||
this.hsl = this.color.getHSL();
|
||||
},
|
||||
tick: function(time, delta) {
|
||||
this.hsl.h += delta * 0.0001 * this.data.speed;
|
||||
if (this.hsl.l > 1.0) this.hsl.l = 0.0;
|
||||
this.color.setHSL(this.hsl.h, this.hsl.s, this.hsl.l);
|
||||
this.el.setAttribute('light', { color: this.color.getHex() });
|
||||
},
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
AFRAME.registerComponent('discotube', {
|
||||
schema: {
|
||||
speedX: { default: 1.0 },
|
||||
speedY: { default: 0.1 },
|
||||
},
|
||||
init: function() {
|
||||
this.material = this.el.object3D.children[0].material;
|
||||
},
|
||||
tick: function(time, delta) {
|
||||
if (this.material == null) return;
|
||||
this.material.map.offset.x -= delta * 0.0001 * this.data.speedX;
|
||||
this.material.map.offset.y -= delta * 0.0001 * this.data.speedY;
|
||||
},
|
||||
});
|
||||
20
src/components/history.js
Normal file
20
src/components/history.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Update window title and history.
|
||||
*/
|
||||
AFRAME.registerComponent('history', {
|
||||
schema: {
|
||||
challengeId: {type: 'string'},
|
||||
songName: {type: 'string'},
|
||||
songSubName: {type: 'string'}
|
||||
},
|
||||
|
||||
update: function () {
|
||||
const data = this.data;
|
||||
history.pushState(
|
||||
'',
|
||||
data.songName,
|
||||
updateQueryParam(window.location.href, 'challenge', data.challengeId)
|
||||
);
|
||||
document.title = `Super Saber - ${data.songName}`;
|
||||
}
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Play audio element on event.
|
||||
*/
|
||||
AFRAME.registerComponent('play-audio', {
|
||||
schema: {
|
||||
audio: { type: 'string' },
|
||||
event: { type: 'string' },
|
||||
volume: { type: 'number', default: 1 },
|
||||
},
|
||||
|
||||
multiple: true,
|
||||
|
||||
init: function() {
|
||||
var audio;
|
||||
audio = document.querySelector(this.data.audio);
|
||||
audio.volume = this.data.volume;
|
||||
|
||||
this.el.addEventListener(this.data.event, evt => {
|
||||
if (!audio.paused) {
|
||||
audio.pause();
|
||||
audio.currentTime = 0;
|
||||
}
|
||||
audio.play();
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
AFRAME.registerComponent('play-button', {
|
||||
init: function() {
|
||||
var el = this.el;
|
||||
|
||||
el.addEventListener('click', () => {
|
||||
el.sceneEl.emit('playbuttonclick');
|
||||
});
|
||||
|
||||
el.sceneEl.addEventListener('youtubefinished', evt => {
|
||||
el.object3D.visible = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
43
src/components/play-sound.js
Normal file
43
src/components/play-sound.js
Normal file
@@ -0,0 +1,43 @@
|
||||
var SoundPool = require('../lib/soundpool');
|
||||
|
||||
AFRAME.registerSystem('play-sound', {
|
||||
init: function () {
|
||||
this.lastSoundPlayed = '';
|
||||
this.lastSoundPlayedTime = 0;
|
||||
this.pools = {};
|
||||
},
|
||||
|
||||
createPool: function (sound, volume) {
|
||||
if (this.pools[sound]) { return; }
|
||||
this.pools[sound] = new SoundPool(sound, volume);
|
||||
},
|
||||
|
||||
playSound: function (sound, volume) {
|
||||
this.createPool(sound, volume);
|
||||
this.pools[sound].play();
|
||||
|
||||
this.lastSoundPlayed = sound;
|
||||
this.lastSoundTime = this.el.time;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Play sound on event.
|
||||
*/
|
||||
AFRAME.registerComponent('play-sound', {
|
||||
schema: {
|
||||
enabled: {default: true},
|
||||
event: {type: 'string'},
|
||||
sound: {type: 'string'},
|
||||
volume: {type: 'number', default: 1}
|
||||
},
|
||||
|
||||
multiple: true,
|
||||
|
||||
init: function () {
|
||||
this.el.addEventListener(this.data.event, evt => {
|
||||
if (!this.data.enabled) { return; }
|
||||
this.system.playSound(this.data.sound, this.data.volume);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -31,6 +31,7 @@ AFRAME.registerComponent('preview-song', {
|
||||
},
|
||||
|
||||
update: function (oldData) {
|
||||
// Stop.
|
||||
if (oldData.challengeId && !this.data.challengeId) {
|
||||
if (this.animation) { this.animation.pause(); }
|
||||
this.audio.pause();
|
||||
|
||||
@@ -14,9 +14,7 @@ AFRAME.registerComponent('recenter', {
|
||||
this.checkInViewAfterRecenter = this.checkInViewAfterRecenter.bind(this);
|
||||
// Delay to make sure we have a valid pose.
|
||||
sceneEl.addEventListener('enter-vr', () => {
|
||||
setTimeout(() => {
|
||||
this.recenter();
|
||||
}, 100);
|
||||
setTimeout(() => { this.recenter(); }, 100);
|
||||
});
|
||||
// User can also recenter the menu manually.
|
||||
sceneEl.addEventListener('menudown', () => {
|
||||
@@ -49,7 +47,7 @@ AFRAME.registerComponent('recenter', {
|
||||
checkInViewAfterRecenter: function() {
|
||||
var camera = this.el.sceneEl.camera;
|
||||
var frustum = this.frustum;
|
||||
var menu = document.querySelector('#menu');
|
||||
var menu = this.el;
|
||||
var menuPosition = this.menuPosition;
|
||||
camera.updateMatrix();
|
||||
camera.updateMatrixWorld();
|
||||
|
||||
39
src/components/song.js
Normal file
39
src/components/song.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Active challenge song / audio.
|
||||
*/
|
||||
AFRAME.registerComponent('song', {
|
||||
schema: {
|
||||
challengeId: {default: ''},
|
||||
isPlaying: {default: false}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
// Use audio element for audioanalyser.
|
||||
this.audio = document.createElement('audio');
|
||||
this.audio.setAttribute('id', 'song');
|
||||
this.el.sceneEl.appendChild(this.audio);
|
||||
},
|
||||
|
||||
update: function (oldData) {
|
||||
var el = this.el;
|
||||
var data = this.data;
|
||||
|
||||
// Changed challenge.
|
||||
if (data.challengeId !== oldData.challengeId) {
|
||||
let songUrl = utils.getS3FileUrl(data.challengeId, 'song.ogg');
|
||||
this.audio.currentTime = 0;
|
||||
this.audio.src = data.challengeId ? songUrl : '';
|
||||
console.log(`Playing ${songUrl}...`);
|
||||
}
|
||||
|
||||
// Keep playback state up to date.
|
||||
if ((data.isPlaying && data.challengeId) && this.audio.paused) {
|
||||
this.audio.play();
|
||||
return;
|
||||
} else if ((!data.isPlaying || !data.challengeId) && !this.audio.paused) {
|
||||
this.audio.pause();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -5,29 +5,25 @@
|
||||
<script src="vendor/aframe.dev.js"></script>
|
||||
<script src="build/build.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<audio id="hoverSound" src="/assets/sounds/hover.ogg"></audio>
|
||||
|
||||
<a-scene bind__beat-loader="challengeId: challenge.id"
|
||||
bind__preview-song="challengeId: menuSelectedChallenge.id"
|
||||
challenge-loader
|
||||
<a-scene bind__beat-loader="challengeId: challenge.id; difficulty: challenge.difficulty"
|
||||
bind__preview-song="challengeId: menuSelectedChallenge.id; previewStartTime: menuSelectedChallenge.previewStartTime"
|
||||
bind__song="challengeId: challenge.id; isPlaying: !menu.active && !challenge.isLoading"
|
||||
console-shortcuts
|
||||
search>
|
||||
<a-assets timeout="10000">
|
||||
<a-mixin id="raycaster" raycaster="objects: [raycastable]; far: 2"></a-mixin>
|
||||
<audio id="hoverSound" src="/assets/sounds/hover.ogg"></audio>
|
||||
<img id="gridImg" src="assets/img/grid.png">
|
||||
<img id="playImg" src="assets/img/play.png">
|
||||
<img id="resultImg" src="assets/img/result.png">
|
||||
<img id="gridImg" src="assets/img/grid.png">
|
||||
<img id="sliceImg" src="assets/img/slice.png">
|
||||
<a-mixin id="slice" slice9="color: #050505; src: #sliceImg; left: 50; right: 52; top: 50; bottom: 52; padding: 0.04"></a-mixin>
|
||||
<a-mixin id="font" text="font: exo2semibold; letterSpacing: -1"></a-mixin>
|
||||
<a-mixin id="raycaster" raycaster="objects: [raycastable]; far: 2"></a-mixin>
|
||||
<a-mixin id="slice" slice9="color: #050505; src: #sliceImg; left: 50; right: 52; top: 50; bottom: 52; padding: 0.04"></a-mixin>
|
||||
<a-mixin id="textFont" text="font: exo2semibold; letterSpacing: -1"></a-mixin>
|
||||
</a-assets>
|
||||
|
||||
<a-entity id="dustParticles" particle-system="maxAge: 100; positionSpread: 5 5 5; type: 2; rotationAxis: x; rotationAngle: 0.001; accelerationValue: 0.001 0.001 0.001; accelerationSpread: 0.001 0.001 0.001; velocityValue: 0.001 0.001 0.001; velocitySpread: 0.0125 0.0125 0.0125; color: #ffffff; size: 0.1; opacity: 0.85; direction: 0; particleCount: 150; texture: assets/img/smokeparticle.png"></a-entity>
|
||||
|
||||
<a-entity id="container">
|
||||
<a-entity id="container" recenter>
|
||||
{% include './templates/environment.html' %}
|
||||
{% include './templates/gameUi.html' %}
|
||||
{% include './templates/menu.html' %}
|
||||
@@ -39,7 +35,8 @@
|
||||
<a-entity id="rightHand" controller="hand: right"></a-entity>
|
||||
</a-entity>
|
||||
|
||||
<a-entity id="mouseCursor" mixin="raycaster" cursor="rayOrigin: mouse" debug-cursor bind__isPlaying="!inVR"></a-entity>
|
||||
<a-entity id="mouseCursor" mixin="raycaster" cursor="rayOrigin: mouse" debug-cursor
|
||||
bind__raycaster="enabled: !inVR"></a-entity>
|
||||
</a-scene>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
module.exports = function SoundPool (src, volume, size) {
|
||||
module.exports = function SoundPool (src, volume) {
|
||||
var currSound = 0;
|
||||
var i;
|
||||
var pool = [];
|
||||
var sound;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
sound = new Audio(src);
|
||||
sound.volume = volume;
|
||||
sound.load();
|
||||
pool.push(sound);
|
||||
}
|
||||
sound = new Audio(src);
|
||||
sound.volume = volume;
|
||||
pool.push(sound);
|
||||
|
||||
return {
|
||||
play: function () {
|
||||
// Dynamic size pool.
|
||||
if (pool[currSound].currentTime !== 0 || !pool[currSound].ended) {
|
||||
sound = new Audio(src);
|
||||
sound.volume = volume;
|
||||
pool.push(sound);
|
||||
currSound++;
|
||||
}
|
||||
|
||||
if (pool[currSound].currentTime === 0 || pool[currSound].ended) {
|
||||
pool[currSound].play();
|
||||
}
|
||||
currSound = (currSound + 1) % size;
|
||||
currSound = (currSound + 1) % pool.length;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,79 +9,95 @@ AFRAME.registerState({
|
||||
challenge: {
|
||||
author: '',
|
||||
difficulty: '',
|
||||
downloads: '',
|
||||
downloadsText: '',
|
||||
id: AFRAME.utils.getUrlParameter('challenge'),
|
||||
image: '',
|
||||
isLoading: false,
|
||||
songName: '',
|
||||
songSubName: '',
|
||||
songSubName: ''
|
||||
},
|
||||
inVR: false,
|
||||
maxStreak: 0,
|
||||
menu: {
|
||||
active: true
|
||||
active: true,
|
||||
playButtonText: 'Play'
|
||||
},
|
||||
menuDifficulties: [],
|
||||
menuSelectedChallenge: {
|
||||
author: '',
|
||||
difficulty: '',
|
||||
downloads: '',
|
||||
downloadsText: '',
|
||||
id: '',
|
||||
image: ''
|
||||
image: '',
|
||||
songName: '',
|
||||
songSubName: ''
|
||||
},
|
||||
score: {
|
||||
maxStreak: 0,
|
||||
score: 0,
|
||||
streak: 0
|
||||
},
|
||||
playButtonText: 'Play',
|
||||
score: 0,
|
||||
scoreText: '',
|
||||
// screen: keep track of layers or depth. Like breadcrumbs.
|
||||
screen: hasInitialChallenge ? 'challenge' : 'home',
|
||||
screenHistory: [],
|
||||
searchResults: [],
|
||||
streak: 0
|
||||
searchResults: []
|
||||
},
|
||||
|
||||
handlers: {
|
||||
beatloaderfinish: function (state, payload) {
|
||||
beatloaderfinish: (state) => {
|
||||
state.challenge.isLoading = false;
|
||||
},
|
||||
|
||||
beatloaderstart: function (state, payload) {
|
||||
beatloaderstart: (state) => {
|
||||
state.challenge.isLoading = true;
|
||||
},
|
||||
|
||||
challengeset: function (state, payload) {
|
||||
state.challenge.id = payload.challengeId;
|
||||
state.score = 0;
|
||||
state.streak = 0;
|
||||
state.maxStreak = 0;
|
||||
state.menu.active = false;
|
||||
state.menuSelectedChallenge.id = '';
|
||||
setScreen(state, 'challenge');
|
||||
},
|
||||
|
||||
/**
|
||||
* Song clicked from menu.
|
||||
*/
|
||||
menuchallengeselect: function (state, id) {
|
||||
menuchallengeselect: (state, id) => {
|
||||
// Copy from challenge store populated from search results.
|
||||
let challengeData = challengeDataStore[id];
|
||||
Object.assign(state.menuSelectedChallenge, challengeData);
|
||||
state.menuSelectedChallenge.id = id;
|
||||
|
||||
state.menuDifficulties.length = 0;
|
||||
for (let i = 0; i < challengeData.difficulties.length; i++) {
|
||||
state.menuDifficulties.push(challengeData.difficulties[i]);
|
||||
}
|
||||
|
||||
state.menuSelectedChallenge.image = utils.getS3FileUrl(id, 'image.jpg');
|
||||
state.menuSelectedChallenge.downloadsText = `${challengeData.downloads} Plays`;
|
||||
|
||||
// Choose first difficulty.
|
||||
// TODO: Default and order by easiest to hardest.
|
||||
state.menuSelectedChallenge.difficulty = state.menuDifficulties[0];
|
||||
},
|
||||
|
||||
menudifficultyselect: function (state, difficulty) {
|
||||
menudifficultyselect: (state, difficulty) => {
|
||||
state.menuSelectedChallenge.difficulty = difficulty;
|
||||
},
|
||||
|
||||
playbuttonclick: function (state) {
|
||||
/**
|
||||
* Start challenge.
|
||||
* Transfer staged challenge to the active challenge.
|
||||
*/
|
||||
playbuttonclick: (state) => {
|
||||
// Reset score.
|
||||
state.score.maxStreak = 0;
|
||||
state.score.score = 0;
|
||||
state.score.streak = 0;
|
||||
|
||||
// Set challenge. `beat-loader` is listening.
|
||||
Object.assign(state.challenge, state.menuSelectedChallenge);
|
||||
|
||||
// Reset menu.
|
||||
state.menu.active = false;
|
||||
state.menuSelectedChallenge.id = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Update search results. Will automatically render using `bind-for` (menu.html).
|
||||
*/
|
||||
searchresults: function (state, payload) {
|
||||
searchresults: (state, payload) => {
|
||||
var i;
|
||||
state.searchResults.length = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
@@ -93,21 +109,23 @@ AFRAME.registerState({
|
||||
state.searchResults.__dirty = true;
|
||||
},
|
||||
|
||||
togglemenu: function (state) {
|
||||
togglemenu: (state) => {
|
||||
state.menu.active = !state.menu.active;
|
||||
},
|
||||
|
||||
'enter-vr': function (state, payload) {
|
||||
'enter-vr': (state) => {
|
||||
state.inVR = true;
|
||||
},
|
||||
|
||||
'exit-vr': function (state, payload) {
|
||||
'exit-vr': (state) => {
|
||||
state.inVR = false;
|
||||
}
|
||||
},
|
||||
|
||||
computeState: function (state) {
|
||||
state.scoreText = `Streak: ${state.streak} / Max Streak: ${state.maxStreak} / Score: ${state.score}`;
|
||||
/**
|
||||
* Post-process the state after each action.
|
||||
*/
|
||||
computeState: (state) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<a-entity id="sky" cubemap="folder: /assets/img/env/space/"></a-entity>
|
||||
<a-entity id="sky" cubemap="folder: assets/img/env/space/"></a-entity>
|
||||
|
||||
<a-entity id="skyFade"
|
||||
bind__visible="menu.active"
|
||||
@@ -20,3 +20,5 @@
|
||||
<!-- Default lights -->
|
||||
<a-entity light="type: ambient; color: #BBB"></a-entity>
|
||||
<a-entity light="type: directional; color: #FFF; intensity: 0.6" position="-0.5 1 1"></a-entity>
|
||||
|
||||
<a-entity id="dustParticles" particle-system="maxAge: 100; positionSpread: 5 5 5; type: 2; rotationAxis: x; rotationAngle: 0.001; accelerationValue: 0.001 0.001 0.001; accelerationSpread: 0.001 0.001 0.001; velocityValue: 0.001 0.001 0.001; velocitySpread: 0.0125 0.0125 0.0125; color: #ffffff; size: 0.1; opacity: 0.85; direction: 0; particleCount: 150; texture: assets/img/smokeparticle.png"></a-entity>
|
||||
|
||||
@@ -1,36 +1,30 @@
|
||||
<a-entity id="gameInfo"
|
||||
bind__visible="isChallengeScreen"
|
||||
bind__visible="!menu.active && !!challenge.id && !challenge.isLoading"
|
||||
position="0 0 -80"
|
||||
scale="100 100 100">
|
||||
<a-entity mixin="textFont"
|
||||
text="align:right; width:1.25; value:SCORE; color:#d6d955; anchor:right; letterSpacing:-2"
|
||||
position="-0.089 0.183 -1.01"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="align: right; width: 1.25; value: SCORE; color: #d6d955; anchor: right; letterSpacing: -2"
|
||||
position="-0.089 0.183 -1.01"></a-entity>
|
||||
<a-entity mixin="textFont"
|
||||
text="width:0.9; value:STREAK; color:#f95895; letterSpacing:-2; anchor:left"
|
||||
position="0.097 0.183 -1.01"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="width: 0.9; value: STREAK; color: #f95895; letterSpacing: -2; anchor: left"
|
||||
position="0.097 0.183 -1.01"></a-entity>
|
||||
<a-entity mixin="textFont"
|
||||
text="width:0.7; value:MAX; color:#f95895; anchor:left; letterSpacing:-2"
|
||||
position="0.101 0.1 -1.01"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="width: 0.7; value: MAX; color: #f95895; anchor: left; letterSpacing: -2"
|
||||
position="0.101 0.1 -1.01"></a-entity>
|
||||
|
||||
<a-entity id="score"
|
||||
bind__text="value: score"
|
||||
bind__text="value: score.score"
|
||||
mixin="textFont"
|
||||
text="align:right; width:2; color:#feffc1; anchor:right; letterSpacing:-2"
|
||||
position="-0.08 0.132 -1"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="align: right; width: 2; color: #feffc1; anchor: right; letterSpacing: -2"
|
||||
position="-0.08 0.132 -1"></a-entity>
|
||||
<a-entity id="streak"
|
||||
bind__text="value: streak"
|
||||
bind__text="value: score.streak"
|
||||
mixin="textFont"
|
||||
text="width:1.25; color:#ffbdd6; anchor:left; letterSpacing:-2"
|
||||
position="0.098 0.144 -1"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="width: 1.25; color: #ffbdd6; anchor: left; letterSpacing: -2"
|
||||
position="0.098 0.144 -1"></a-entity>
|
||||
<a-entity id="maxStreak"
|
||||
bind__text="value: maxStreak"
|
||||
bind__text="value: score.maxStreak"
|
||||
mixin="textFont"
|
||||
text="width:0.8; color:#ffbdd6; anchor:left; letterSpacing:-2"
|
||||
position="0.1 0.074 -1"
|
||||
bind__visible="!challenge.isLoading"></a-entity>
|
||||
text="width: 0.8; color: #ffbdd6; anchor: left; letterSpacing: -2"
|
||||
position="0.1 0.074 -1"></a-entity>
|
||||
</a-entity>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
geometry="primitive: plane; width: 0.8; height: 0.1"
|
||||
material="shader: flat; color: #111"
|
||||
position="0 -0.13 -0.01"
|
||||
play-audio="event: mouseenter; audio: #hoverSound; volume: 0.03"
|
||||
play-sound="event: mouseenter; sound: #hoverSound; volume: 0.03"
|
||||
animation__mouseenter="property: material.color; from: #111; to: #666; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150"
|
||||
animation__mouseleave="property: material.color; from: #666; to: #111; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150"
|
||||
raycastable></a-entity>
|
||||
@@ -50,7 +50,7 @@
|
||||
geometry="primitive: plane; width: 0.3; height: 0.1"
|
||||
material="shader: flat; color: #111"
|
||||
position="-0.4 -0.005 0"
|
||||
play-audio="event: mouseenter; audio: #hoverSound; volume: 0.03"
|
||||
play-sound="event: mouseenter; sound: #hoverSound; volume: 0.03"
|
||||
animation__mouseenter="property: material.color; from: #111; to: #666; startEvents: mouseenter; pauseEvents: mouseleave; dur: 150"
|
||||
animation__mouseleave="property: material.color; from: #666; to: #111; startEvents: mouseleave; pauseEvents: mouseenter; dur: 150"
|
||||
bind-toggle__raycastable="menu.active && !!menuSelectedChallenge.id"></a-entity>
|
||||
@@ -75,10 +75,11 @@
|
||||
<a-entity class="menuSelectedChallengeDownloads" mixin="textFont" text="align: center; color: #FFF; wrapCount: 45" position="0 -0.09 0" bind__text="value: menuSelectedChallenge.downloadsText"></a-entity>
|
||||
</a-entity>
|
||||
|
||||
<a-plane id="play"
|
||||
<a-plane id="playButton"
|
||||
play-button
|
||||
play-audio="event: mouseenter; audio: #hoverSound; volume: 0.03"
|
||||
play-sound="event: mouseenter; sound: #hoverSound; volume: 0.03"
|
||||
position="0 -0.25 0"
|
||||
proxy-event="event: click; to: a-scene; as: playbuttonclick"
|
||||
material="shader: flat; src: #playImg; transparent: true; color: #BBB"
|
||||
width="0.256"
|
||||
height="0.128"
|
||||
|
||||
Reference in New Issue
Block a user