2017-10-09 1 views
1

EDIT : 원래는 데스크톱 브라우저 만 검사했으나 모바일 브라우저에서는 그림이 훨씬 복잡해졌습니다.Canvas.measure 브라우저의 차이점은 대단합니다

일부 브라우저와 텍스트 렌더링 기능에서 이상한 문제가 발생했으며이를 방지하기 위해 무엇인가 할 수 있는지 확신 할 수 없습니다.

안드로이드의 WebKit과 덜 일관된 Firefox가 2D Canvas 라이브러리를 사용하여 약간 큰 텍스트를 생성하는 것으로 보입니다. 나는 지금 시각적 인 외양을 무시하고 싶지만 대신 쉽게 비교할 수있는 텍스트 측정에 초점을 맞추고 싶습니다.

내가 텍스트 폭을 계산하기 위해 두 가지 일반적인 방법을 사용하고 있습니다 : 텍스트를

  • 캔버스 2D API를하고 측정
  • DOM 방법이 질문에 설명 된대로

: 그러나 Calculate text width with JavaScript , 이 두 가지 방법 모두 (모든 브라우저에서) 동일한 결과를 얻을 수 있습니다.

http://jsfiddle.net/aj7v5e4L/15/ :

function getTextWidth(text, font) { 
    // if given, use cached canvas for better performance 
    // else, create new canvas 
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas")); 
    var context = canvas.getContext("2d"); 
    context.font = font; 
    var metrics = context.measureText(text); 
    return metrics.width; 
}; 

function getTextWidthDOM(text, font) { 
    var f = font || '12px arial', 
     o = $('<span>' + text + '</span>') 
      .css({'font': f, 'float': 'left', 'white-space': 'nowrap'}) 
      .css({'visibility': 'hidden'}) 
      .appendTo($('body')), 
     w = o.width(); 

    return w; 
} 

내가합니다 (웹 글꼴이 측정 버튼을 클릭하기 전에 먼저로드 될 때까지 기다리십시오) 샘플 글꼴 집합에 대한 텍스트 측정을 수행 할 수 있습니다 구글 글꼴을 사용하여 작은 바이올린을 수정

,535,559,156,977 : 는 다양한 브라우저에서이 실행

(글꼴 - 무게와 스타일을 강제로 업데이트) 나는 데 문제 (문자열을 사용하여 'S')를 보여줍니다

모든 데스크탑 브라우저의 차이점은 사소한 것입니다. 사파리 만이 눈에 띄는 데, 폰트에 따라 보았을 때 약 1 %에서 4 % 정도입니다. 그래서 크지는 않지만 계산을 포기합니다.

업데이트 : 일부 모바일 브라우저도 테스트되었습니다. iOS의 경우 Safari와 동일한 수준 (모두 WebKit을 사용하므로 깜짝 선물이 없습니다)이며 Android의 Firefox는 매우 켜고 꺼져 있습니다.

서브 픽셀 정확도가 실제로 모든 브라우저 (예 : 예전 IE의 경우)에서 지원되지는 않지만 반올림해도 도움이되지 않는다는 것을 읽었습니다. 그러면 다른 폭을 갖게 될 수 있습니다.

webfont를 사용하지 않고 표준 글꼴 만 사용하면 Chrome과 Safari의 정확한 측정 값이 반환되므로 웹 글꼴과 관련이 있다고 생각합니다.

나는 지금 내가 할 수있는 것에 당혹 스럽다. 나는이 문제를 해결하기 위해 인터넷에서 아무 것도 발견하지 못했기 때문에 내가 잘못 생각한 것처럼 생각한다.하지만 바이올린은 얻을 수있는만큼 간단하다. . 나는이 하루 종일을 정말로 보냈다. 그래서 너희들은 내 유일한 희망이다.

나는 (예 : 영향을받는 브라우저에서 텍스트를 4 % 작게 표현하는 등) 내 머리 속에 몇 가지 추악한 해결 방법이 있습니다. 나는 그것을 피하고 싶습니다.

+0

결과 테이블이 문자열 ""S "'로 작성 되었습니까? 그렇다면 나는 첫번째 폰트에서 안드로이드에 대한 파이어 폭스에'15.73333 .. '을 가져 왔는데, 이것은 다른 글꼴보다 사파리 결과에 더 가깝습니다. 현재 실제 키보드에 액세스 할 수 없지만 글꼴 두께를 강요하면 어떻게됩니까? – Kaiido

+0

예, 문자열 "S"로 생성되었습니다 - 모바일 브라우저의 영역을 만지지도 않았으므로 더 많은 문제가 열릴 수 있습니다.) - font-weight를 시도합니다 – Michael

답변

1

Safari (및 몇 가지 다른 것들)는 하위 픽셀 수준으로 올라가는 것을 지원하지만 그림은 보이지 않는 것 같습니다.

글꼴 크기를 9.5pt으로 설정하면이 값은 12.6666 ... px으로 변환됩니다.

사파리는이에 대한 높은 정밀도 값 반환 않는 경우에도 : 단지 캔버스에 제대로 정수가 아닌 글꼴 크기로 그릴 수없는, 그리고하지

console.log(getComputedStyle(document.body)['font-size']); 
 
// on Safari returns 12.666666984558105px oO
body{font-size:9.5pt}

를 :

console.log(getRangeWidth("S", '12.3px serif')); 
 
// safari: 6.673828125 | FF 6.8333282470703125 
 
console.log(getRangeWidth("S", '12.4px serif')); 
 
// safari: 6.673828125 | FF 6.883331298828125 
 
console.log(getRangeWidth("S", '12.5px serif')); 
 
// safari 7.22998046875 | FF 6.95001220703125 
 
console.log(getRangeWidth("S", '12.6px serif')); 
 
// safari 7.22998046875 | FF 7 
 

 
// High precision DOM based measurement 
 
function getRangeWidth(text, font) { 
 
    var f = font || '12px arial', 
 
     o = $('<span>' + text + '</span>') 
 
      .css({'font': f, 'white-space': 'nowrap'}) 
 
      .appendTo($('body')), 
 
     r = document.createRange(); 
 
r.selectNode(o[0]); 
 
var w = r.getBoundingClientRect().width; 
 
o.remove(); 
 
return w; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

이러한 단점을 피하기 위해 정수 값을 사용하여 항상 px 장치를 사용해보십시오.

+0

안드로이드에서 Ps : FF는 정말 이상하게 반올림하는 것 같습니다 : 12.3! = 12.4 == 12.5 == 12.6 ... – Kaiido

+0

굉장하다. 정수 폰트 크기가 픽셀로되어있어 실제로 일관성이있는 것 같다. (좀 더 확인해야한다.) 새로운 바이올린은 그 사실을 보여 주며 즉시 글꼴 크기를 편집 할 수 있습니다. http://jsfiddle.net/aj7v5e4L/17/ 정말로 도움이 된 Kaiido, 정말 고마워요. – Michael

관련 문제