keyboard restyling (fixes #124)
This commit is contained in:
BIN
assets/img/keyboard/keyboard-hover.png
Normal file
BIN
assets/img/keyboard/keyboard-hover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
assets/img/keyboard/keyboard.png
Normal file
BIN
assets/img/keyboard/keyboard.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB |
35
package-lock.json
generated
35
package-lock.json
generated
@@ -155,36 +155,6 @@
|
||||
"resolved": "https://registry.npmjs.org/aframe-state-component/-/aframe-state-component-6.3.1.tgz",
|
||||
"integrity": "sha512-L+64JKz9mQW6f6ZY10OyJwyT2QHx5u9sh4xlNS1eKJD8j/BgYYvKie4rlypHxZwzp+5n9Ajy5a6LsnMynuhlOA=="
|
||||
},
|
||||
"aframe-super-keyboard": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/aframe-super-keyboard/-/aframe-super-keyboard-2.0.2.tgz",
|
||||
"integrity": "sha512-KaqZFjczuFdwL2i3CB9S2A73rzx6G+KpaODwgzozeAeEHvyLQCYpfkyXN4NcwBfnd11d0uHYDxpl3KzyIDzndg==",
|
||||
"requires": {
|
||||
"uglify-js": "^3.3.23",
|
||||
"uglifyjs": "^2.4.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.4.9",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
||||
"integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
|
||||
"requires": {
|
||||
"commander": "~2.17.1",
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"aframe-thumb-controls-component": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aframe-thumb-controls-component/-/aframe-thumb-controls-component-1.1.0.tgz",
|
||||
@@ -10355,11 +10325,6 @@
|
||||
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
|
||||
"optional": true
|
||||
},
|
||||
"uglifyjs": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npmjs.org/uglifyjs/-/uglifyjs-2.4.11.tgz",
|
||||
"integrity": "sha1-NEDWTgRXWViVJEGOtkHGi7kNET4="
|
||||
},
|
||||
"uglifyjs-webpack-plugin": {
|
||||
"version": "0.4.6",
|
||||
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"aframe-proxy-event-component": "^2.1.0",
|
||||
"aframe-slice9-component": "^1.0.0",
|
||||
"aframe-state-component": "^6.2.0",
|
||||
"aframe-super-keyboard": "2.0.2",
|
||||
"aframe-thumb-controls-component": "^1.1.0",
|
||||
"algoliasearch": "^3.29.0",
|
||||
"ansi-html": "0.0.7",
|
||||
|
||||
@@ -45,9 +45,9 @@ AFRAME.registerComponent('gpu-preloader', {
|
||||
},
|
||||
|
||||
preloadKeyboard: function () {
|
||||
const keyboard = document.getElementById('keyboard')
|
||||
const kbImg = keyboard.components['super-keyboard'].kbImg;
|
||||
this.preloadTexture(kbImg.getObject3D('mesh').material.map);
|
||||
const keyboard = document.getElementById('keyboard').components['super-keyboard'];
|
||||
this.preloadTexture(keyboard.kbImg.getObject3D('mesh').material.map);
|
||||
this.preloadTexture(keyboard.keyColorPlane.getObject3D('mesh').material.map);
|
||||
},
|
||||
|
||||
preloadMineEnvMaps: function () {
|
||||
|
||||
586
src/components/super-keyboard.js
Normal file
586
src/components/super-keyboard.js
Normal file
@@ -0,0 +1,586 @@
|
||||
/* global AFRAME */
|
||||
var KEYBOARDS = {
|
||||
supersaber: {wrapCount: 30, inputOffsetY: 0.008, inputOffsetX: 0.08, img: 'keyboard.png', hoverImg: 'keyboard-hover.png', layout: [{"key":"1", "x":0.014, "y":0.024, "w":0.094, "h":0.183}, {"key":"2", "x":0.108, "y":0.024, "w":0.094, "h":0.183}, {"key":"3", "x":0.203, "y":0.024, "w":0.095, "h":0.183}, {"key":"4", "x":0.299, "y":0.024, "w":0.094, "h":0.183}, {"key":"5", "x":0.394, "y":0.024, "w":0.093, "h":0.183}, {"key":"6", "x":0.487, "y":0.024, "w":0.095, "h":0.183}, {"key":"7", "x":0.583, "y":0.024, "w":0.093, "h":0.183}, {"key":"8", "x":0.677, "y":0.024, "w":0.095, "h":0.183}, {"key":"9", "x":0.772, "y":0.024, "w":0.093, "h":0.183}, {"key":"0", "x":0.866, "y":0.024, "w":0.093, "h":0.183}, {"key":"q", "x":0.014, "y":0.215, "w":0.094, "h":0.183}, {"key":"w", "x":0.108, "y":0.215, "w":0.094, "h":0.183}, {"key":"e", "x":0.203, "y":0.215, "w":0.095, "h":0.183}, {"key":"r", "x":0.299, "y":0.215, "w":0.094, "h":0.183}, {"key":"t", "x":0.394, "y":0.215, "w":0.093, "h":0.183}, {"key":"y", "x":0.487, "y":0.215, "w":0.095, "h":0.183}, {"key":"i", "x":0.677, "y":0.215, "w":0.095, "h":0.183}, {"key":"u", "x":0.583, "y":0.215, "w":0.093, "h":0.183}, {"key":"o", "x":0.772, "y":0.215, "w":0.093, "h":0.183}, {"key":"p", "x":0.866, "y":0.215, "w":0.093, "h":0.183}, {"key":"a", "x":0.063, "y":0.405, "w":0.094, "h":0.183}, {"key":"s", "x":0.158, "y":0.405, "w":0.094, "h":0.183}, {"key":"d", "x":0.253, "y":0.405, "w":0.095, "h":0.183}, {"key":"f", "x":0.349, "y":0.405, "w":0.094, "h":0.183}, {"key":"g", "x":0.443, "y":0.405, "w":0.093, "h":0.183}, {"key":"h", "x":0.537, "y":0.405, "w":0.095, "h":0.183}, {"key":"j", "x":0.633, "y":0.405, "w":0.092, "h":0.183}, {"key":"k", "x":0.726, "y":0.405, "w":0.095, "h":0.183}, {"key":"l", "x":0.821, "y":0.405, "w":0.093, "h":0.183}, {"key":"z", "x":0.111, "y":0.598, "w":0.093, "h":0.181}, {"key":"x", "x":0.205, "y":0.598, "w":0.095, "h":0.181}, {"key":"c", "x":0.301, "y":0.598, "w":0.095, "h":0.181}, {"key":"v", "x":0.396, "y":0.598, "w":0.093, "h":0.181}, {"key":"b", "x":0.49, "y":0.598, "w":0.094, "h":0.181}, {"key":"n", "x":0.585, "y":0.598, "w":0.094, "h":0.181}, {"key":"m", "x":0.68, "y":0.598, "w":0.093, "h":0.181}, {"key":"Backspace", "x":0.777, "y":0.598, "w":0.137, "h":0.181}, {"key":" ", "x":0.297, "y":0.788, "w":0.381, "h":0.201}, {"key":"Escape", "x":0.013, "y":0.797, "w":0.137, "h":0.181}, {"key":"Insert", "x":0.014, "y":-0.001, "w":0.01, "h":0.005}]}
|
||||
};
|
||||
|
||||
if (typeof AFRAME === 'undefined') {
|
||||
throw new Error('Component attempted to register before AFRAME was available.');
|
||||
}
|
||||
|
||||
var FontFactors = {
|
||||
roboto: 17,
|
||||
aileronsemibold: 20,
|
||||
dejavu: 20.5,
|
||||
exo2bold: 20,
|
||||
exo2semibold: 20.3,
|
||||
kelsonsans: 22.8,
|
||||
monoid: 19.5,
|
||||
mozillavr: 9.5,
|
||||
sourcecodepro: 20.3
|
||||
};
|
||||
|
||||
AFRAME.registerComponent('super-keyboard', {
|
||||
schema: {
|
||||
align: {default: 'left', oneOf: ['left', 'center', 'right']},
|
||||
blinkingSpeed: {type: 'int', default: 400},
|
||||
filters: {type: 'array'},
|
||||
// roboto aileronsemibold dejavu exo2bold exo2semibold kelsonsans monoid sourcecodepro
|
||||
font: {default: 'aileronsemibold'},
|
||||
hand: {type: 'selector'},
|
||||
imagePath: {default: '.'},
|
||||
injectToRaycasterObjects: {default: true},
|
||||
inputColor: {type: 'color', default: '#6699ff'},
|
||||
interval: {type: 'int', default: 50},
|
||||
keyBgColor: {type: 'color', default: '#000'},
|
||||
keyColor: {type: 'color', default: '#6699ff'},
|
||||
keyHoverColor: {type: 'color', default: '#1A407F'},
|
||||
keyPressColor: {type: 'color', default: '#5290F6'},
|
||||
label: {type: 'string', default: ''},
|
||||
labelColor: {type: 'color', default: '#aaa'},
|
||||
maxLength: {type: 'int', default: 0},
|
||||
model: {default: 'basic'},
|
||||
show: {default: true},
|
||||
value: {type: 'string', default: ''},
|
||||
width: {default: 0.8}
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.el.addEventListener('click', this.click.bind(this));
|
||||
this.changeEventDetail = {};
|
||||
this.textInputObject = {};
|
||||
|
||||
this.keys = null;
|
||||
this.focused = false;
|
||||
this.keyHover = null;
|
||||
this.prevCheckTime = null;
|
||||
this.shift = false;
|
||||
|
||||
this.rawValue = this.data.value;
|
||||
this.defaultValue = this.data.value;
|
||||
|
||||
this.userFilterFunc = null;
|
||||
this.intervalId = 0;
|
||||
|
||||
// Create keyboard image.
|
||||
this.kbImg = document.createElement('a-entity');
|
||||
this.kbImg.classList.add('keyboardRaycastable');
|
||||
this.kbImg.classList.add('superKeyboardImage');
|
||||
this.kbImg.addEventListener('raycaster-intersected', this.hover.bind(this));
|
||||
this.kbImg.addEventListener('raycaster-intersected-cleared', this.blur.bind(this));
|
||||
this.el.appendChild(this.kbImg);
|
||||
|
||||
// Create label.
|
||||
this.label = document.createElement('a-entity');
|
||||
this.label.setAttribute('text', {
|
||||
align: 'center',
|
||||
font: this.data.font,
|
||||
baseline: 'bottom',
|
||||
lineHeight: 40,
|
||||
value: this.data.label,
|
||||
color: this.data.labelColor,
|
||||
width: this.data.width,
|
||||
wrapCount: 30});
|
||||
this.el.appendChild(this.label);
|
||||
|
||||
// Create input.
|
||||
this.textInput = document.createElement('a-entity');
|
||||
this.textInput.setAttribute('text', {
|
||||
align: this.data.align,
|
||||
font: this.data.font,
|
||||
value: this.data.value,
|
||||
color: this.data.inputColor,
|
||||
width: this.data.width,
|
||||
wrapCount: 20
|
||||
});
|
||||
this.el.appendChild(this.textInput);
|
||||
|
||||
this.cursor = document.createElement('a-entity');
|
||||
this.cursor.object3D.position.set(0, 0, 0.001);
|
||||
this.cursor.setAttribute('material', {shader: 'flat', color: this.data.inputColor});
|
||||
this.textInput.appendChild(this.cursor);
|
||||
this.cursorUpdated = false;
|
||||
|
||||
this.keyBgColor = new THREE.Color();
|
||||
this.keyHoverColor = new THREE.Color();
|
||||
this.keyPressColor = new THREE.Color();
|
||||
|
||||
var self = this;
|
||||
document.addEventListener('keydown', function (ev) {
|
||||
if (ev.key === 't') {
|
||||
var ss = '';
|
||||
var s = 'abcdefghijklmopqrstuvQWIEUTGASDLIGKBXACQWETL102394676457';
|
||||
var l = Math.floor(Math.random() * 20);
|
||||
for (var i = 0; i < l; i++) ss += s[Math.floor(Math.random() * s.length)];
|
||||
self.el.setAttribute('super-keyboard', {value: ss});
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('show', this.open.bind(this));
|
||||
|
||||
this.hand = null;
|
||||
this.handListenersSet = false;
|
||||
this.raycaster = null;
|
||||
},
|
||||
|
||||
update: function (oldData) {
|
||||
var kbdata = KEYBOARDS[this.data.model];
|
||||
var w = this.data.width;
|
||||
var h = this.data.width / 2;
|
||||
var w2 = w / 2;
|
||||
var h2 = h / 2;
|
||||
|
||||
if (kbdata === undefined) {
|
||||
console.error('super-keyboard ERROR: model "' + this.data.model + '" undefined.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!oldData || this.defaultValue !== oldData.defaultValue) {
|
||||
this.rawValue = this.data.value;
|
||||
this.defaultValue = this.data.value;
|
||||
this.updateTextInput(this.filter(this.data.value));
|
||||
} else {
|
||||
this.updateTextInput(this.filter(this.rawValue));
|
||||
}
|
||||
|
||||
if (this.data.width !== oldData.width ||
|
||||
this.data.height !== oldData.height ||
|
||||
this.data.keyColor !== oldData.keyColor) {
|
||||
this.kbImg.setAttribute('geometry', {primitive: 'plane', width: w, height: h});
|
||||
this.kbImg.setAttribute('material', {
|
||||
shader: 'flat',
|
||||
src: this.data.imagePath + '/' + kbdata.img,
|
||||
color: this.data.keyColor,
|
||||
transparent: true
|
||||
});
|
||||
}
|
||||
|
||||
if (this.data.label !== oldData.label ||
|
||||
this.data.labelColor !== oldData.labelColor ||
|
||||
this.data.width !== oldData.width) {
|
||||
this.label.setAttribute('text', {
|
||||
value: this.data.label, color: this.data.labelColor, width: this.data.width});
|
||||
this.label.object3D.position.set(0, 0.3 * w, -0.02);
|
||||
}
|
||||
|
||||
if (this.data.width !== oldData.width ||
|
||||
this.data.keyBgColor !== oldData.keyBgColor) {
|
||||
this.initKeyColorPlane();
|
||||
}
|
||||
|
||||
var inputx = this.data.align !== 'center' ? kbdata.inputOffsetX * w : 0;
|
||||
if (this.data.align === 'right') { inputx *= -1; }
|
||||
|
||||
if (this.data.font !== oldData.font ||
|
||||
this.data.inputColor !== oldData.inputColor ||
|
||||
this.data.width !== oldData.width ||
|
||||
this.data.align !== oldData.align) {
|
||||
this.textInput.setAttribute('text', {
|
||||
font: this.data.font,
|
||||
color: this.data.inputColor,
|
||||
width: w,
|
||||
wrapCount: kbdata.wrapCount,
|
||||
align: this.data.align
|
||||
});
|
||||
}
|
||||
|
||||
// Some hack where the inputRect is stored in the Insert key.
|
||||
for (var i = 0; i < kbdata.layout.length; i++) {
|
||||
var kdata = kbdata.layout[i];
|
||||
if (kdata.key === 'Insert') {
|
||||
this.inputRect = kdata;
|
||||
}
|
||||
}
|
||||
|
||||
this.textInput.object3D.position.set(
|
||||
inputx,
|
||||
(w / 4) - (this.inputRect.y + this.inputRect.h / 2) * w / 2 + kbdata.inputOffsetY * w,
|
||||
0.002
|
||||
);
|
||||
|
||||
if (this.data.width !== oldData.width) {
|
||||
this.cursor.setAttribute('geometry', {
|
||||
primitive: 'plane', width: 0.03 * w, height: 0.01 * w});
|
||||
}
|
||||
|
||||
this.updateCursorPosition();
|
||||
this.setupHand();
|
||||
|
||||
this.keyBgColor.set(this.data.keyBgColor);
|
||||
this.keyHoverColor.set(this.data.keyHoverColor);
|
||||
this.keyPressColor.set(this.data.keyPressColor);
|
||||
|
||||
if (this.data.show) {
|
||||
this.open();
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
|
||||
tick: function (time) {
|
||||
var intersection;
|
||||
|
||||
if (this.prevCheckTime && (time - this.prevCheckTime < this.data.interval)) { return; }
|
||||
if (!this.prevCheckTime) {
|
||||
this.prevCheckTime = time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.raycaster) { return; }
|
||||
if (!this.focused) { return; }
|
||||
|
||||
intersection = this.raycaster.getIntersection(this.kbImg);
|
||||
if (!intersection) { return; }
|
||||
|
||||
var uv = intersection.uv;
|
||||
var keys = KEYBOARDS[this.data.model].layout;
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var k = keys[i];
|
||||
if (uv.x > k.x && uv.x < k.x + k.w && (1.0 - uv.y) > k.y && (1.0 - uv.y) < k.y + k.h) {
|
||||
if (this.keyHover !== k) {
|
||||
// Update key hover.
|
||||
this.keyHover = k;
|
||||
this.updateKeyColorPlane(this.keyHover.key, this.keyHoverColor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
play: function () {
|
||||
if (!this.cursorUpdated) { return; }
|
||||
this.startBlinking();
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
this.stopBlinking();
|
||||
},
|
||||
|
||||
/**
|
||||
* The plane for visual feedback when a key is hovered or clicked
|
||||
*/
|
||||
initKeyColorPlane: function () {
|
||||
var kbdata = KEYBOARDS[this.data.model];
|
||||
var keyColorPlane = this.keyColorPlane = document.createElement('a-entity');
|
||||
keyColorPlane.classList.add('superKeyboardKeyColorPlane');
|
||||
keyColorPlane.object3D.position.z = 0.001;
|
||||
keyColorPlane.object3D.visible = false;
|
||||
keyColorPlane.setAttribute('geometry', {primitive: 'plane', buffer: false});
|
||||
keyColorPlane.setAttribute('material', {shader: 'flat', color: this.data.keyBgColor,
|
||||
transparent: true});
|
||||
if (kbdata.hoverImg) {
|
||||
keyColorPlane.setAttribute('material', {src: this.data.imagePath + '/' + kbdata.hoverImg});
|
||||
}
|
||||
|
||||
keyColorPlane.addEventListener('componentinitialized', function (evt) {
|
||||
if (evt.detail.name !== 'material') { return; }
|
||||
if (!kbdata.hoverImg) {
|
||||
this.getObject3D('mesh').material.blending = THREE.AdditiveBlending;
|
||||
}
|
||||
});
|
||||
this.el.appendChild(keyColorPlane);
|
||||
},
|
||||
|
||||
/**
|
||||
* Move key color plane to appropriate position, scale, and change color.
|
||||
*/
|
||||
updateKeyColorPlane: function (key, color) {
|
||||
var kbdata = KEYBOARDS[this.data.model];
|
||||
var keyColorPlane = this.keyColorPlane;
|
||||
|
||||
// Unset.
|
||||
if (!key) {
|
||||
keyColorPlane.object3D.visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < kbdata.layout.length; i++) {
|
||||
var kdata = kbdata.layout[i];
|
||||
if (kdata.key !== key) { continue; }
|
||||
var w = this.data.width;
|
||||
var h = this.data.width / 2;
|
||||
var w2 = w / 2;
|
||||
var h2 = h / 2;
|
||||
var keyw = kdata.w * w;
|
||||
var keyh = kdata.h * h;
|
||||
// Size.
|
||||
keyColorPlane.object3D.scale.x = keyw;
|
||||
keyColorPlane.object3D.scale.y = keyh;
|
||||
// Position.
|
||||
keyColorPlane.object3D.position.x = kdata.x * w - w2 + keyw / 2;
|
||||
keyColorPlane.object3D.position.y = (1 - kdata.y) * h - h2 - keyh / 2;
|
||||
// Color.
|
||||
keyColorPlane.getObject3D('mesh').material.color.copy(color);
|
||||
// UVs.
|
||||
|
||||
var geometry = keyColorPlane.getObject3D('mesh').geometry
|
||||
var uvSet = geometry.faceVertexUvs[0];
|
||||
var kdataY = 1 - kdata.y;
|
||||
uvSet[0][0].set(kdata.x, kdataY);
|
||||
uvSet[0][1].set(kdata.x, kdataY - kdata.h);
|
||||
uvSet[0][2].set(kdata.x + kdata.w, kdataY);
|
||||
uvSet[1][0].set(kdata.x, kdataY - kdata.h);
|
||||
uvSet[1][1].set(kdata.x + kdata.w, kdataY - kdata.h);
|
||||
uvSet[1][2].set(kdata.x + kdata.w, kdataY);
|
||||
geometry.uvsNeedUpdate = true;
|
||||
break;
|
||||
}
|
||||
keyColorPlane.object3D.visible = true;
|
||||
},
|
||||
|
||||
setupHand: function () {
|
||||
if (this.hand && this.hand.ownRaycaster) {
|
||||
this.hand.removeAttribute('raycaster');
|
||||
}
|
||||
if (this.data.hand) {
|
||||
this.hand = this.data.hand;
|
||||
} else {
|
||||
this.hand = document.querySelector([
|
||||
'[cursor]',
|
||||
'[vive-controls]',
|
||||
'[tracked-controls]',
|
||||
'[oculus-touch-controls]',
|
||||
'[windows-motion-controls]',
|
||||
'[hand-controls]',
|
||||
'[daydream-controls] [cursor] > [raycaster]'
|
||||
].join(','));
|
||||
}
|
||||
|
||||
if (!this.hand) {
|
||||
console.error('super-keyboard: no controller found. Add <a-entity> with controller or specify with super-keyboard="hand: #selectorToController".');
|
||||
} else {
|
||||
if (!this.hand.hasLoaded) {
|
||||
this.hand.addEventListener('loaded', this.setupHand.bind(this));
|
||||
return;
|
||||
}
|
||||
var raycaster = this.hand.components['raycaster'];
|
||||
var params = {};
|
||||
|
||||
if (!raycaster) {
|
||||
this.hand.ownRaycaster = true;
|
||||
params.showLine = this.data.show;
|
||||
params.enabled = this.data.show;
|
||||
if (this.data.injectToRaycasterObjects) {
|
||||
params.objects = '.keyboardRaycastable';
|
||||
}
|
||||
this.hand.setAttribute('raycaster', params);
|
||||
} else {
|
||||
this.hand.ownRaycaster = false;
|
||||
if (this.data.injectToRaycasterObjects) {
|
||||
var objs = raycaster.data.objects.split(',');
|
||||
if (objs.indexOf('.keyboardRaycastable') === -1) {
|
||||
objs.push('.keyboardRaycastable');
|
||||
}
|
||||
params.objects = objs.join(',').replace(/^,/, '');
|
||||
this.hand.setAttribute('raycaster', params);
|
||||
}
|
||||
}
|
||||
|
||||
this.raycaster = this.hand.components.raycaster;
|
||||
}
|
||||
},
|
||||
|
||||
filter: function (str) {
|
||||
if (str === '') { return ''; }
|
||||
for (var i = 0; i < this.data.filters.length; i++) {
|
||||
switch (this.data.filters[i]) {
|
||||
case 'custom': {
|
||||
if (this.userFilterFunc) str = this.userFilterFunc(str);
|
||||
break;
|
||||
}
|
||||
case 'allupper': {
|
||||
str = str.toUpperCase();
|
||||
break;
|
||||
}
|
||||
case 'alllower': {
|
||||
str = str.toLowerCase();
|
||||
break;
|
||||
}
|
||||
case 'title': {
|
||||
str = str.split(' ').map(function (s) { return s[0].toUpperCase() + s.substr(1); }).join(' ');
|
||||
break;
|
||||
}
|
||||
case 'numbers': {
|
||||
str = str.split('').filter(function (c) { return !isNaN(parseInt(c)) || c === '.'; }).join('');
|
||||
break;
|
||||
}
|
||||
case 'first': {
|
||||
str = str[0].toUpperCase() + str.substr(1);
|
||||
break;
|
||||
}
|
||||
case 'trim': {
|
||||
str = str.trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.data.maxLength > 0 ? str.substr(0, this.data.maxLength) : str;
|
||||
},
|
||||
|
||||
click: function (ev) {
|
||||
if (!this.keyHover) { return; }
|
||||
|
||||
switch (this.keyHover.key) {
|
||||
case 'Enter': {
|
||||
this.accept();
|
||||
break;
|
||||
}
|
||||
case 'Insert': {
|
||||
return;
|
||||
}
|
||||
case 'Delete': {
|
||||
this.rawValue = this.rawValue.substr(0, this.rawValue.length - 1);
|
||||
var newValue = this.filter(this.rawValue);
|
||||
this.el.setAttribute('super-keyboard', 'value', newValue);
|
||||
this.updateTextInput(newValue);
|
||||
this.changeEventDetail.value = newValue;
|
||||
this.el.emit('superkeyboardchange', this.changeEventDetail);
|
||||
break;
|
||||
}
|
||||
case 'Shift': {
|
||||
this.shift = !this.shift;
|
||||
this.keyHover.el.setAttribute('material', 'color',
|
||||
this.shift ? this.data.keyHoverColor : this.data.keyBgColor
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'Escape': {
|
||||
this.dismiss();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (this.data.maxLength > 0 && this.rawValue.length > this.data.maxLength) { break; }
|
||||
this.rawValue += this.shift ? this.keyHover.key.toUpperCase() : this.keyHover.key;
|
||||
var newValue = this.filter(this.rawValue);
|
||||
this.el.setAttribute('super-keyboard', 'value', newValue);
|
||||
this.updateTextInput(newValue);
|
||||
this.changeEventDetail.value = newValue;
|
||||
this.el.emit('superkeyboardchange', this.changeEventDetail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateKeyColorPlane(this.keyHover.key, this.keyPressColor);
|
||||
var self = this;
|
||||
setTimeout(function () {
|
||||
self.updateKeyColorPlane(self.keyHover.key, self.keyHoverColor);
|
||||
}, 100);
|
||||
this.updateCursorPosition();
|
||||
},
|
||||
|
||||
open: function () {
|
||||
this.el.object3D.visible = true;
|
||||
if (this.hand && this.hand.ownRaycaster) {
|
||||
this.hand.setAttribute('raycaster', {showLine: true, enabled: true});
|
||||
}
|
||||
},
|
||||
|
||||
close: function () {
|
||||
this.el.object3D.visible = false;
|
||||
if (this.hand && this.hand.ownRaycaster) {
|
||||
this.hand.setAttribute('raycaster', {showLine: false, enabled: false});
|
||||
}
|
||||
},
|
||||
|
||||
accept: function () {
|
||||
this.el.object3D.visible = false;
|
||||
if (this.hand && this.hand.ownRaycaster) {
|
||||
this.hand.setAttribute('raycaster', {showLine: false, enabled: false});
|
||||
}
|
||||
this.el.emit('superkeyboardinput', {value: this.data.value});
|
||||
this.data.show = false;
|
||||
},
|
||||
|
||||
dismiss: function () {
|
||||
this.data.value = this.defaultValue;
|
||||
this.updateTextInput();
|
||||
this.el.object3D.visible = false;
|
||||
if (this.hand && this.hand.ownRaycaster) {
|
||||
this.hand.setAttribute('raycaster', {showLine: false, enabled: false});
|
||||
}
|
||||
this.el.emit('superkeyboarddismiss');
|
||||
this.data.show = false;
|
||||
},
|
||||
|
||||
blur: function (ev) {
|
||||
this.focused = false;
|
||||
if (this.keyHover && this.keyHover.key !== 'Shift') {
|
||||
this.updateKeyColorPlane(this.keyHover.key, this.keyBgColor);
|
||||
}
|
||||
this.keyHover = null;
|
||||
},
|
||||
|
||||
hover: function (ev) {
|
||||
this.focused = true;
|
||||
},
|
||||
|
||||
startBlinking: function () {
|
||||
this.stopBlinking();
|
||||
this.intervalId = window.setInterval(this.blink.bind(this), this.data.blinkingSpeed);
|
||||
},
|
||||
|
||||
stopBlinking: function () {
|
||||
window.clearInterval(this.intervalId);
|
||||
this.intervalId = 0;
|
||||
},
|
||||
|
||||
blink: function () {
|
||||
this.cursor.object3D.visible = !this.cursor.object3D.visible;
|
||||
},
|
||||
|
||||
setCustomFilter: function (f) {
|
||||
this.userFilterFunc = f;
|
||||
},
|
||||
|
||||
addCustomModel: function (name, model) {
|
||||
if (!name) { return; }
|
||||
KEYBOARDS[name] = model;
|
||||
},
|
||||
|
||||
updateCursorPosition: function () {
|
||||
var font = this.textInput.components.text.currentFont;
|
||||
if (!font) {
|
||||
var self = this;
|
||||
this.cursor.object3D.visible = false;
|
||||
window.setTimeout(function () {
|
||||
self.updateCursorPosition();
|
||||
self.startBlinking();
|
||||
}, 700);
|
||||
return;
|
||||
}
|
||||
|
||||
var w = this.data.width;
|
||||
var kbdata = KEYBOARDS[this.data.model];
|
||||
var posy = -this.inputRect.h / 2 * w / 2.4 + kbdata.inputOffsetY * w;
|
||||
var ratio = this.data.width / this.textInput.components.text.data.wrapCount;
|
||||
var pos = 0;
|
||||
var fontFactor = FontFactors[this.textInput.components.text.data.font];
|
||||
if (fontFactor === undefined) { fontFactor = 20; }
|
||||
for (var i = 0; i < this.data.value.length; i++) {
|
||||
var char = findFontChar(font.chars, this.data.value.charCodeAt(i));
|
||||
pos += char.width + char.xadvance * (char.id === 32 ? 2 : 1);
|
||||
}
|
||||
if (this.data.align === 'center') {
|
||||
pos = pos * ratio * fontFactor * 0.0011 / 2.0 + 0.02 * w;
|
||||
} else if (this.data.align === 'left') {
|
||||
pos = pos * ratio * fontFactor * 0.0011 + 0.02 * w;
|
||||
pos -= w / 2;
|
||||
} else if (this.data.align === 'right') {
|
||||
pos = -pos * ratio * fontFactor * 0.0011 - 0.02 * w;
|
||||
pos += w / 2;
|
||||
}
|
||||
this.cursor.object3D.position.set(pos, posy, 0.001);
|
||||
this.cursorUpdated = true;
|
||||
},
|
||||
|
||||
updateTextInput: function (value) {
|
||||
this.textInputObject.value = value || this.data.value;
|
||||
this.textInput.setAttribute('text', this.textInputObject);
|
||||
}
|
||||
});
|
||||
|
||||
function findFontChar (chars, code) {
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
if (chars[i].id === code) { return chars[i]; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -13,7 +13,6 @@ require('aframe-orbit-controls');
|
||||
require('aframe-proxy-event-component');
|
||||
require('aframe-state-component');
|
||||
require('aframe-slice9-component');
|
||||
require('aframe-super-keyboard');
|
||||
require('aframe-thumb-controls-component');
|
||||
|
||||
requireAll(require.context('./components/', true, /\.js$/));
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
<a-entity
|
||||
id="keyboard"
|
||||
bind__super-keyboard="{% if not DEBUG_KEYBOARD %}hand: activeHand === 'left' && '#leftHand' || '#rightHand'; {% endif %}show: isSearching"
|
||||
super-keyboard="label: Search from over 2500 songs!; labelColor: #FAFAFA; width: 1; hand: {{ DEBUG_KEYBOARD and '#mouseCursor' or '#rightHand' }}; imagePath: assets/img/keyboard/; injectToRaycasterObjects: false"
|
||||
super-keyboard="label: Search from over 2500 songs!; inputColor: #fff; labelColor: #FFF; width: 1.2; hand: {{ DEBUG_KEYBOARD and '#mouseCursor' or '#rightHand' }}; imagePath: assets/img/keyboard/; font: assets/fonts/Teko-Bold.json; align: center; model: supersaber; keyColor: #fff; injectToRaycasterObjects: false"
|
||||
position="0.6 1.1 -1.999"
|
||||
keyboard-raycastable
|
||||
search
|
||||
|
||||
Reference in New Issue
Block a user