javascript - 如何用 JavaScript 画一个简单的尺子?

标签 javascript android html cordova canvas

我从 PhoneGap 开始,尝试一个简单的应用程序,即标尺。我是 JavaScript 初学者,我的大部分移动工作都是使用原生 Android 代码,但我对此绞尽脑汁,无法弄清楚出了什么问题。

由于屏幕尺寸不同,我的想法是计算一毫米(pixelsInMm)中有多少像素,得到屏幕的高度,并使用 HTML5 Canvas 每 N 个像素画一条线。

我的 HTML 正文很简单, Canvas 填满了整个屏幕

  <body onload="init();" id="stage" class="theme">     
  <canvas id="myCanvas" style="width: 100%;height: 100%;"></canvas>
  </body>

我已经弄清楚如何获取设备每英寸像素的密度 (dpi),并使用简单的数学方法我们可以得到一厘米中有多少个像素

var mmInInch = 25.399999999972568;
function getPixelsPerMillimeter(dpi){
    return dpi/mmInInch;        
}

我的 js 文件的其余部分也很简单

var heightInPixels;
var heightDensity;

获取高度密度(以每英寸像素为单位)

function getDeviceResolution(){
    heightDensity = window.MyConnectorClass.getYdpi();
    heightInPixels = window.outerHeight;
    console.log("Y density = " + heightDensity);
    console.log("Y pixels = " + heightInPixels);
    return heightDensity;
}

在给定的 Canvas 和 y 坐标中绘制一条水平线

function drawOnCanvas(ctx2d,y){
    console.log("Drawing on :" + y)     
    ctx2d.moveTo(0,y);
    ctx2d.lineTo(20,y);
    ctx2d.stroke();
}

我的主循环,在每个 ppm 处绘制一条水平线。

function drawRuler(){
    console.log("append Ruler")         
    var YDpi = getDeviceResolution();
    var ppm = getPixelsPerMillimeter(YDpi);
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    ctx.lineWidth = 1;
    for(var i=0; i<90; i++){         
      var topPos = (5+ i*ppm);
      console.log("topPos" + topPos);
      drawOnCanvas(ctx,topPos);     
    };
}

但是,正如您在下图中看到的那样,我得到的并不是预期的标尺,而是线条间隔非常大,与我预期的 1 毫米相差甚远。为什么?而且它绘制的线条有不同的尺寸,而且它们的宽度肯定不是 1px。

enter image description here

这是显示计算正确的 logcat,我正在高度为 800px、屏幕高度为 93mm 的 Galaxy S2 中进行测试,因此每 8.6 像素就有 1 毫米。

