2

我从 PhoneGap 开始,我正在尝试一个简单的应用程序,一个 Ruler。我是 JavaScript 的初学者,我的大部分移动工作都是在原生 Android 代码中完成的,但我对此很头疼,我不知道出了什么问题。

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

我的 HTML 的主体很简单,一个画布填满了整个屏幕

  <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;
}

在给定的画布和 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 毫米相差甚远。为什么?它绘制的线条也有不同的大小,而且它们的宽度绝对不是 1 像素。

在此处输入图像描述

这是显示计算正确的logcat,我在一个高度为800px、屏幕高度为93mm的galaxy S2中测试它,所以每8.6像素我就有1mm。

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
4

2 回答 2

4

几个问题正在发生。

看看http://diveintohtml5.info/canvas.html - 它讨论了如何避免模糊线(起始线为 0.5 像素)并讨论画布大小(不要通过 css 进行)。

作为一个例子看看这里:http: //jsfiddle.net/QdBd7/2/

变化:

这修复了奇数线宽:

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

添加了缺少的开始路径:

ctx.beginPath();

更改以在加载时设置画布大小:

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 像素......)当你画得更多时,你可以以某种方式调整变化,但它得到了随着浮点错误开始出现,更加棘手。

希望这能让你开始。

于 2012-09-22T21:48:15.210 回答
-2
var cmm=15
var countCm=0
var c = document.getElementById("myCanvas");
var ctx= c.getContext("2d");
ctx.lineWidth = 1;
ctx.fillRect(0,0,30,250);
function drawOnCanvas(y){
    ctx.beginPath();    
    ctx.moveTo(0,y);
    ctx.lineTo(cmm,y);
    ctx.stroke();
}
function drawRuler(){
    var ppm = 8.602150744349842,
        count = Math.floor(c.height / ppm);

    for(var i=0; i<count; i++){  
        if(countCm==4){cmm=15;countCm=0}else{cmm=4;countCm++}
      var topPos = (5 + i*ppm);
      drawOnCanvas(Math.floor(topPos)+.5);     
    };

}
function resizeCanvas(){
   c.width = document.body.clientWidth - 5,
   c.height = document.body.clientHeight - 5;
}



resizeCanvas();
drawRuler();
于 2014-09-29T13:06:39.897 回答