example-telemetry-resultSharing.html 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no" />
  6. <title>HTML5 Speedtest</title>
  7. <style type="text/css">
  8. html,body{
  9. border:none; padding:0; margin:0;
  10. background:#FFFFFF;
  11. color:#202020;
  12. }
  13. body{
  14. text-align:center;
  15. font-family:"Roboto",sans-serif;
  16. }
  17. h1{
  18. color:#404040;
  19. }
  20. #startStopBtn{
  21. display:inline-block;
  22. margin:0 auto;
  23. color:#6060AA;
  24. background-color:rgba(0,0,0,0);
  25. border:0.15em solid #6060FF;
  26. border-radius:0.3em;
  27. transition:all 0.3s;
  28. box-sizing:border-box;
  29. width:8em; height:3em;
  30. line-height:2.7em;
  31. cursor:pointer;
  32. box-shadow: 0 0 0 rgba(0,0,0,0.1), inset 0 0 0 rgba(0,0,0,0.1);
  33. }
  34. #startStopBtn:hover{
  35. box-shadow: 0 0 2em rgba(0,0,0,0.1), inset 0 0 1em rgba(0,0,0,0.1);
  36. }
  37. #startStopBtn.running{
  38. background-color:#FF3030;
  39. border-color:#FF6060;
  40. color:#FFFFFF;
  41. }
  42. #startStopBtn:before{
  43. content:"Start";
  44. }
  45. #startStopBtn.running:before{
  46. content:"Abort";
  47. }
  48. #test{
  49. margin-top:2em;
  50. margin-bottom:12em;
  51. }
  52. div.testArea{
  53. display:inline-block;
  54. width:16em;
  55. height:12.5em;
  56. position:relative;
  57. box-sizing:border-box;
  58. }
  59. div.testName{
  60. position:absolute;
  61. top:0.1em; left:0;
  62. width:100%;
  63. font-size:1.4em;
  64. z-index:9;
  65. }
  66. div.meterText{
  67. position:absolute;
  68. bottom:1.55em; left:0;
  69. width:100%;
  70. font-size:2.5em;
  71. z-index:9;
  72. }
  73. div.meterText:empty:before{
  74. content:"0.00";
  75. }
  76. div.unit{
  77. position:absolute;
  78. bottom:2em; left:0;
  79. width:100%;
  80. z-index:9;
  81. }
  82. div.testArea canvas{
  83. position:absolute;
  84. top:0; left:0; width:100%; height:100%;
  85. z-index:1;
  86. }
  87. div.testGroup{
  88. display:inline-block;
  89. }
  90. #shareArea{
  91. width:95%;
  92. max-width:40em;
  93. margin:0 auto;
  94. margin-top:2em;
  95. }
  96. #shareArea > *{
  97. display:block;
  98. width:100%;
  99. height:auto;
  100. margin: 0.25em 0;
  101. }
  102. @media all and (max-width:65em){
  103. body{
  104. font-size:1.5vw;
  105. }
  106. }
  107. @media all and (max-width:40em){
  108. body{
  109. font-size:0.8em;
  110. }
  111. div.testGroup{
  112. display:block;
  113. margin: 0 auto;
  114. }
  115. }
  116. </style>
  117. <script type="text/javascript">
  118. function I(id){return document.getElementById(id);}
  119. var meterBk="#E0E0E0";
  120. var dlColor="#6060AA",
  121. ulColor="#309030",
  122. pingColor="#AA6060",
  123. jitColor="#AA6060";
  124. var progColor="#EEEEEE";
  125. //CODE FOR GAUGES
  126. function drawMeter(c,amount,bk,fg,progress,prog){
  127. var ctx=c.getContext("2d");
  128. var dp=window.devicePixelRatio||1;
  129. var cw=c.clientWidth*dp, ch=c.clientHeight*dp;
  130. var sizScale=ch*0.0055;
  131. if(c.width==cw&&c.height==ch){
  132. ctx.clearRect(0,0,cw,ch);
  133. }else{
  134. c.width=cw;
  135. c.height=ch;
  136. }
  137. ctx.beginPath();
  138. ctx.strokeStyle=bk;
  139. ctx.lineWidth=16*sizScale;
  140. ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,Math.PI*0.1);
  141. ctx.stroke();
  142. ctx.beginPath();
  143. ctx.strokeStyle=fg;
  144. ctx.lineWidth=16*sizScale;
  145. ctx.arc(c.width/2,c.height-58*sizScale,c.height/1.8-ctx.lineWidth,-Math.PI*1.1,amount*Math.PI*1.2-Math.PI*1.1);
  146. ctx.stroke();
  147. if(typeof progress !== "undefined"){
  148. ctx.fillStyle=prog;
  149. ctx.fillRect(c.width*0.3,c.height-16*sizScale,c.width*0.4*progress,4*sizScale);
  150. }
  151. }
  152. function mbpsToAmount(s){
  153. return 1-(1/(Math.pow(1.3,Math.sqrt(s))));
  154. }
  155. function msToAmount(s){
  156. return 1-(1/(Math.pow(1.08,Math.sqrt(s))));
  157. }
  158. //SPEEDTEST AND UI CODE
  159. var w=null; //speedtest worker
  160. var data=null; //data from worker
  161. var testParameters={
  162. telemetry_level:"basic"
  163. //Optional: add more test parameters here
  164. }
  165. function startStop(){
  166. if(w!=null){
  167. //speedtest is running, abort
  168. w.postMessage('abort');
  169. w=null;
  170. data=null;
  171. I("startStopBtn").className="";
  172. initUI();
  173. }else{
  174. //test is not running, begin
  175. w=new Worker('speedtest_worker.min.js');
  176. w.postMessage('start '+JSON.stringify(testParameters));
  177. I("startStopBtn").className="running";
  178. I("shareArea").style.display="none";
  179. w.onmessage=function(e){
  180. data=JSON.parse(e.data);
  181. var status=data.testState;
  182. if(status>=4){
  183. //test completed
  184. I("startStopBtn").className="";
  185. w=null;
  186. updateUI(true);
  187. if(status==4){
  188. //if testId is present, show sharing panel, otherwise do nothing
  189. try{
  190. var testId=Number(data.testId);
  191. if(!isNaN(testId)){
  192. var shareURL=window.location.href.substring(0,window.location.href.lastIndexOf("/"))+"/results/?id="+testId;
  193. I("resultsImg").src=shareURL;
  194. I("resultsURL").value=shareURL;
  195. I("testId").innerHTML=testId;
  196. I("shareArea").style.display="block";
  197. }
  198. }catch(e){}
  199. }
  200. }
  201. };
  202. }
  203. }
  204. //this function reads the data sent back by the worker and updates the UI
  205. function updateUI(forced){
  206. if(!forced&&(!data||!w)) return;
  207. var status=data.testState;
  208. I("ip").textContent=data.clientIp;
  209. I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
  210. drawMeter(I("dlMeter"),mbpsToAmount(Number(data.dlStatus*(status==1?oscillate():1))),meterBk,dlColor,Number(data.dlProgress),progColor);
  211. I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
  212. drawMeter(I("ulMeter"),mbpsToAmount(Number(data.ulStatus*(status==3?oscillate():1))),meterBk,ulColor,Number(data.ulProgress),progColor);
  213. I("pingText").textContent=data.pingStatus;
  214. drawMeter(I("pingMeter"),msToAmount(Number(data.pingStatus*(status==2?oscillate():1))),meterBk,pingColor,Number(data.pingProgress),progColor);
  215. I("jitText").textContent=data.jitterStatus;
  216. drawMeter(I("jitMeter"),msToAmount(Number(data.jitterStatus*(status==2?oscillate():1))),meterBk,jitColor,Number(data.pingProgress),progColor);
  217. }
  218. function oscillate(){
  219. return 1+0.02*Math.sin(Date.now()/100);
  220. }
  221. //poll the status from the worker (this will call updateUI)
  222. setInterval(function(){
  223. if(w) w.postMessage('status');
  224. },200);
  225. //update the UI every frame
  226. window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||(function(callback,element){setTimeout(callback,1000/60);});
  227. function frame(){
  228. requestAnimationFrame(frame);
  229. updateUI();
  230. }
  231. frame(); //start frame loop
  232. //function to (re)initialize UI
  233. function initUI(){
  234. drawMeter(I("dlMeter"),0,meterBk,dlColor,0);
  235. drawMeter(I("ulMeter"),0,meterBk,ulColor,0);
  236. drawMeter(I("pingMeter"),0,meterBk,pingColor,0);
  237. drawMeter(I("jitMeter"),0,meterBk,jitColor,0);
  238. I("dlText").textContent="";
  239. I("ulText").textContent="";
  240. I("pingText").textContent="";
  241. I("jitText").textContent="";
  242. I("ip").textContent="";
  243. }
  244. </script>
  245. </head>
  246. <body>
  247. <h1>HTML5 Speedtest - Telemetry and sharing example</h1>
  248. <div id="startStopBtn" onclick="startStop()"></div>
  249. <div id="test">
  250. <div class="testGroup">
  251. <div class="testArea">
  252. <div class="testName">Download</div>
  253. <canvas id="dlMeter" class="meter"></canvas>
  254. <div id="dlText" class="meterText"></div>
  255. <div class="unit">Mbps</div>
  256. </div>
  257. <div class="testArea">
  258. <div class="testName">Upload</div>
  259. <canvas id="ulMeter" class="meter"></canvas>
  260. <div id="ulText" class="meterText"></div>
  261. <div class="unit">Mbps</div>
  262. </div>
  263. </div>
  264. <div class="testGroup">
  265. <div class="testArea">
  266. <div class="testName">Ping</div>
  267. <canvas id="pingMeter" class="meter"></canvas>
  268. <div id="pingText" class="meterText"></div>
  269. <div class="unit">ms</div>
  270. </div>
  271. <div class="testArea">
  272. <div class="testName">Jitter</div>
  273. <canvas id="jitMeter" class="meter"></canvas>
  274. <div id="jitText" class="meterText"></div>
  275. <div class="unit">ms</div>
  276. </div>
  277. </div>
  278. <div id="ipArea">
  279. IP Address: <span id="ip"></span>
  280. </div>
  281. <div id="shareArea" style="display:none">
  282. <h3>Share results</h3>
  283. <p>Test ID: <span id="testId"></span></p>
  284. <input type="text" value="" id="resultsURL" readonly="readonly" onclick="this.select();this.focus();this.select();document.execCommand('copy');alert('Link copied')"/>
  285. <img src="" id="resultsImg" />
  286. </div>
  287. </div>
  288. <div>Basic telemetry is active; results will be saved in your database, without the full log. If the results don't appear, or the sharing panel doesn't appear at the end of the test, check the settings in telemetry_settings.php</div>
  289. <a href="https://github.com/adolfintel/speedtest">Source code</a>
  290. <script type="text/javascript">setTimeout(initUI,100);</script>
  291. </body>
  292. </html>