09-22 \n:16.530: D/test(12353): ppm:8.602150744349842
09-22 \n:16.530: D/test(12353): mmSize:93.0
09-22 \n:16.530: D/test(12353): Pos0: 5.0px
09-22 \n:16.530: D/test(12353): Pos1: 13.602150744349842px
09-22 \n:16.530: D/test(12353): Pos2: 22.204301488699684px
09-22 \n:16.530: D/test(12353): Pos3: 30.806452233049527px
09-22 \n:16.530: D/test(12353): Pos4: 39.40860297739937px
09-22 \n:16.530: D/test(12353): Pos5: 48.01075372174921px
09-22 \n:16.530: D/test(12353): Pos6: 56.61290446609905px
09-22 \n:16.535: D/test(12353): Pos7: 65.2150552104489px
09-22 \n:16.535: D/test(12353): Pos8: 73.81720595479874px
09-22 \n:16.535: D/test(12353): Pos9: 82.41935669914858px
09-22 \n:16.535: D/test(12353): Pos10: 91.02150744349842px
09-22 \n:16.535: D/test(12353): Pos11: 99.62365818784826px
09-22 \n:16.535: D/test(12353): Pos12: 108.2258089321981px
09-22 \n:16.535: D/test(12353): Pos13: 116.82795967654795px
09-22 \n:16.535: D/test(12353): Pos14: 125.43011042089779px
09-22 \n:16.535: D/test(12353): Pos15: 134.03226116524763px
09-22 \n:16.540: D/test(12353): Pos16: 142.63441190959747px
09-22 \n:16.540: D/test(12353): Pos17: 151.23656265394732px
09-22 \n:16.540: D/test(12353): Pos18: 159.83871339829716px
09-22 \n:16.540: D/test(12353): Pos19: 168.440864142647px
09-22 \n:16.540: D/test(12353): Pos20: 177.04301488699684px
09-22 \n:16.540: D/test(12353): Pos21: 185.64516563134669px
09-22 \n:16.540: D/test(12353): Pos22: 194.24731637569653px
09-22 \n:16.540: D/test(12353): Pos23: 202.84946712004637px
09-22 \n:16.540: D/test(12353): Pos24: 211.4516178643962px
09-22 \n:16.540: D/test(12353): Pos25: 220.05376860874605px
09-22 \n:16.540: D/test(12353): Pos26: 228.6559193530959px
09-22 \n:16.540: D/test(12353): Pos27: 237.25807009744574px
09-22 \n:16.540: D/test(12353): Pos28: 245.86022084179558px
09-22 \n:16.540: D/test(12353): Pos29: 254.46237158614542px
09-22 \n:16.540: D/test(12353): Pos30: 263.06452233049527px
09-22 \n:16.540: D/test(12353): Pos31: 271.6666730748451px
09-22 \n:16.540: D/test(12353): Pos32: 280.26882381919495px
09-22 \n:16.540: D/test(12353): Pos33: 288.8709745635448px
09-22 \n:16.540: D/test(12353): Pos34: 297.47312530789463px
09-22 \n:16.540: D/test(12353): Pos35: 306.0752760522445px
09-22 \n:16.540: D/test(12353): Pos36: 314.6774267965943px
09-22 \n:16.540: D/test(12353): Pos37: 323.27957754094416px
09-22 \n:16.540: D/test(12353): Pos38: 331.881728285294px
09-22 \n:16.540: D/test(12353): Pos39: 340.48387902964384px
09-22 \n:16.540: D/test(12353): Pos40: 349.0860297739937px
09-22 \n:16.540: D/test(12353): Pos41: 357.68818051834353px
09-22 \n:16.540: D/test(12353): Pos42: 366.29033126269337px
09-22 \n:16.540: D/test(12353): Pos43: 374.8924820070432px
09-22 \n:16.540: D/test(12353): Pos44: 383.49463275139306px
09-22 \n:16.540: D/test(12353): Pos45: 392.0967834957429px
09-22 \n:16.545: D/test(12353): Pos46: 400.69893424009274px
09-22 \n:16.545: D/test(12353): Pos47: 409.3010849844426px
09-22 \n:16.545: D/test(12353): Pos48: 417.9032357287924px
09-22 \n:16.545: D/test(12353): Pos49: 426.50538647314227px
09-22 \n:16.545: D/test(12353): Pos50: 435.1075372174921px
09-22 \n:16.545: D/test(12353): Pos51: 443.70968796184195px
09-22 \n:16.545: D/test(12353): Pos52: 452.3118387061918px
09-22 \n:16.545: D/test(12353): Pos53: 460.91398945054164px
09-22 \n:16.545: D/test(12353): Pos54: 469.5161401948915px
09-22 \n:16.545: D/test(12353): Pos55: 478.1182909392413px
09-22 \n:16.545: D/test(12353): Pos56: 486.72044168359116px
09-22 \n:16.545: D/test(12353): Pos57: 495.322592427941px
09-22 \n:16.545: D/test(12353): Pos58: 503.92474317229085px
09-22 \n:16.545: D/test(12353): Pos59: 512.5268939166407px
09-22 \n:16.545: D/test(12353): Pos60: 521.1290446609905px
09-22 \n:16.545: D/test(12353): Pos61: 529.7311954053404px
09-22 \n:16.545: D/test(12353): Pos62: 538.3333461496902px
09-22 \n:16.545: D/test(12353): Pos63: 546.93549689404px
09-22 \n:16.545: D/test(12353): Pos64: 555.5376476383899px
09-22 \n:16.545: D/test(12353): Pos65: 564.1397983827397px
09-22 \n:16.545: D/test(12353): Pos66: 572.7419491270896px
09-22 \n:16.545: D/test(12353): Pos67: 581.3440998714394px
09-22 \n:16.545: D/test(12353): Pos68: 589.9462506157893px
09-22 \n:16.545: D/test(12353): Pos69: 598.5484013601391px
09-22 \n:16.545: D/test(12353): Pos70: 607.150552104489px
09-22 \n:16.545: D/test(12353): Pos71: 615.7527028488388px
09-22 \n:16.545: D/test(12353): Pos72: 624.3548535931886px
09-22 \n:16.545: D/test(12353): Pos73: 632.9570043375385px
09-22 \n:16.545: D/test(12353): Pos74: 641.5591550818883px
09-22 \n:16.545: D/test(12353): Pos75: 650.1613058262382px
09-22 \n:16.545: D/test(12353): Pos76: 658.763456570588px
09-22 \n:16.545: D/test(12353): Pos77: 667.3656073149378px
09-22 \n:16.545: D/test(12353): Pos78: 675.9677580592877px
09-22 \n:16.545: D/test(12353): Pos79: 684.5699088036375px
09-22 \n:16.545: D/test(12353): Pos80: 693.1720595479874px
09-22 \n:16.545: D/test(12353): Pos81: 701.7742102923372px
09-22 \n:16.545: D/test(12353): Pos82: 710.3763610366871px
09-22 \n:16.550: D/test(12353): Pos83: 718.9785117810369px
09-22 \n:16.550: D/test(12353): Pos84: 727.5806625253867px
09-22 \n:16.550: D/test(12353): Pos85: 736.1828132697366px
09-22 \n:16.550: D/test(12353): Pos86: 744.7849640140864px
09-22 \n:16.550: D/test(12353): Pos87: 753.3871147584363px
09-22 \n:16.550: D/test(12353): Pos88: 761.9892655027861px
09-22 \n:16.550: D/test(12353): Pos89: 770.591416247136px
09-22 \n:16.550: D/test(12353): Pos90: 779.1935669914858px
09-22 \n:16.550: D/test(12353): Pos91: 787.7957177358356px
09-22 \n:16.550: D/test(12353): Pos92: 796.3978684801855px

