Семичев Олег
if (window.speechSynthesis) {}
speechSynthesis
.cancel()
.pause()
.resume()
.speak()
.getVoices()
var message = new SpeechSynthesisUtterance('Hello World');
window.speechSynthesis.speak(message);
var voices = window.speechSynthesis.getVoices();
message.voice = voices[10]; // голос
message.rate = 1; // скорость от 0 до 10
message.pitch = 2; // высота от 0 до 2
message.text = 'Text';
message.lang = 'en-US';
message
.onboundary // при окончании слова/предложения
.onend
.onerror
.onpause
.onresume
.onstart
var SpeechRecognition = window.SpeechRecognition ||
window.webkitSpeechRecognition;
var recognizer = new SpeechRecognition();
recognizer.lang = 'en-US';
// продолжает слушать и расопзнавать речь даже после паузы
recognizer.continuous = true; // false по умолчанию
// повзоляет получать промежуточные результаты
recognizer.interimResults = true; // false по умолчанию
recognizer
.start()
.stop()
recognizer
.onstart
.onend
.onerror
.onresult
{
resultIndex: 0, // индекс текущего результата
results : [ // 2d-массив результатов/слов
[
isFinal: true, // – законченный результат
0: { // [0] - самое вероятное слово
confidence: 0.91233,
transcript: 'Hi'
},
...
],
...
]
}
<div id="speech-log">Click to start!</div>
var log = document.getElementById('speech-log');
var recognizer = new SpeechRecognition();
recognizer.lang = 'en-US';
recognizer.continious = true;
log.onclick = function () {
log.innerHTML = 'Recognition started';
recognizer.start();
};
recognizer.onresult = function (e) {
var index = e.resultIndex;
var result = e.results[index][0].transcript.trim();
log.innerHTML = result;
if (result.toLowerCase() === 'tequila') {
log.innerHTML += '
Recognition stopped';
recognizer.stop();
}
};
navigator.getUserMedia
,
который можно уже считать legacy,
ибо в будущем он будет переписан и попадет в MediaDevices
.
var getUserMedia = navigator.getUserMedia ||
navigator.mozGetUserMedia ||
navigator.webkitGetUserMedia;
getUserMedia(
options,
function successCallback(stream) {},
function errorCallback(error) {}
);
options = {
video: true,
audio: true
}
options = {
video: {
// обязательные условия, которые должен
// выполнить UA, иначе вызовется errorCallback
mandatory: {
minWidth : 1280,
minHeight : 720,
minFrameRate: 30
},
optional: [
{ minFrameRate: 60 }
]
}
}
Подробнее в спеке
<video id="media-video"></video>
var video = document.getElementById('media-video');
var localStream = null;
video.onclick = function () {
if (// поток активен) {
// вырубаем его
}
// включаем
}
video.onclick = function () {
if (// поток активен) {
// вырубаем его
}
getUserMedia(
{ video: true, audio: true },
function(mediaStream) {
localStream = mediaStream;
video.src = URL.createObjectURL(mediaStream);
video.play();
},
function (error) { console.log(error); }
);
};
О createObjectURL на MDN
video.onclick = function () {
if (localStream && localStream.active) {
var track = localStream.getTracks()[0];
track.stop();
video.pause();
return;
}
// включаем
};
AmbientLightSensor
, описанный
в спецификации, не реализован нигде. Но существуют два события:ondevicelight
и
onlightlevel
,
из которых работаетondevicelight
.
if ('ondevicelight' in window) {}
<div id="light-value"></div>
var lightValue = document.getElementById('light-value');
window.ondevicelight = function(e) {
lightValue.innerHTML = 'Light is ' + e.value + ' lux';
};
if (navigator.getGamepads) {}
var gamepads = navigator.getGamepads();
// Chrome - { 0, 1, 2, 3, length}
// Firefox - [ 0 ... n ]
// Edge - [ undefined, undefined, undefined, undefined ]
var gamepad = gamepads[0];
// ???
gamepad
.index
.connected // true, если геймпад подключен
.id // информация о геймпаде,
// напр. производитель, модель
.timestamp // t последнего изменения состояния
// (некоторые модели постоянно
// пингуют браузер)
gamepad
// массив осей со значениями от -1 до 1:
// -1 – вверх/влево
// 1 – вниз/вправо
// 0 – не нажато
.axes [
0: -1, // крестовина - горизонтальная ось
1: 1, // крестовина - вертикальная ось
...
]
gamepads
.buttons: [
0: {
pressed: true,
value: 1
},
...
]
window.addEventListener('gamepadconnected', callback);
window.addEventListener('gamepaddisconnected', callback);
// e.gamepad - Gamepad Object
// Firefox only
window.addEventListener('gamepadbuttondown', callback);
window.addEventListener('gamepadbuttonup', callback);
// e.button – индекс нажатой кнопки
// Firefox Nightly only
window.addEventListener('gamepadaxismove', callback);
// e.axis – индекс оси, e.value – ее значение
<pre id="gamepad-logger"></pre>
var logger = document.getElementById('gamepad-logger');
// какой-то хитрый бесконечный цикл в котором...
var gamepads = navigator.getGamepads()[0];
var gamepad = gamepads[0]; // ...получим геймпад
log(gamepad); // ...и залогируем его
Это, в нашем случае, так называемый Game loop
(function loop() {
var gamepad = navigator.getGamepads()[0];
gamepad && log(gamepad);
window.requestAnimationFrame(loop);
})();
Що таке rAF?
var AXS_MOVE = 0;
var BTN_JUMP = 1;
var BTN_ATK = 2;
function isPressed(value) { return value ? '[X]' : '[ ]'; }
function log(gp) {
logger.innerHTML = [
isPressed(gp.axes[AXS_MOVE] < -.5) + ' Left',
isPressed(gp.axes[AXS_MOVE] > .5) + ' Right',
isPressed(gp.buttons[BTN_JUMP].pressed) + ' Jump',
isPressed(gp.buttons[BTN_ATK].pressed) + ' Atk'
].join('\n');
}
if (navigator.getBattery) {}
navigator
.getBattery()
.then(initBattery);
function initBattery(battery) {
console.log(battery);
}
battery {
level : 0.94
charging : false
chargingTime : Infinity
dischargingTime: 11460
}
battery
.level // заряд батареи от 0 до 1
.chagring // true, если заряжяется
.chagringTime // ~время до полной зарядки, сек
.dischagringTime // ~время до полной разрядки, сек
battery
.onlevelchange
.onchagringchange
.onchagringtimechange
.ondischagringtimechange
<div id="battery-level"></div>
<div id="battery-charging"></div>
var level = document.getElementById('battery-level');
var charging = document.getElementById('battery-charging');
navigator
.getBattery()
.then(initBattery);
function initBattery(battery) {
battery.onlevelchange = updateLevel;
battery.onlevelchange();
battery.onchargingchange = updateCharging;
battery.onchargingchange();
}
function updateLevel() {
level.innerHTML = (this.level * 100).toFixed(2) + '%';
}
function updateCharging() {
var color = this.charging ? '#0a0' : '#a00';
charging.style.background = color;
var onOff = this.charging ? 'on' : 'off';
charging.innerHTML = 'Charger is ' + onOff;
}
var hidden = null;
var visibilityState = null;
var visibilityChange = null;
if ('hidden' in document) {
hidden = 'hidden';
visibilityState = 'visibilityState';
visibilityChange = 'visibilitychange';
} else if ('mozHidden' in document) {
hidden = 'mozHidden';
visibilityState = 'mozVisibilityState';
visibilityChange = 'mozvisibilitychange';
} else if ('webkitHidden' in document) {
hidden = 'webkitHidden';
visibilityState = 'webkitVisibilityState';
visibilityChange = 'webkitvisibilitychange';
}
document[hidden]
// true - неактивная вкладка, окно не в фокусе или свернуто
document[visibilityState]
// 'visible' – значение видимой/активной вкладки
// 'hidden' - значение скрытой вкладки или
// неактивного/свернутого окна браузера
//
// Необязательные к поддержке значения:
// 'unloaded' - значение вкладки, которую хотят
// закрыть/перейти на другую страницу
// 'prerender' - значение пререндереной вкладки
Подробнее о "магическом" пререндере
document.addEventListener(visibilityChange, function () {
console.log([
'----------------',
'Hidden: ' + document[hidden],
'State : ' + document[visibilityState],
'----------------'
].join('\n'));
});
var Notification = window.Notification ||
window.webkitNotification;
Notification.requestPermission(callback);
new Notification(title, options);
title = 'Hi'; // обязательный параметр
options = {
body: 'My name is',
tag : 'SlimShady', // своеобразный id
dir : 'ltr', // или 'rtl'
lang: 'en-US',
icon: 'img/eminem.jpg'
}
var notification = new Notification(title);
notification
.onclick // при клике на оповещение
.onclose // при закрытии, в т.ч. браузером
.onshow // при появлении оповещения
.onerror // при ошибке, чаще всего, если
// пользователь запретил оповещения
var notification = new Notification('Hi', {
body: 'My name is',
icon: 'img/eminem.jpg',
});
notification.onerror = function () {
alert('Probably, blocked :\'C');
}
var vibrate = navigator.vibrate ||
navigator.mozVibrate ||
navigator.webkitVibrate;
// вибрация длительностью 500ms
vibrate(500); // === [500]
// 500ms вибрация, 250ms пауза, 500ms вибрация
vibrate([500, 250, 500]);
// останавливает вибрацию
vibrate(0); // === []
Вибрация не блокирует поток выполнения