not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
14 KiB

  1. define(["sugar-web/graphics/palette","sugar-web/env","webL10n","sugar-web/datastore","sugar-web/activity/activity"], function (palette,env,l10n,datastore,activity) {
  2. var canvas = document.getElementById("canvas");
  3. var ctx = canvas.getContext('2d');
  4. canvas.width = window.innerWidth;
  5. canvas.height = window.innerHeight-55;
  6. var windowWidth = canvas.getBoundingClientRect().width;
  7. var windowHeight = canvas.getBoundingClientRect().height;
  8. var shiftY = 45;
  9. var radiusEye = Math.min(windowWidth,windowHeight)/6.5;
  10. var radiusEyeball = Math.min(windowWidth,windowHeight)/28;
  11. var eyePos = [{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0}];
  12. var mouthStart = {x:windowWidth*1.35/4,y:shiftY+windowHeight*2/3.0};
  13. var mouthEnd = {x:windowWidth*2.65/4,y:shiftY+windowHeight*2/3.0};
  14. var noOfEyes = 2;
  15. var colors;
  16. var awake = true;
  17. var idletimer;
  18. activity.getXOColor(function (error, retcolors) {
  19. colors = retcolors;
  20. });
  21. function idleTimer() {
  22. awake = true;
  23. clearInterval(idletimer);
  24. idletimer = setInterval(function () {
  25. awake = false;
  26. var language = document.getElementById('speaklang').innerHTML;
  27. var text = l10n.get("Sleepy");
  28. speech.playVoice(language, text);
  29. clearInterval(idletimer);
  30. },60000*2)
  31. }
  32. $(window).resize(function() {
  33. canvas.width = window.innerWidth;
  34. canvas.height = window.innerHeight-55;
  35. windowWidth = canvas.getBoundingClientRect().width;
  36. windowHeight = canvas.getBoundingClientRect().height;
  37. mouthStart = {x:windowWidth*1.35/4,y:shiftY+windowHeight*2/3.0};
  38. mouthEnd = {x:windowWidth*2.65/4,y:shiftY+windowHeight*2/3.0};
  39. radiusEye = Math.min(windowWidth,windowHeight)/6.5;
  40. radiusEyeball = Math.min(windowWidth,windowHeight)/28;
  41. setEyes();
  42. })
  43. canvas.addEventListener('mousemove', function(evt) {
  44. setMousePosition(canvas, evt);
  45. }, false);
  46. // Detect if the browser is IE or not
  47. var IE = document.all?true:false
  48. var mouseX = -1,mouseY = -1;
  49. var mouthYdiff = 0.0;
  50. var mouthDirection = 1;
  51. var mouthTimeout;
  52. var speech = null;
  53. var sugarSettings = {};
  54. var first = true;
  55. function init(){
  56. speech = Speech();
  57. env.getEnvironment(function(err, environment) {
  58. var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language;
  59. if (!environment.user) environment.user = { language: defaultLanguage };
  60. sugarSettings = environment.user;
  61. speech.init(sugarSettings);
  62. // If not IE, setup mouse for capture
  63. if (!IE){
  64. document.captureEvents(Event.MOUSEMOVE)
  65. }
  66. var FPS = 30;
  67. setInterval(function() {
  68. updateCanvas();
  69. }, 1000/FPS);
  70. window.addEventListener('localized', function() {
  71. if (first) {
  72. l10n.language.code = sugarSettings.language;
  73. first = false;
  74. return;
  75. } else {
  76. localize();
  77. var timer = window.setTimeout(function() {
  78. window.clearTimeout(timer);
  79. var language = document.getElementById('speaklang').innerHTML;
  80. var text = l10n.get("TypeSomething", {name:sugarSettings.name});
  81. document.getElementById("combo-box").title = l10n.get("SavedTalk"); // Localized Saved talk title.
  82. document.getElementsByClassName("dropdown").title = l10n.get("SavedTalk"); // Localized Saved talk title.
  83. speech.playVoice(language, text);
  84. moveMouth(text);
  85. }, 100);
  86. }
  87. });
  88. });
  89. idleTimer();
  90. }
  91. function hidePalettes(){
  92. var palettes = document.getElementsByClassName('palette');
  93. for(var i=0;i<palettes.length;i++){
  94. palettes[i].style.visibility="hidden";
  95. }
  96. }
  97. document.getElementById('userArea').onmouseup = function(e){
  98. hidePalettes();
  99. }
  100. function setEyes(eyes){
  101. var i;
  102. var rect = canvas.getBoundingClientRect();
  103. var width = rect.width - rect.width/4.5;
  104. var height = rect.height;
  105. var center = rect.width/2;
  106. var offset = (width*(eyes)/(5))/(eyes-1); //The max offset with 5 eyes
  107. //console.log(offset);
  108. if(eyes%2 == 0){
  109. for(i=0;i<Math.floor(eyes/2);i++){
  110. eyePos[i+1].x = (center - offset/2) - (Math.floor(eyes/2)-i-1)*offset;
  111. eyePos[i+1].y = shiftY+height/3;
  112. }
  113. for(i=0;i<Math.floor(eyes/2);i++){
  114. eyePos[i+Math.floor(eyes/2)+1].x = (center + offset/2) + i*offset;
  115. eyePos[i+Math.floor(eyes/2)+1].y = shiftY+height/3;
  116. }
  117. }
  118. if(eyes%2 == 1){
  119. eyePos[1].x = center;
  120. eyePos[1].y = shiftY+height/3;
  121. for(i=0;i<Math.floor(eyes/2);i++){
  122. eyePos[i+2].x = center - (Math.floor(eyes/2)-i)*offset;
  123. eyePos[i+2].y = shiftY+height/3;
  124. }
  125. for(i=0;i<Math.floor(eyes/2);i++){
  126. //console.log(i+Math.floor(eyes/2)+2);
  127. eyePos[i+Math.floor(eyes/2)+2].x = center + (i+1)*offset;
  128. eyePos[i+Math.floor(eyes/2)+2].y = shiftY+height/3;
  129. }
  130. }
  131. //console.log(eyePos[1]);
  132. }
  133. function setMousePosition(canvas, evt){
  134. var rect = canvas.getBoundingClientRect();
  135. mouseX = (evt.clientX - rect.left)*canvas.width/rect.width;
  136. mouseY = (evt.clientY - rect.top)*canvas.height/rect.height;
  137. }
  138. function drawEyes(){
  139. if(awake) {
  140. var i;
  141. var eyetype = document.getElementById('eyetype').innerHTML;
  142. for(i=1;i<=noOfEyes;i++){
  143. ctx.beginPath();
  144. ctx.fillStyle="#000000";
  145. if (eyetype == 1) {
  146. ctx.arc(eyePos[i].x,eyePos[i].y,radiusEye*1.1,0,2*Math.PI);
  147. ctx.fill();
  148. } else {
  149. var rectsize = radiusEye*1.1;
  150. ctx.fillRect(eyePos[i].x-rectsize,eyePos[i].y-rectsize,rectsize*2,rectsize*2);
  151. }
  152. ctx.closePath();
  153. }
  154. for(i=1;i<=noOfEyes;i++){
  155. ctx.beginPath();
  156. ctx.fillStyle="#FFFFFF";
  157. if (eyetype == 1) {
  158. ctx.arc(eyePos[i].x,eyePos[i].y,radiusEye,0,2*Math.PI);
  159. ctx.fill();
  160. } else {
  161. var rectsize = radiusEye;
  162. ctx.fillRect(eyePos[i].x-rectsize,eyePos[i].y-rectsize,rectsize*2,rectsize*2);
  163. }
  164. ctx.closePath();
  165. }
  166. } else {
  167. for(i=1;i<=noOfEyes;i++){
  168. var i;
  169. ctx.beginPath();
  170. ctx.arc(eyePos[i].x,eyePos[i].y,radiusEye*1.1,0.4,Math.PI-0.4);
  171. ctx.lineWidth = 20;
  172. ctx.stroke();
  173. ctx.closePath();
  174. }
  175. }
  176. }
  177. function getEyeballOffset(eye){ //eye=1 for the first eye and so on...
  178. var offsetX,offsetY;
  179. var baseoffset = 0.30*windowWidth/(noOfEyes+2);
  180. var ratio = (1)/(noOfEyes+2);
  181. if(mouseX == -1 && mouseY == -1){
  182. offsetX = 0;
  183. offsetY = 0;
  184. }
  185. else{
  186. offsetX = mouseX - eyePos[eye]['x'];
  187. offsetY = mouseY - eyePos[eye]['y'];
  188. }
  189. var xMult=1,yMult=1;
  190. if(offsetX < 0){
  191. xMult = -1;
  192. }
  193. if(offsetY < 0){
  194. yMult = -1;
  195. }
  196. var angle = Math.atan(Math.abs(offsetY/offsetX));
  197. if(isNaN(angle)){
  198. angle = 0.0;
  199. }
  200. return {x:xMult*Math.min((radiusEye-radiusEyeball)*Math.cos(angle),Math.abs(offsetX)),
  201. y:yMult*Math.min((radiusEye-radiusEyeball)*Math.sin(angle),Math.abs(offsetY))}
  202. }
  203. function drawEyeballs(){
  204. if(awake) {
  205. var i;
  206. for(i=1;i<=noOfEyes;i++){
  207. ctx.beginPath();
  208. ctx.fillStyle="#000000";
  209. ctx.arc(eyePos[i].x + getEyeballOffset(i).x,eyePos[i].y + getEyeballOffset(i).y,radiusEyeball,0,2*Math.PI);
  210. ctx.fill();
  211. ctx.closePath();
  212. }
  213. }
  214. }
  215. document.getElementById('speakText').onmousedown = function(e){
  216. var language = document.getElementById('speaklang').innerHTML;
  217. var text = document.getElementById('userText').value;
  218. speech.playVoice(language, text);
  219. idleTimer();
  220. }
  221. document.getElementById('speakText').onmouseup = function(e){
  222. var text = document.getElementById('userText').value;
  223. moveMouth(text);
  224. if(document.getElementById('mode').innerHTML == "3"){
  225. addToChat();
  226. }
  227. }
  228. document.getElementById('userText').onkeypress = function(e) {
  229. var key = e.keyCode || e.which;
  230. if (key == 13) {
  231. var language = document.getElementById('speaklang').innerHTML;
  232. var text = document.getElementById('userText').value;
  233. speech.playVoice(language, text);
  234. moveMouth(text);
  235. idleTimer();
  236. if(document.getElementById('mode').innerHTML == "3"){
  237. addToChat();
  238. }
  239. }
  240. }
  241. document.getElementById('userText').oninput = function(e) {
  242. var bounding = this.getBoundingClientRect();
  243. var position = { clientX: bounding.left + 20*document.getElementById('userText').selectionStart, clientY: bounding.top };
  244. setMousePosition(canvas, position);
  245. updateCanvas();
  246. }
  247. document.getElementById('userText').addEventListener('mousemove', function(evt) {
  248. setMousePosition(canvas, evt);
  249. updateCanvas();
  250. }, false);
  251. document.getElementById('gamemode1-button').onmouseup = function(e){
  252. //The type something to hear it mode
  253. document.getElementById('mode').innerHTML = "1";
  254. document.getElementById('canvas').style.display = "block";
  255. closeChat();
  256. }
  257. document.getElementById('gamemode2-button').onmouseup = function(e){
  258. //The robot mode
  259. document.getElementById('mode').innerHTML = "2";
  260. document.getElementById('canvas').style.display = "block";
  261. closeChat();
  262. }
  263. document.getElementById('gamemode3-button').onmouseup = function(e){
  264. //The chat mode
  265. document.getElementById('mode').innerHTML = "3";
  266. document.getElementById('canvas').style.display = "none";
  267. setupChat();
  268. }
  269. function setupChat(){
  270. document.getElementById('chat').style.display = "block";
  271. }
  272. function closeChat(){
  273. document.getElementById('chat').style.display = "none";
  274. }
  275. function addToChat(){
  276. var text = document.getElementById('userText').value;
  277. var chatbox = document.getElementById('chatbox');
  278. var li = document.createElement("li");
  279. li.style.borderRadius = "10px";
  280. li.style.backgroundColor = "#999999";
  281. li.style.listStyleType = "none";
  282. li.style.padding = "15px";
  283. li.style.margin = "-15px";
  284. li.appendChild(document.createTextNode(text));
  285. chatbox.appendChild(li);
  286. }
  287. function animateMouth(speed){
  288. //console.log('animateMouthcalled');
  289. if(document.getElementById('speaking').innerHTML == "0"){
  290. clearInterval(mouthTimeout);
  291. mouthYdiff = 0;
  292. }
  293. var change = speed/70+1;
  294. change = Math.min(4,change);
  295. change = Math.max(1,change);
  296. if(mouthDirection==1){
  297. mouthYdiff -= change;
  298. if(mouthYdiff<-40){
  299. mouthDirection = 2;
  300. }
  301. }
  302. else if(mouthDirection==2){
  303. mouthYdiff += change;
  304. if(mouthYdiff>40){
  305. mouthDirection = 1;
  306. }
  307. }
  308. }
  309. function startMouthAnim(){
  310. var speed = document.getElementById('rate').innerHTML;
  311. var interval = 0.01;
  312. document.getElementById('speaking').innerHTML = 1;
  313. mouthTimeout = setInterval(function(){
  314. animateMouth(speed);
  315. },interval*1000);
  316. }
  317. function moveMouth(text){
  318. if(text != ""){
  319. if(document.getElementById('mode').innerHTML=="2"){
  320. setTimeout(function(){
  321. startMouthAnim();
  322. }, 4000);
  323. }
  324. else{
  325. startMouthAnim();
  326. }
  327. }
  328. }
  329. function drawMouth(){
  330. ctx.beginPath();
  331. ctx.moveTo(mouthStart.x,mouthStart.y);
  332. ctx.bezierCurveTo(mouthStart.x+100,mouthStart.y+mouthYdiff,mouthEnd.x-100,mouthEnd.y+mouthYdiff,mouthEnd.x,mouthEnd.y);
  333. ctx.lineWidth = 10;
  334. ctx.stroke();
  335. ctx.closePath();
  336. ctx.beginPath();
  337. ctx.moveTo(mouthStart.x,mouthStart.y);
  338. ctx.bezierCurveTo(mouthStart.x+100,mouthStart.y-mouthYdiff,mouthEnd.x-100,mouthEnd.y-mouthYdiff,mouthEnd.x,mouthEnd.y);
  339. ctx.lineWidth = 10;
  340. ctx.stroke();
  341. ctx.closePath();
  342. }
  343. function updateCanvas(){
  344. clearCanvas();
  345. noOfEyes = parseInt(document.getElementById('numeyes').innerHTML);
  346. setEyes(noOfEyes);
  347. drawEyes();
  348. drawEyeballs();
  349. drawMouth();
  350. }
  351. function clearCanvas(){
  352. ctx.clearRect(0, 0, canvas.width, canvas.height);
  353. ctx.beginPath();
  354. ctx.rect(0, 0, canvas.width, canvas.height);
  355. ctx.fillStyle = colors["fill"];
  356. ctx.fill();
  357. }
  358. function localize() {
  359. document.getElementById('gamemode1-button').title = l10n.get("TypeSomethingToHear");
  360. document.getElementById('gamemode2-button').title = l10n.get("AskRobot");
  361. document.getElementById('gamemode3-button').title = l10n.get("VoiceChat");
  362. document.getElementById('language-button').title = l10n.get("Language");
  363. document.getElementById('speech-button').title = l10n.get("Speech");
  364. document.getElementById('face-button').title = l10n.get("Face");
  365. document.getElementById('ratelabel').innerHTML = l10n.get("ratelabel");
  366. document.getElementById('pitchlabel').innerHTML = l10n.get("pitchlabel");
  367. document.getElementById('eyesnumber').innerHTML = l10n.get("eyesnumber");
  368. document.getElementById('eyes').title = l10n.get("eyes");
  369. document.getElementById('glasses').title = l10n.get("glasses");
  370. document.getElementById('speakText').title = l10n.get("speak");
  371. document.getElementById('lang-en').innerHTML = l10n.get('langen');
  372. document.getElementById('lang-ca').innerHTML = l10n.get('langca');
  373. document.getElementById('lang-cs').innerHTML = l10n.get('langcs');
  374. document.getElementById('lang-de').innerHTML = l10n.get('langde');
  375. document.getElementById('lang-el').innerHTML = l10n.get('langel');
  376. document.getElementById('lang-eo').innerHTML = l10n.get('langeo');
  377. document.getElementById('lang-es').innerHTML = l10n.get('langes');
  378. document.getElementById('lang-fi').innerHTML = l10n.get('langfi');
  379. document.getElementById('lang-fr').innerHTML = l10n.get('langfr');
  380. document.getElementById('lang-hu').innerHTML = l10n.get('langhu');
  381. document.getElementById('lang-it').innerHTML = l10n.get('langit');
  382. document.getElementById('lang-kn').innerHTML = l10n.get('langkn');
  383. document.getElementById('lang-la').innerHTML = l10n.get('langla');
  384. document.getElementById('lang-lv').innerHTML = l10n.get('langlv');
  385. document.getElementById('lang-nl').innerHTML = l10n.get('langnl');
  386. document.getElementById('lang-pl').innerHTML = l10n.get('langpl');
  387. document.getElementById('lang-pt').innerHTML = l10n.get('langpt');
  388. document.getElementById('lang-ro').innerHTML = l10n.get('langro');
  389. document.getElementById('lang-sk').innerHTML = l10n.get('langsk');
  390. document.getElementById('lang-sv').innerHTML = l10n.get('langsv');
  391. document.getElementById('lang-tr').innerHTML = l10n.get('langtr');
  392. document.getElementById('lang-zh').innerHTML = l10n.get('langzh');
  393. }
  394. init();
  395. });