휴대폰의 HTML 캔버스에서 흐릿한 텍스트를 수정하는 방법

저는 마인드맵을 기반으로 소셜 미디어 네트워크 및 협업 도구를 구축하고 있으며 이 블로그 게시물 시리즈에서 제 작업을 문서화하고 있습니다. React, Tailwind CSS, Firebase, Apollo/GraphQL, three.js 및 TypeScript를 사용하여 웹 앱을 구축하는 과정에서 제가 배운 내용에 관심이 있으시면 저를 팔로우하세요.

오늘의 에피소드는 내가 만난 특정 문제와 해결 방법에 대한 것입니다.

문제



이전 에피소드에서는 3D 그래픽 라이브러리 three.js( , , , )를 사용하여 마인드맵을 만들어 보았습니다.

다음은 문제가 있는 이전 버전의 코드입니다.



이제 예를 들어 풀 HD 해상도(1920x1080)의 일반 모니터로 이것을 보면 다음과 같이 보일 것입니다.



괜찮아 보이지만 iPhone에서 보면 다음과 같습니다.



으, 레이블 텍스트를 거의 해독할 수 없습니다!

원인



내 휴대폰은 내 모니터보다 인치당 픽셀 수가 더 많습니다(PPI). Apple은 이것을 "Retina"화면이라고 부르지만 Android 휴대폰과 태블릿에도 이 화면이 있습니다.

내 마인드 맵은 HTML canvas element 에 렌더링됩니다.

휴대 전화의 높은 PPI 속도는 웹 페이지의 일반 텍스트가 더 선명하게(덜 픽셀화됨) 렌더링되는 반면 HTML 캔버스에서는 그 효과가 반대입니다. 브라우저는 화면이 일반인 것처럼 캔버스에 콘텐츠를 렌더링합니다. , 낮은 PPI. 실제로 더 나쁜 것은 콘텐츠를 추가로 흐리게 하는 것 같습니다. 어떤 브라우저를 사용하든 내 마인드맵은 Chrome과 Safari에서 똑같이 좋지 않게 보입니다.

해결책



이 페이지에서 해결책을 찾았습니다.
  • Handling High DPI (Retina) displays in WebGL

  • 트릭은 다음과 같습니다.
  • PPI가 높은 장치에서 캔버스가 렌더링되고 있는지 감지합니다
  • .
  • 장치의 PPI가 높으면 캔버스 크기를 늘립니다
  • .
  • 더 큰 캔버스가 같은 크기로 보이도록 하려면 CSS 스타일을 사용하여 더 작게 만드십시오
  • .

    코드



    각 장치에 적합한 캔버스를 만드는 이 기능을 생각해 냈습니다.

    function createCanvas(width, height, set2dTransform = true) {
      const ratio = Math.ceil(window.devicePixelRatio);
      const canvas = document.createElement('canvas');
      canvas.width = width * ratio;
      canvas.height = height * ratio;
      canvas.style.width = `${width}px`;
      canvas.style.height = `${height}px`;
      if (set2dTransform) {
        canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
      }
      return canvas;
    }
    


    MycreateCanvas 함수는 세 가지 인수를 허용합니다.
  • width , height : 캔버스의 크기, 화면에 보이는 방식
  • set2dTransform : 캔버스에서 2D 렌더링이 올바르게 작동하는지 확인하기 위해 setTransform을 사용하는 특정 코드 라인을 전환합니다. 기본적으로 true
  • set2DTransform 인수가 필요한 이유는 무엇입니까? 내가 사용하고 있는 3D 그래픽 라이브러리three.js에서 2D 변형을 설정하면 오류가 발생한다는 것을 발견했습니다. 그래서 선택 사항으로 만들었습니다.

    함수는 window.devicePixelRatio을 호출하여 일반 또는 높은 PPI 화면이 있는지 확인합니다. 내 모니터에서 값은 1 이고 내 iPhone에서는 2 입니다.

    일부 장치에는 분수 장치 픽셀 비율이 있어 렌더링 문제가 발생할 수 있으므로 Math.ceil을 사용하여 다음 정수로 반올림합니다.

    그런 다음 입력된 너비와 높이에 장치 픽셀 비율을 곱하여 캔버스의 너비와 높이를 설정합니다. 너비가 800이고 높이가 600인 경우 내 모니터에서 캔버스 크기는 800x600이고 휴대폰에서는 1600x1200입니다.

    그런 다음 style.widthstyle.height를 사용하여 캔버스가 화면에 표시되는 너비와 높이를 설정합니다(제 예에서는 장치 픽셀 비율에 관계없이 800x600입니다).

    결과



    Retina 호환 마인드 맵은 다음과 같습니다.



    내 휴대전화의 스크린샷:



    👍🏻 멋져요!

    감사의 말



    ❤️ 문제( SydBal )를 지적해 주신 Reddit 사용자see discussion에게 감사드립니다!

    ❤️ 내 솔루션의 기반이 되는 StackOverflow 사용자mynameisko에게 감사합니다!

    SO에 게시 계속하려면…



    저는 제 마인드맵을 소셜 미디어 네트워크 및 협업 도구로 전환할 계획이며 후속 기사에서 저의 진행 상황에 대해 계속 블로그에 올릴 것입니다. 계속 지켜봐!

    좋은 웹페이지 즐겨찾기