2011-12-22 2 views
2

아래 코드는 IE9 및 FireFox에서 깨진 링을 멋지게 렌더링하지만 Chrome에서 원을 그리는 데 실패합니다. 왜 모든 아이디어, 또는 모든 브라우저에서 렌더링을 할 수 있습니까?Google 크롬에서 HTML5 캔버스 호가 올바르게 렌더링되지 않습니다.

건배

(크롬 버전 15.0.874.121)

<!DOCTYPE html> 
<html> 
<body> 
<canvas id="canvas1" width="201" height="201">No canvas in your browser...sorry...</canvas> 
<script> 
     var canv = document.getElementById('canvas1'); 
     var ctx = canv.getContext('2d'); 
     var size = 201; 
     var centerX = size/2; 
     var centerY = centerX; 
     var i; 
     var PI_180 = Math.PI/180; 
     var fill = true; 

     size = size/2; 
     ctx.translate(centerX, centerY); 
     // broken ring 
     for (i = 0; i < 360; i += 15) { 
      fill = !fill; 
      ctx.beginPath(); 
      ctx.arc(0, 0, size * 0.86, i * PI_180, (i + 15) * PI_180, false); 
      ctx.arc(0, 0, size * 0.75, (i + 15) * PI_180, i * PI_180, true); 
      ctx.closePath(); 
      if (fill) { 
       ctx.fill(); 
      } 
      ctx.stroke(); 
     } 
     ctx.translate(-centerX, -centerY); 
</script> 
</body> 
</html> 
+0

도현이, 난 그냥 사용할 수 크롬에 대한 업데이트가 있었다 발견 - 16.0.912.63이 - 그리고 지금 너무 크롬에서 제대로 렌더링 . 이것은 몇 달 동안 저를 괴롭 혔으며 질문을 게시 한 날이 고쳐졌습니다! (또는 적어도 나는 단지 오늘 갱신을 보았다). – MCrossley

답변

0

그것은 크롬 16, 17에서 완벽하게 작동하고, 18

크롬의 캔버스 개발은 매우 빠르게 진행되고 그들은했습니다 지난 한 해 동안 여러 가지 일들을 어지럽 혔습니다. 앤티 앨리어싱, 텍스트 왜곡 및 경로가 일부 비늘에서 전혀 나타나지 않는 문제는 모두 1 주 또는 2 주 동안 (주요) 버그를 남길 수있는 Chrome의 안정 버전으로 만들었습니다.

Chrome의 버그가 의심 될 때마다 개발자 및 카나리아 버전이 어떻게 반응하는지 항상 살펴볼 가치가 있습니다. 이러한 이유로 나는 뭔가가 명백하게 깨진 경우 두 가지를 열어 하나에서 다른 것으로 전환한다. 재미있는 점은 버그가 만들어지고 고쳐지는 것을 보게 될 것이고, 1 개월 후에 사람들은 안정 버전의 버그에 대해 불평 할 것입니다!

+0

현재 2012 년 5 월 15 일 오전 11시 15 분 15 초에 모든 브라우저가 모두 원의 2 차 근사를 사용하기 때문에 Arc의 불완전한 렌더링을합니다. 두 개의 큰 호, 반경 600px 및 602px를 180도 (sAngle 0, eAngle 180 둘 다)로 렌더링하면 테스트를 위해 JSFiddle (보류 중, 5 분 후에 보류 중)을 떠날 것입니다. 미래의 브라우저. (이것이 주요 OSS 브라우저에 버그로 기록되어 있는지 확인하고 확인해야합니다.) – ocodo

+0

그 문제를 보여주는 jsfiddle. http://jsfiddle.net/vXL2r/ - 200px 및 500px 반경의 수차 비교를 보여줍니다. - 이것이 얼마나 중요한지는 정확성에 대한 필요성에 분명히 달려 있습니다. 같은 시작/끝 각도를 사용하여 그려진 호는 괜찮아 보이지만 서로 정현파의 수차를 보여주고 있습니다.). – ocodo

+0

여기 여전히 주목할 만하다. http://jsfiddle.net/VNUaK/ –

1

해결 방법은 다음과 같습니다. 그것은 제가 작성한 호 메서드의 대체 구현입니다. 또한 2 차 베 지어를 사용하여 근사하지만 Chrome에서 훨씬 정확합니다. 수차 내가 해봤 서클 (2 회 화면 크기까지) 거의 눈에 띈다 :

var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; 
if (is_chrome) { 
    CanvasRenderingContext2D.prototype.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) { 
    // Signed length of curve 
    var signedLength; 
    var tau = 2 * Math.PI; 

    if (!anticlockwise && (endAngle - startAngle) >= tau) { 
     signedLength = tau; 
    } else if (anticlockwise && (startAngle - endAngle) >= tau) { 
     signedLength = -tau; 
    } else { 
     var delta = endAngle - startAngle; 
     signedLength = delta - tau * Math.floor(delta/tau); 

     // If very close to a full number of revolutions, make it full 
     if (Math.abs(delta) > 1e-12 && signedLength < 1e-12) 
     signedLength = tau; 

     // Adjust if anti-clockwise 
     if (anticlockwise && signedLength > 0) 
     signedLength = signedLength - tau; 
    } 

    // Minimum number of curves; 1 per quadrant. 
    var minCurves = Math.ceil(Math.abs(signedLength)/(Math.PI/2)); 

    // Number of curves; square-root of radius (or minimum) 
    var numCurves = Math.ceil(Math.max(minCurves, Math.sqrt(radius))); 

    // "Radius" of control points to ensure that the middle point 
    // of the curve is exactly on the circle radius. 
    var cpRadius = radius * (2 - Math.cos(signedLength/(numCurves * 2))); 

    // Angle step per curve 
    var step = signedLength/numCurves; 

    // Draw the circle 
    this.lineTo(x + radius * Math.cos(startAngle), y + radius * Math.sin(startAngle)); 
    for (var i = 0, a = startAngle + step, a2 = startAngle + step/2; i < numCurves; ++i, a += step, a2 += step) 
     this.quadraticCurveTo(x + cpRadius * Math.cos(a2), y + cpRadius * Math.sin(a2), x + radius * Math.cos(a), y + radius * Math.sin(a)); 
    } 
} 

편집 : 제작 WHATWG 준수 (파이어 폭스, 사파리 등). 크롬은 특정 각도에서 서클을 잘못 보는 것처럼 보입니다.

1

ctx.clip()으로 수정할 수 있습니다. 예를 들어

:

ctx.save(); 
// clipping 
ctx.beginPath() 
ctx.arc(x, y, radius, 0, 6.28, true); 
ctx.clip(); 

// drawing 
ctx.beginPath(); 
ctx.arc(x, y, radius, 0, 6.28, true); 
ctx.fill(); 
ctx.restore(); 
ctx.stroke(); 

너의 Keyten/신인 배우 :

관련 문제