Created
January 31, 2016 06:17
-
-
Save cimadai/7cd295f194f4ff231a8e to your computer and use it in GitHub Desktop.
talktrans - client side
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends layout | |
block content | |
div(class="container-fluid") | |
div(class="row") | |
div(class="col-xs-12") | |
form | |
div(class="form-group") | |
label(for="input_text" class="step-message") Step1. 言語を選択 | |
div(style="text-align:center;") | |
input(type="checkbox" id="lang_select" checked data-toggle="toggle" data-on="日本語から英語" data-off="English to Japanese" data-width="250px" data-onstyle="primary" data-offstyle="success") | |
div(class="form-group") | |
label(for="input_text" class="step-message") Step2. ボタンを押して話す | |
div(style="text-align:center;") | |
span(id="record" class="speech-button-wrapper") | |
img(src="/images/language.png" width="100px") | |
hr | |
div(class="form-group") | |
label(for="input_text" class="step-message") 音声認識した言葉 | |
textarea(type="text" id="input_text" class="form-control" placeholder="Input or speak") | |
div(class="form-group") | |
label(for="result_text" class="step-message") 翻訳した言葉 | |
textarea(type="text" id="result_text" class="form-control" placeholder="Translated message") | |
footer(class="footer") | |
div(class="container-fluid") | |
b talktrans | |
span © 2016 cimadai. MIT License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;$(function () { | |
"use strict"; | |
var $inputTextArea = $("#input_text"); | |
var $resultTextArea = $("#result_text"); | |
var $langSelect = $("#lang_select"); | |
var $record = $("#record"); | |
var speech = new SpeechSynthesisUtterance(); | |
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition; | |
var recognition = new window.SpeechRecognition(); | |
recognition.continuous = true; | |
var langMap = {ja: "ja-JP", en: "en-US"}; | |
function translateLangToSpeechLang(translateLang) { | |
return langMap[translateLang] || "ja-JP"; | |
} | |
var isTranslating = false; | |
function translateAndSpeech(text) { | |
if (!isTranslating) { | |
isTranslating = true; | |
$.ajax({ | |
type: "GET", | |
url: "/translate", | |
dataType: "json", | |
data: { | |
text: text | |
}, | |
success: function (ret) { | |
isTranslating = false; | |
$resultTextArea.val(ret.translated); | |
speechMessage(ret.translated, translateLangToSpeechLang(ret.to)); | |
}, | |
error: function (XMLHttpRequest, textStatus, errorThrown) { | |
isTranslating = false; | |
$resultTextArea.val(textStatus); | |
} | |
}); | |
} | |
} | |
$inputTextArea.on("change", function () { | |
var text = $inputTextArea.val(); | |
if (text.length > 0) { | |
translateAndSpeech(text); | |
} | |
}); | |
function speechMessage(text, lang) { | |
speech.text = text; | |
speech.lang = lang; | |
speechSynthesis.speak(speech); | |
} | |
var isRecording = false; | |
recognition.addEventListener('start', function(event) { | |
isRecording = true; | |
$record.addClass("on-record"); | |
}, false); | |
//recognition.addEventListener('speechstart', function(event) { | |
//}, false); | |
recognition.addEventListener('end', function(event) { | |
isRecording = false; | |
$record.removeClass("on-record"); | |
}, false); | |
// 録音終了時トリガー | |
recognition.addEventListener('result', function(event) { | |
var text = event.results.item(0).item(0).transcript; | |
translateAndSpeech(text); | |
$inputTextArea.val(text); | |
recognition.stop(); | |
}, false); | |
function getRecordingLang() { | |
if ($langSelect.prop("checked")) { | |
return "ja-JP"; | |
} else { | |
return "en-US"; | |
} | |
} | |
$record.on("click", function (ev) { | |
ev.preventDefault(); | |
if (isRecording) { | |
recordStop(); | |
} else { | |
recordStart(getRecordingLang()); | |
} | |
return false; | |
}); | |
function recordStart(lang) { | |
recognition.lang = lang; | |
recognition.start(); | |
} | |
function recordStop() { | |
recognition.stop(); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
doctype html | |
html | |
head | |
meta(charset="UTF-8") | |
meta(name="viewport", content="width=device-width, initial-scale=1") | |
title= title | |
link(rel="shortcut icon" href="/images/favicon.png") | |
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css") | |
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css") | |
link(rel="stylesheet", href="https://gitcdn.github.io/bootstrap-toggle/2.2.0/css/bootstrap-toggle.min.css") | |
link(rel="stylesheet", href="/stylesheets/style.css") | |
script(src="https://code.jquery.com/jquery-2.1.4.min.js") | |
script(src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js") | |
script(src="https://gitcdn.github.io/bootstrap-toggle/2.2.0/js/bootstrap-toggle.min.js") | |
script(src="/javascripts/translate.js") | |
body | |
nav(class="navbar navbar-default navbar-fixed-top") | |
div(class="container") | |
div(class="navbar-header") | |
a(class="navbar-brand" href="#") | |
span talktrans | |
block content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
padding-top: 1em; | |
background-color: white; | |
} | |
.speech-button-wrapper { | |
/*border: 1px solid darkgrey;*/ | |
display: inline-block;" | |
} | |
.step-message { | |
color: #777; | |
} | |
body > .container-fluid { | |
padding-top: 60px; | |
} | |
.navbar { | |
height: 32px !important; | |
min-height: 32px !important; | |
} | |
.navbar-brand { | |
background: url("/images/favicon.png") no-repeat left center; | |
background-size: contain; | |
height: 32px; | |
padding-top: 0; | |
} | |
.navbar-brand span { | |
padding-left: 32px; | |
line-height: 32px; | |
height: 32px; | |
display: inline-block; | |
} | |
#record { | |
cursor: pointer; | |
} | |
.on-record { | |
background: linear-gradient(3deg, #ffffff, #7eaeff); | |
background-size: 400% 400%; | |
-webkit-animation: recording 1s ease infinite; | |
-moz-animation: recording 1s ease infinite; | |
animation: recording 1s ease infinite; | |
} | |
@-webkit-keyframes recording { | |
0%{background-position:50% 0%} | |
50%{background-position:50% 100%} | |
100%{background-position:50% 0%} | |
} | |
@-moz-keyframes recording { | |
0%{background-position:50% 0%} | |
50%{background-position:50% 100%} | |
100%{background-position:50% 0%} | |
} | |
@keyframes recording { | |
0%{background-position:50% 0%} | |
50%{background-position:50% 100%} | |
100%{background-position:50% 0%} | |
} | |
/* Sticky footer styles | |
-------------------------------------------------- */ | |
html { | |
position: relative; | |
min-height: 100%; | |
} | |
body { | |
/* Margin bottom by footer height */ | |
margin-bottom: 30px; | |
} | |
.footer { | |
position: absolute; | |
bottom: 0; | |
width: 100%; | |
/* Set the fixed height of the footer here */ | |
height: 30px; | |
background-color: #f5f5f5; | |
vertical-align: bottom; | |
} | |
.footer div { | |
height: 30px; | |
line-height: 30px; | |
} | |
/* Custom page CSS | |
-------------------------------------------------- */ | |
/* Not required for template or sticky footer method. */ | |
body > .container { | |
padding: 30px 15px 0; | |
} | |
.container .text-muted { | |
margin: 20px 0; | |
} | |
.footer > .container { | |
padding-right: 15px; | |
padding-left: 15px; | |
} | |
code { | |
font-size: 80%; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment