1

我正在开发一个 HTML5 画布应用程序,其中包含我用图像填充的形状。它是一个框架工具,用于构建和预览自定义框架。

在台式机/笔记本电脑上一切都很好,但是当我切换到 iOS 设备时,我得到了以下奇怪的行为。

有时,在我用来填充形状的图像重复的边界处会出现一条细白线。

请参阅以下 JSFiddle:http: //jsfiddle.net/3TVSy/3/

HTML:

<canvas id="canvas2" width="100" height="500" style="vertical-align:top"></canvas>
<canvas id="canvas1" width="300" height="2000" style="vertical-align:top"></canvas>

​ Javascript:

jQuery(function($){
    var $canvas = $('#canvas1'),
        $canvas2 = $('#canvas2'),
        scale = {scale: 0.21688837478311163, x: 0, y: 0},
        side = {
            fillStyle: '#222',
            x1: 0,
            x2: 266,
            x3: 266,
            x4: 0,
            y1: -4.610666666666667,
            y2: 261.38933333333335,
            y3: 1538.898666666667,
            y4: 1804.898666666667,
        }
    ;

    $canvas.createPattern({
        source: "http://vps5960.inmotionhosting.com/~romamo5/wp-content/uploads/2012/12/286-ft.jpg",
        repeat: "repeat-y",
        // Draw frame when pattern loads
        load: function(ptrn){
            side.fillStyle = ptrn;
            $canvas.clearCanvas()
                .drawLine(side)
            ;
            $canvas2.clearCanvas()
                .scaleCanvas(scale)
                .drawLine(side)
            ;
    }
});    

});​

小提琴有两个版本的画布。较大的不缩放,较小的缩放。该工件仅出现在较小的工件上(并且仅出现在实际的 iOS 设备上,而不是模拟器上)。您可以在较小的画布上看到大约 90% 的细白线。

我必须缩放图像,所以不缩放不是一种选择。我还注意到,如果我将小提琴中的比例因子四舍五入到小数点后三位,那么工件就会消失。问题是,如果我进行舍入,我的框架工具真的开始在后续方面搞砸了,所以舍入也真的不是一种选择。

我正在使用 jCanvas 进行绘图,但我不怀疑这是问题所在。它只是所有本机画布方法的包装器。(编辑:确认,即使不使用 jCanvas 也会出现工件 - 请参阅http://jsfiddle.net/3TVSy/5/

有没有其他人看到/解决了这个问题?这是iOS浏览器中的错误吗?

4

1 回答 1

1

我在 iOS6 的 safari 上也看到过同样的问题。重复图像之间出现间隙。在我看来,仅当图案图像的宽度/高度(不是原始图像大小,而是应用比例后的大小)为十进制数并且其第一个小数位小于 5(这意味着 [X. 0 < n < X.5]

我没有任何解决方案,但我可以通过以下逻辑检测到问题:

var scaledWidth = img.width * scale,
    scaledHeight = img.height * scale,
    decimalPartOfWidth = scaledWidth - (scaledWidth | 0),
    decimalPartOfHeight = scaledHeight - (scaledHeight | 0);

if ((decimalPartOfWidth > 0 && decimalPartOfWidth < 0.5)
    ||
    (decimalPartOfHeight > 0 && decimalPartOfHeight < 0.5)) {
  ; // The issue will occur.
} else {
  ; // The issue will not occur.
}

下面粘贴的是我用来重现该问题的代码。

<!DOCTYPE html>
<html>
  <body>
    <div id="status"></div>
    <div>
      <canvas width="480px" height="400px"></canvas>
    </div>
    <script>
      var canvas = document.getElementsByTagName('canvas')[0],
          ctx = canvas.getContext('2d'),
          stats = document.getElementById('status'),
          img = new Image(),
          doDrawImage = function (pScale) {
            var txt = 'scale = ' + pScale + ', w = ' + (img.width * pScale);
            stats.innerHTML = txt;
            ctx.save();
            ctx.transform(pScale, 0, 0, pScale, 0, 0);
            ctx.fillStyle = ctx.createPattern(img, 'repeat');
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.beginPath();
            ctx.rect(0, 0, canvas.width, canvas.height);
            ctx.fill();
            ctx.restore();
            console.log(txt + ' : ' + canvas.toDataURL());
          };

      img.src = 'pattern.png';
      img.onload = function () {
        var scale = 1.00,
            onTimeout = function () {
              if (scale < 2.00) {
                doDrawImage(scale);
                scale += 0.01;
                setTimeout(onTimeout, 1000);
              }
            };
        onTimeout();
      };
    </script>
  </body>
</html>

IMO 最好的解决方案是将背景颜色设置为与图案图像相同的颜色;p

于 2013-12-05T03:55:14.717 回答