最佳答案

有几个问题正在发生。

看看http://diveintohtml5.info/canvas.html - 它介绍了如何避免模糊的线条(从 0.5 像素开始线条)并讨论了 Canvas 大小(不要通过 css 来实现)。

作为示例,请看这里: http://jsfiddle.net/QdBd7/2/

变化:

这修复了奇数线宽:

drawOnCanvas(Math.floor(topPos)+.5)

添加了缺失的开始路径:

ctx.beginPath();

更改为加载时设置 Canvas 大小:

function resizeCanvas(){
   c.width = document.body.clientWidth - 5, // 5 is from jsfiddle frame
   c.height = document.body.clientHeight - 5;
}

即使进行了这些更改,您仍然会注意到细微的变化,我不想指出这一点:http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

但是我没有任何解决方案(因为 ppm 可能最终会出现一些奇怪的 y 值,例如 75.812315 - 它将相差 0.3 像素...)当您绘制更多时,您可以以某种方式调整变化但随着浮点错误开始出现,事情变得更加棘手。

希望这能让您开始。

关于javascript - 如何用 JavaScript 画一个简单的尺子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12547716/

相关文章:

javascript - 从 JQuery Ajax/Javascript 调用启用 CORS 的 API

javascript - for..in 和 hasOwnProperty

javascript - Jquery 将数据堆栈附加在彼此之上,而不是超过表长度

android - java.net.ProtocolException : Unexpected status line: HTTP/1. 1 422不可处理的实体

android - 如何在 ActionBar 中引入 Swipeable Tabs?

android - Windows Phone 的 native iOS/android 应用程序

Javascript:单击调整大小的窗口不起作用

javascript - polymer 不删除删除的元素

javascript - Div 内的文本溢出另一个 Div

javascript - 如何创建多层 Accordion 菜单?