I would like to create a website that can classify different types of cars. I have managed to get the website working to use the mobile net model, but I would like to use a custom model that I trained in google colab and then converted into javascript. Does anyone know how I could achieve this?
Here is the javascript code:
// Defining Variables
const webcamElement = document.getElementById('webcam');
let net;
var webcamrunning = false; // Flag, indicates if webcam-prediction is running or not
var bw = document.getElementById('butwebcam')
var bi = document.getElementById('butimage')
// App that predicts image
async function app() {
console.log('Loading mobilenet..');
const uploadJSONInput = document.getElementById('upload-json');
const model = await tf.loadLayersModel(tf.io.browserFiles([uploadJSONInput.files[0]]));
// Check if model loaded, if not, load it.
if (net == undefined)
{bi.innerHTML = 'Wait for Initiation...';
net = await model.load();
console.log('Sucessfully loaded model');
bi.innerHTML = 'Predict'}
else {console.log('Model already loaded')};
// Make a prediction through the model on our image.
const imgEl = document.getElementById('output');
const result = await net.classify(imgEl);
document.getElementById('console_pic').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
}
// Function that activates (starts webcam app) and deactivates the Webcam-Prediction
function start_webcam(){
if (webcamrunning == false)
{app_webcam();
}
else {webcamrunning = false;
bw.innerHTML = 'Activate Predicting';
};
};
// Setup Webcam
async function setupWebcam() {
return new Promise((resolve, reject) => {
const navigatorAny = navigator;
navigator.getUserMedia = navigator.getUserMedia ||
navigatorAny.webkitGetUserMedia || navigatorAny.mozGetUserMedia ||
navigatorAny.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true},
stream => {
webcamElement.srcObject = stream;
webcamElement.addEventListener('loadeddata', () => resolve(), false);
},
error => reject());
} else {
reject();
}
});
}
// Webcam application
async function app_webcam() {
console.log('Loading mobilenet..');
// Check if model loaded, if not, load it.
if (net == undefined)
{bw.innerHTML = 'Wait for Initiation...';
net = await mobilenet.load();
console.log('Sucessfully loaded model');}
else {console.log('Model already loaded')};
await setupWebcam();
webcamrunning =true;
bw.innerHTML = 'Stop Predicting';
while (webcamrunning) {
const result = await net.classify(webcamElement);
document.getElementById('console_vid').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
// Give some breathing room by waiting for the next animation frame to
// fire.
await tf.nextFrame();
}
}
;
Here is the html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel='stylesheet' href='styles.css'/>
<input type="file" id="upload-json" src="C:\Users\USER\Desktop\ImageClassifier-master\model\model.json"/>
<!-- Load the latest version of TensorFlow.js -->
<script src="https://unpkg.com/#tensorflow/tfjs"></script>
<script src="https://unpkg.com/#tensorflow-models/mobilenet"></script>
<title> Image Classifier with MobileNet </title>
</head>
<body>
<img style='margin-top: -6px; z-index: 19;' id="header" height ="320">
<h1 style='margin-top: -35px'> What car is that?</h1>
<br>
<hr/>
<br>
<em> <strong> </strong> </em>
<br>
<br>
<hr/>
<br>
<h2> Upload your own Picture</h2>
<!-- Upload Function with File Preview -->
<input type="file" accept=".png, .jpg, .jpeg" height="200"
onchange="document.getElementById('output').src = window.URL.createObjectURL(this.files[0])">
<!-- Predict button, calls predict function in Javascript -->
<button id="butimage" onclick="app()"> Predict! </button>
<!-- Window for Picture Preview -->
<div class = "window">
<span class="helper"></span>
<img class="center" id="output" alt="your image" src = "img/example.jpg" />
</div>
<div class = "result" id="console_pic">Result</div>
<br>
<hr/>
<br>
<br>
<br>
<br>
<script src="index.js"></script>
</body>
</html>
Related
I'm not sure if my title explains my problem well.
I have a web application that should allow users to pick contacts from their phone book and add them to their account as emergency contacts.
I came across an API on https://contact-picker.glitch.me/.
The API does not work on desktop, it's not meant to. That's ok, because my web application is for mobile.
I run some tests in chrome for android and the API works very well without any problems.
MY PROBLEM:
I compiled the web application as an android mobile app on several websites that offer this service such as https://gonative.io, https://www.swing2app.com/, and even https://appsgeyser.com/.
The APKs work fine except for the contact picker API. It does not respond when clicked on, despite it being compatible. And when click a second time this is the error I get:
InvalidStateError: Failed to execute 'select' on 'ContactsManager': Contacts Picker is already in use.
I'm not sure how to go about this. I would appreciate any information or help as to how to resolve this problem. Thank you.
Below is my code if it will help. It's just the necessary bit that calls the contact picker. Nothing is processed after that.
`
< !DOCTYPE html >
<html>
<head></head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, minimal-ui, viewport-fit=cover">
<body>
<h2>CONTACT PICKER API</h2>
<p id="requireHTTPS" class="hidden"></p>
<p id="notSupported"></p>
<input type="checkbox" checked hidden id="multiple" />
<input type="checkbox" checked hidden id="name" />
<input type="checkbox" id="email" hidden />
<input type="checkbox" checked hidden id="tel" />
<input type="checkbox" hidden id="address" />
<input type="checkbox" hidden id="icon" />
<!-- END -------- HIDDEN FORM ELEMENTS FOR JS - KEEP OUT OF FROM SUBMIT -->
<button id="butRequest" type="button" class="btn btn-sm btn-danger light" disabled>
Select contacts
</button>
<form action="#" method="post">
<p><textarea cols="80" rows="5" id="demo" name="contacts"></textarea></p>
<button type="submit" name="add_contacts">Add Contacts</button>
</form>
<script>
const butReq = document.getElementById('butRequest');
butReq.addEventListener('click', getContacts);
const cbMultiple = document.getElementById('multiple');
const cbName = document.getElementById('name');
const cbEmail = document.getElementById('email');
const cbTel = document.getElementById('tel');
const cbAddress = document.getElementById('address');
const cbIcon = document.getElementById('icon');
const ulResults = document.getElementById('results');
const preResults = document.getElementById('rawResults');
const supported = ('contacts' in navigator && 'ContactsManager' in window);
if (supported) {
const divNotSupported = document.getElementById('notSupported');
divNotSupported.classList.toggle('hidden', true);
butReq.removeAttribute('disabled');
checkProperties();
}
async function checkProperties() {
const supportedProperties = await navigator.contacts.getProperties();
if (supportedProperties.includes('name')) {
enableProp(cbName);
}
if (supportedProperties.includes('email')) {
enableProp(cbEmail);
}
if (supportedProperties.includes('tel')) {
enableProp(cbTel);
}
if (supportedProperties.includes('address')) {
enableProp(cbAddress);
}
if (supportedProperties.includes('icon')) {
enableProp(cbIcon);
}
}
async function getContacts() {
const props = [];
if (cbName.checked) props.push('name');
if (cbEmail.checked) props.push('email');
if (cbTel.checked) props.push('tel');
if (cbAddress.checked) props.push('address');
if (cbIcon.checked) props.push('icon');
const opts = {
multiple: cbMultiple.checked
};
try {
const contacts = await navigator.contacts.select(props, opts);
handleResults(contacts);
} catch (ex) {
ulResults.classList.toggle('error', true);
ulResults.classList.toggle('success', false);
ulResults.innerText = ex.toString();
}
}
function handleResults(contacts) {
ulResults.classList.toggle('success', true);
ulResults.classList.toggle('error', false);
ulResults.innerHTML = '';
renderResults(contacts);
}
function enableProp(cbox) {
cbox.removeAttribute('disabled');
//cbox.setAttribute('checked', 'checked');
}
function renderResults(contacts) {
contacts.forEach((contact) => {
const lines = [];
if (contact.name) lines.push(`${contact.name}`);
if (contact.tel) lines.push(`${contact.tel}`);
lines.push(`${JSON.stringify(contact)}`);
const li = document.createElement('li');
li.innerHTML = lines.join(',');
//li.disabled= true;
var counter = 1;
li.setAttribute('name', 'contact_' + counter)
ulResults.appendChild(li);
counter = counter + 1;
});
const strContacts = JSON.stringify(contacts, null, 1);
//alert(strContacts);
document.getElementById("demo").innerHTML = strContacts;
}
</script>
</body>
</html>
`
NOTE THAT:
I've tried the same script in browser and it works well.
I've also tried having the contact picker bit of the application to open into chrome browser itself bit it keeps opening in-app. I did this by adding "target='_blank'' to the html element.
Thank you in advance.
I am trying to piece together a Google Apps script for a touchscreen clocking in system, and that involves generating some buttons from an array taken from a spreadsheet, but I'm getting a bit lost working out how to get the script to document which of these automatically generated buttons has been pressed.
Basically, I am using a modified version of this script (https://www.youtube.com/watch?v=KGhGWuTjJwc) - I need it to work with a touch screen.
I have got a version of the script given in the video above working. But because the web app must work on a touch screen I need to be able to generate buttons for the input of staff ID and PIN to replace the text boxes.
To do this I am pulling in an array from a Google Sheet that contains all staff initials needed to log in, as well as adding a numeric keypad to enter a PIN.
I have (sort of) successfully borrowed a keypad from here:https://github.com/ProgrammingHero1/batch5-pin-matcher-solution but I am stuck trying to get use buttons for the staff ID input.
I have managed to generate the buttons from the spreadsheet array, using a modified version of this Create an array of buttons from Javascript array but I can't work out how to set staffid to match whichever of the auto-generated buttons was pressed last. Currently those buttons don't do anything.
If anyone can help guide me the last step of the way so that staffid is set using the buttons and not using the text box that would be very much appreciated.
Below is the code I am using. I am aware that it is a dog's breakfast - that's because I am hacking it together from various sources working at (well, realistically well beyond) the limits of my understanding!
Anyway, here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- Metro 4 -->
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
<style>
.main-box {
max-width:500px;
}
.error-message {
background:red;
color:white
padding: 1000px;
border-radius: 1000px;
}
</style>
</head>
<body>
<div class="container">
<div class="container d-flex flex-justify-center pt-9">
<div data-role="panel" class="main-box">
<form id="main-form">
<div class="form-group">
<input type="text" data-role="input" data-prepend="Staff ID" id="staffid">
<div class="form-group">
</div>
<div class="form-group">
<button id="start-work" class="button success" type="submit" data-action="Start work">Start work</button>
<button id="finish-work" class="button success" type="submit" data-action="Finish work">Finish work</button>
<button id="start-break" class="button success" type="submit" data-action="Start break">Start break</button>
<button id="finish-break" class="button success" type="submit" data-action="Finish break">Finish break</button>
<div class="input-section half-width">
<input id="typed-numbers" class="form-control" type="text">
<div class="numbers">
<div id="key-pad" class="calc-body">
<div class="calc-button-row">
<div class="button">7</div>
<div class="button">8</div>
<div class="button">9</div>
</div>
<div class="calc-button-row">
<div class="button">4</div>
<div class="button">5</div>
<div class="button">6</div>
</div>
<div class="calc-button-row">
<div class="button">1</div>
<div class="button">2</div>
<div class="button">3</div>
</div>
<div class="calc-button-row">
<div class="button"><</div>
<div class="button">0</div>
<div class="button">C</div>
</div>
</div>
</div>
</div>
</div>
</form>
<div id="message" class="d-none error-message mt4">
Error!!
</div>
</div>
</div>
</body>
<!-- Metro 4 -->
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script>
const TSPwebapp = {}
TSPwebapp.onLoad = function(){
TSPwebapp.form = document.getElementById("main-form")
TSPwebapp.staffidInput = document.getElementById("staffid")
TSPwebapp.pinInput = document.getElementById("typed-numbers")
TSPwebapp.startWorkButton = document.getElementById("start-work")
TSPwebapp.finishWorkButton = document.getElementById("finish-work")
TSPwebapp.startBreakButton = document.getElementById("start-break")
TSPwebapp.finishBreakButton = document.getElementById("finish-break")
TSPwebapp.message = document.getElementById("message")
TSPwebapp.form.addEventListener("submit",TSPwebapp.onSubmit)
TSPwebapp.startWorkButton.addEventListener("click",TSPwebapp.startFinishWork)
TSPwebapp.finishWorkButton.addEventListener("click",TSPwebapp.startFinishWork)
TSPwebapp.startBreakButton.addEventListener("click",TSPwebapp.startFinishBreak)
TSPwebapp.finishBreakButton.addEventListener("click",TSPwebapp.startFinishBreak)
} // TSPwebapp.onLoad function
TSPwebapp.onSubmit= function(e){
e.preventDefault()
} // TSPwebapp.onSubmit function
TSPwebapp.startFinishWork = function(e){
const payload = {
staffid: TSPwebapp.staffidInput.value,
pin: TSPwebapp.pinInput.value,
action: e.target.dataset.action
}
google.script.run.withSuccessHandler(() => {
TSPwebapp.staffidInput.value = ""
TSPwebapp.pinInput.value = ""
} ).withFailureHandler(() => {
TSPwebapp.message.classList.remove("d-none")
setTimeout(() => {TSPwebapp.message.classList.add("d-none")},5000)
}).startFinishWork(payload)
} // TSPwebapp.startFinishWork function
TSPwebapp.startFinishBreak = function(e){
const payload = {
staffid: TSPwebapp.staffidInput.value,
pin: TSPwebapp.pinInput.value,
action: e.target.dataset.action
}
google.script.run.withSuccessHandler(() => {
TSPwebapp.staffidInput.value = ""
TSPwebapp.pinInput.value = ""
} ).withFailureHandler(() => {
TSPwebapp.message.classList.remove("d-none")
setTimeout(() => {TSPwebapp.message.classList.add("d-none")},5000)
}).startFinishBreak(payload)
} // TSPwebapp.startFinishBreak function
</script>
<script>
document.getElementById('key-pad').addEventListener('click', function (event) {
const number = event.target.innerText;
const calcInput = document.getElementById('typed-numbers');
if (isNaN(number)) {
if (number == 'C') {
calcInput.value = '';
}
}
else {
const previousNumber = calcInput.value;
const newNumber = previousNumber + number;
calcInput.value = newNumber;
}
});
</script>
<script>
document.addEventListener("DOMContentLoaded",TSPwebapp.onLoad)
document.addEventListener("DOMContentLoaded",function(){
google.script.run.withSuccessHandler(printBtn).useDataRange();
});
function printBtn(staffData) {
for (var i = 0; i < staffData.length; i++) {
var btn = document.createElement("button");
var t = document.createTextNode(staffData[i]);
btn.appendChild(t);
document.body.appendChild(btn);
}
}
window.onload = printBtn();
</script>
</body>
</html>
Here is the Google Apps Script code:
function doGet(e) {
Logger.log(e);
return HtmlService.createHtmlOutputFromFile("form");
}
function useDataRange () {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,1).getValues()
Logger.log(staffData)
return staffData;
}
function startFinishBreak(payload){
console.log(payload)
if (!["Start work","Finish work","Start break","Finish break"].includes(payload.action)){
throw new Error("Sign in or sign out failed")
return
}
console.log("Initial check passed")
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsBreakData = ss.getSheetByName("Break data")
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,3).getValues()
const matchingStaff = staffData.filter(r => r[0].toString() === payload.staffid && r[2].toString() === payload.pin)
if(matchingStaff.length !== 1){
throw new Error("Sign in or sign out failed")
return
}
const idsData = wsBreakData.getRange(2,2,wsBreakData.getLastRow()-1,3).getValues()
console.log(idsData)
const matchingIdsData = idsData.filter(r => r[0].toString() === payload.staffid)
console.log(matchingIdsData)
const latestAction = matchingIdsData.length === 0 ? "Finish break" : matchingIdsData[matchingIdsData.length-1][2]
if (latestAction === payload.action){
throw new Error("Sign in or sign out failed")
return
}
wsBreakData.appendRow([new Date(),payload.staffid,payload.pin,payload.action])
}
function startFinishWork(payload){
console.log(payload)
if (!["Start work","Finish work","Start break","Finish break"].includes(payload.action)){
throw new Error("Sign in or sign out failed")
return
}
console.log("Initial check passed")
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsWorkData = ss.getSheetByName("Work data")
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,3).getValues()
const matchingStaff = staffData.filter(r => r[0].toString() === payload.staffid && r[2].toString() === payload.pin)
if(matchingStaff.length !== 1){
throw new Error("Sign in or sign out failed")
return
}
const idsData = wsWorkData.getRange(2,2,wsWorkData.getLastRow()-1,3).getValues()
console.log(idsData)
const matchingIdsData = idsData.filter(r => r[0].toString() === payload.staffid)
console.log(matchingIdsData)
const latestAction = matchingIdsData.length === 0 ? "Finish work" : matchingIdsData[matchingIdsData.length-1][2]
if (latestAction === payload.action){
throw new Error("Sign in or sign out failed")
return
}
wsWorkData.appendRow([new Date(),payload.staffid,payload.pin,payload.action])
}
I hope this description all more or less makes sense - I am trying something a way beyond by current capabilities but I do need to get this task done and hopefully I'm learning in the process.
You need to add a value and event listener to each button. Then you can use the value to determine which button was pressed.
I have updated my script to address the comments below.
First add a new division.
<div id="staffButtons">
</div>
<div id="message" class="d-none error-message mt4">
Next make some changes to original script as shown.
function printBtn(staffData) {
let div = document.getElementById("staffButtons"); // add this
for (var i = 0; i < staffData.length; i++) {
var btn = document.createElement("button");
var t = document.createTextNode(staffData[i]);
btn.value = staffData[i]
btn.addEventListner("click",buttonClick);
btn.appendChild(t);
div.appendChild(btn); // change this
}
}
function buttonClick() {
document.getElementById("staffid") = this.value;
}
Reference
addEventListener
So I've been trying to make a UI in which the user can upload his pictures to local system (To move from one location to images database by opening a file manager dialogue box) or take live pictures and add to the images database. I made this simple html file which is running well but after i try to run it with flask after creating a localhost , google chrome doesn't prompt for camera permission from above and somehow the permission is already granted but the camera doesn't work . Here is the code- app.py
import os
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
#app.route("/")
def index():
return render_template("upload.html")
#app.route("/upload", methods=["POST"])
#for the intake of the folder name that needs to be created or selected in the dataset folder
def upload():
fold_nam=request.form["name"]
folder_name = request.form.get('superhero')
'''
# this is to verify that folder to upload to exists.
if os.path.isdir(os.path.join(APP_ROOT, 'files/{}'.format(folder_name))):
print("folder exist")
'''
#Change this target variable as per the device working in (set your own path address of the dataset folder)
target="/home" + str(fold_nam).lower()
print(target)
if not os.path.isdir(target):
os.mkdir(target)
print(request.files.getlist("file"))
for upload in request.files.getlist("file"):
print(upload)
print("{} is the file name".format(upload.filename))
filename = upload.filename
# This is to verify files are supported
ext = os.path.splitext(filename)[1]
if (ext == ".jpg") or (ext == ".png"):
print("File supported moving on...")
else:
render_template("Error.html", message="Files uploaded are not supported...")
destination = "/".join([target, filename])
print("Accept incoming file:", filename)
print("Save it to:", destination)
upload.save(destination)
# return send_from_directory("images", filename, as_attachment=True)
return render_template("complete.html", image_name=filename)
if __name__ == "__main__":
app.run(port=4555, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form id="frm1" action="/action_page.php">
Name: <input type="text" name="fname"><br>
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
<script type="text/javascript">
const realFileBtn = document.getElementById("real-file");
const customBtn = document.getElementById("custom-button");
const customTxt = document.getElementById("custom-text");
customBtn.addEventListener("click", function () {
realFileBtn.click();
});
realFileBtn.addEventListener("change", function () {
if (realFileBtn.value) {
customTxt.innerHTML = realFileBtn.value.match(
/[\/\\]([\w\d\s\.\-\(\)]+)$/
)[1];
} else {
customTxt.innerHTML = "No file chosen, yet.";
}
});
</script>
</form>
<div class="container">
<video id="video" width="300" height="300" autoplay="true"></video>
<button class="button" id="snap">Photo</button>
<canvas id="canvas" width="300" height="300"></canvas>
<br>
<a id="download" href="/images/myw3schoolsimage.jpg" download>download</a>
<div>
<input type="submit" value="Upload!" id="upload-button"><br>
</body>
<script>
$("#file-picker").change(function () {
var input = document.getElementById('file-picker');
for (var i = 0; i < input.files.length;i++) {
//koala.jpg, koala.JPG substring(index) lastIndexOf('a') koala.1.jpg
var ext = input.files[i].name.substring(input.files[i].name.lastIndexOf('.') + 1).toLowerCase()
if((ext == 'jpg') || (ext == 'png')) {
$("#msg").text("Files are supported")
}
else {
$("#msg").text("Files are NOT supported")
document.getElementById("file-picker").value = "";
}
}
});
</script>
<script src="./index.js"></script>
</html>
index.js
(() => {
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = document.getElementById("img")
var download = document.getElementById("download")
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
video.srcObject = stream;
video.play();
});
}
document.getElementById("snap").addEventListener("click", () => {
context.drawImage(video, 0, 0, 300, 300);
img.setAttribute("src", canvas.toDataURL("image/png"))
download.setAttribute("href", canvas.toDataURL("image/png"))
});
})()
All i want is to run the **index.html ** using flask with the camera running properly in localhost.
I know that my code is not in the finished state , but i'm stuck at this very place. I would like to mention that all my files are in proper directories and i have no indentation errors etc. Anyone who is willing to help is requested to mention every minute detail as I'm not very good at this .
Thankyou!
I tried many times to submit my app to Samsung but I always get rejected because the back button or exit button of the watch doesn't work.
My app is a multiple page in one single HTML, as explained in the Tizen Documentation.
I don't know if it's a problem with the code within the app.js file where a problem with the multiple page in one single HTML file.
App.js file:
( function () {
window.addEventListener( 'tizenhwkey', function( ev ) {
if( ev.keyName === "back" ) {
var page = document.getElementsByClassName( 'ui-page-active' )[0],
pageid = page ? page.id : "";
if( pageid === "main" ) {
try {
tizen.application.getCurrentApplication().exit();
} catch (ignore) {
}
} else {
tau.changePage("#main");
}
}
} );
} () );
index.html file:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,user-scalable=no">
<title>BRStocks</title>
<link rel="stylesheet" href="lib/tau/wearable/theme/default/tau.min.css">
<link rel="stylesheet" media="all and (-tizen-geometric-shape: circle)" href="lib/tau/wearable/theme/default/tau.circle.min.css">
<!-- load theme file for your application -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="ui-page ui-page-active" id="main">
<header>
<h2 class="ui-title">BR Stocks</h2>
</header>
<div class="ui-content content-padding">
<ul class="ui-listview">
<li>BVSP</li>
<li>IBOV</li>
<li>ABEV3</li>
<li>AZUL4</li>
<li>BTOW3</li>
</ul>
</div>
</div>
<div class="ui-page" id="two">
<span id='ABEV3'>START</span>
<header>
<h2 class="ui-title" id="title">Loading...</h2>
</header>
<div class="ui-content">
<div id="container">
<pre><span id="ticker"></span></pre>
<pre><span id="price"></span></pre>
<pre><span id="pctChange"></span></pre>
<a class="back" href="main" onClick="Clear();">Voltar</a>
</div>
</div>
</div>
<script>
function Clear()
{
document.getElementById('title').innerHTML="Loading...";
document.getElementById('ticker').innerHTML = '';
document.getElementById('price').innerHTML = '';
document.getElementById('pctChange').innerHTML = '';
}
function link(event) {
var element = event.target;
var ticker_id = element.getAttribute("ticker_id");
// do what you will with hike_id
console.log(ticker_id);
getPrice(ticker_id);
return;
}
function getPrice(y) {
if (self.fetch) {
console.log("fetch ok!")
fetch('xxxxxxxxxxxxxxxx')
.then(response => response.json())
.then(data => {
console.log("Fetching...")
//document.getElementById('title').innerHTML = data[y]['name']
var CompanyName = data[y]['name'];
var CompanyTicker = data[y]['ticker'];
var lastPrice = Number(data[y]['lastPrice']);
var pctChange = Number(data[y]['pctChange']);
pctChange = pctChange.toFixed(2);
document.getElementById('ticker').innerHTML = CompanyTicker;
document.getElementById('title').innerHTML = CompanyName;
document.getElementById('price').innerHTML = lastPrice.toLocaleString('pt-BR');
document.getElementById('pctChange').innerHTML = pctChange.replace('.',',') + '%';
if (pctChange < 0) {
console.log('Achou o sinal negativo');
document.getElementById('pctChange').className = 'redFont';
}else{
document.getElementById('pctChange').className = 'greenFont';
}
});
} else {
console.log("Something went wrong...")
}
}
function red(){
var elements = document.getElementById('pctChange').innerHTML;
console.log('Elemento: '+elements);
if (elements.includes('-')) {
console.log('Achou o sinal negativo');
document.getElementById('pctChange').className = 'redFont';
}else{
document.getElementById('pctChange').className = 'greenFont';
}
}
</script>
<script src="lib/tau/wearable/js/tau.min.js"></script>
<script src="js/app.js"></script>
<script src="js/lowBatteryCheck.js"></script>
<script src="js/circle-helper.js"></script>
<script type="text/javascript" src="jquery-3.4.1.min.js"></script>
</body>
</html>
The html file is pretty simple. The multiple page works with href pointing to id tags (in this case is #two and #main the pages).
For any reason, the button back in the emulator and real gadget is not working. Neither back to previous page, nor exit the application.
instead of
<a class="back" href="main" onClick="Clear();">Voltar</a>
try
<a class="back" href="main" ontouchend="Clear();">Voltar</a>
(I took a random eg in your code you can apply that change to every 'onClick' attribute)
I have just figure out that for the buttons to work (and also the function tizenhwkey) you have to setup the config.xml file of your project.
I have just added the line below:
<tizen:setting background-support="disable" encryption="disable" hwkey-event="enable"/>
And now the function and buttons work fine!
I'm trying to implement a simple speech to text and then text to speech as a response to the initial speech to text input!
I'm using code from another open source site for both the speech synthesis and text 2 speech, so I don't fully understand the code.
Basically, what is happening is that when I am finished speaking the input, I press the pause-record-btn which is supposed to trigger myFunction(), yet I have to press the button twice!
(I am VERY new to js but do understand a bit of front end development (css, html) so any help will be very appreciated )
Code Pen
/*-----------------------------
Voice Recognition Script
------------------------------*/
try {
var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
var recognition = new SpeechRecognition();
}
catch(e) {
console.error(e);
$('.no-browser-support').show();
$('.app').hide();
}
var noteTextarea = $('#note-textarea');
var instructions = $('#recording-instructions');
var notesList = $('ul#notes');
var noteContent = '';
// Get all notes from previous sessions and display them.
var notes = getAllNotes();
renderNotes(notes);
/*-----------------------------
Voice Recognition
------------------------------*/
// If false, the recording will stop after a few seconds of silence.
// When true, the silence period is longer (about 15 seconds),
// allowing us to keep recording even when the user pauses.
recognition.continuous = true;
// This block is called every time the Speech APi captures a line.
recognition.onresult = function(event) {
// event is a SpeechRecognitionEvent object.
// It holds all the lines we have captured so far.
// We only need the current one.
var current = event.resultIndex;
// Get a transcript of what was said.
var transcript = event.results[current][0].transcript;
// Add the current transcript to the contents of our Note.
// There is a weird bug on mobile, where everything is repeated twice.
// There is no official solution so far so we have to handle an edge case.
var mobileRepeatBug = (current == 1 && transcript == event.results[0][0].transcript);
if(!mobileRepeatBug) {
noteContent += transcript;
noteTextarea.val(noteContent);
}
};
recognition.onstart = function() {
instructions.text('Voice recognition activated. Try speaking into the microphone.');
}
recognition.onspeechend = function() {
instructions.text('You were quiet for a while so voice recognition turned itself off.');
}
recognition.onerror = function(event) {
if(event.error == 'no-speech') {
instructions.text('No speech was detected. Try again.');
};
}
/*-----------------------------
App buttons and input
------------------------------*/
$('#start-record-btn').on('click', function(e) {
if (noteContent.length) {
noteContent += ' ';
}
recognition.start();
});
$('#pause-record-btn').on('click', function(e) {
recognition.stop();
instructions.text('Voice recognition paused.');
});
// Sync the text inside the text area with the noteContent variable.
noteTextarea.on('input', function() {
noteContent = $(this).val();
})
$('#save-note-btn').on('click', function(e) {
recognition.stop();
if(!noteContent.length) {
instructions.text('Could not save empty note. Please add a message to your note.');
}
else {
// Save note to localStorage.
// The key is the dateTime with seconds, the value is the content of the note.
saveNote(new Date().toLocaleString(), noteContent);
// Reset variables and update UI.
noteContent = '';
renderNotes(getAllNotes());
noteTextarea.val('');
instructions.text('Note saved successfully.');
}
})
notesList.on('click', function(e) {
e.preventDefault();
var target = $(e.target);
// Listen to the selected note.
if(target.hasClass('listen-note')) {
var content = target.closest('.note').find('.content').text();
readOutLoud(content);
}
// Delete note.
if(target.hasClass('delete-note')) {
var dateTime = target.siblings('.date').text();
deleteNote(dateTime);
target.closest('.note').remove();
}
});
/*-----------------------------
Speech Synthesis
------------------------------*/
function readOutLoud(message) {
var speech = new SpeechSynthesisUtterance();
// Set the text and voice attributes.
speech.text = message;
speech.volume = 1;
speech.rate = 1;
speech.pitch = 1;
window.speechSynthesis.speak(speech);
}
/*-----------------------------
Helper Functions
------------------------------*/
function renderNotes(notes) {
var html = '';
if(notes.length) {
notes.forEach(function(note) {
html+= `<li class="note">
<p class="header">
<span class="date">${note.date}</span>
Listen to Note
Delete
</p>
<p class="content">${note.content}</p>
</li>`;
});
}
else {
html = '<li><p class="content">You don\'t have any notes yet.</p></li>';
}
notesList.html(html);
}
function saveNote(dateTime, content) {
localStorage.setItem('note-' + dateTime, content);
}
function getAllNotes() {
var notes = [];
var key;
for (var i = 0; i < localStorage.length; i++) {
key = localStorage.key(i);
if(key.substring(0,5) == 'note-') {
notes.push({
date: key.replace('note-',''),
content: localStorage.getItem(localStorage.key(i))
});
}
}
return notes;
}
function deleteNote(dateTime) {
localStorage.removeItem('note-' + dateTime);
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Voice Controlled Notes App</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src='https://code.responsivevoice.org/responsivevoice.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/shoelace-css/1.0.0-beta16/shoelace.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Voice Controlled Notes App</h1>
<p class="page-description">A tiny app that allows you to take notes by recording your voice</p>
<h3 class="no-browser-support">Sorry, Your Browser Doesn't Support the Web Speech API. Try Opening This Demo In Google Chrome.</h3>
<div class="app">
<h3>Add New Note</h3>
<div class="input-single">
<textarea id="note-textarea" placeholder="Input." rows="6"></textarea>
</div>
<button id="start-record-btn" title="Start Recording">Start Recognition</button>
<button id="pause-record-btn" onClick="myFunction()" title="Pause Recording">Stop listening</button>
<p id="recording-instructions">Press the <strong>Start Recognition</strong> button and allow access.</p>
</div>
</div>
<p id="demo"></p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="script.js"></script>
<script>
function myFunction() {
var str = document.getElementById("note-textarea").value;
if (str.includes("hello how are you")){
document.getElementById("demo").innerHTML = "hi anthony";
responsiveVoice.speak("I am good thanks, and you?");
}
}
</script>
</body>
</html>