일발예! SVG로 HTML 이미지화

10370 단어 자바스크립트SVG

사과와 정정(2016년 12월 5일 추가)



기사 초출시에 React v15.3.2 에서는 foreignObject 요소가 서포트되어 있지 않다,라고 썼습니다만 이쪽은 잘못이었습니다.
React v15.0.0 릴리스 노트 에서 SVG의 모든 요소를 ​​지원했다고 합니다만, 이 타이밍에서는 아직 공식 문서 가 갱신되고 있지 않았습니다.
또 v15.2.x 에서는 일부의 속성이 사용 불가라고 판정되어 버려, 컴퍼넌트의 렌더링 자체는 의도대로 되는 것의 사용에는 불안을 느끼게 하는 거동이 되어 있었습니다.


React V15.2.x에서는 use 요소 또는 foreignObject 요소의 하위 요소에 필요한 xmlns:* 속성을 사용할 수 없다고 경고합니다.

그러나 최근에 공식 문서의 재작성이 시작되어 원래 존재한 「React에서 사용할 수 있는 요소와 속성의 일람」페이지가 마음껏 삭제되었습니다 ( 해당 커밋 ).
그래서 걱정되어 현시점에서 최신 버젼인 v15.4.0 으로 시험했는데, use 요소나 foreignObject 요소가 전술의 경고도 없고 보통으로 사용할 수 있었으므로 자신의 착각을 깨달은 대로입니다.

수중에서 버전을 거슬러 올라가 시도한 결과, v15.3.0 이상이라면 문제없이 동작하는 것 같습니다.
따라서 기사 초출시의 기재는 완전히 잘못입니다.
여기에 정정하고 사과드립니다.
매우 실례했습니다.

이 슬라이드 정보



2016년 10월 19일(수)
SVG 아저씨 마츠다 씨 주최
「마보로시의 SVG 공부회 그 2」 발표 자료
지금은 재료 일지도 모르지만 용서해라.

※ 「마보로시」라는 것은 당사

이것은 HTML로 만든 이미지입니다.





게다가 프런트만으로 실현 가능!

데모 만든



react-dom-imager-demo
git clone [email protected]:haribote/react-dom-imager-demo.git
cd react-dom-imager-demo && npm install
npm start

갑자기 씨앗



HTML을 이미징하는 단계


  • 이미징하려는 HTML을 만듭니다
  • (1) HTML을 SVG foreignObject 요소로 둘러싸는
  • (2)의 SVG를 canvas 요소에 그리기

  • MDN에 전부 써있다



    DOM 객체를 Canvas에 그리기 - HTML | MDN

    코드 예


    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 1280" width="960" height="1280">
      <style>
        h1 {
          color: red;
        }
      </style>
      <g>
        <foreignObject x="0" y="0" width="100%" height="100%">
          <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Hello, world!</h1>
          </div>
        </foreignObject>
      </g>
    </svg>
    

    SVG를 Canvas에 그리기


    // canvas要素とコンテキスト、SVGを読み込むimage要素を用意
    const canvasEl = document.getElementById('canvas');
    const context  = canvasEl.getContext('2d');
    const imageEl  = new Image();
    
    // SVGコードをBlobにしてURLを発行する
    const staticSvgBlob = new Blob(['<svg xmlns...'], { type: 'image/svg+xml' });
    const url           = URL.createObjectURL(staticSvgBlob);
    
    // SVGが読み込まれたらcanvas要素に描画する
    imageEl.onload = () => {
      context.clearRect(0, 0, canvasEl.width, canvasEl.height);
      context.drawImage(imageEl, 0, 0);
      URL.revokeObjectURL(url); // URL解放
    };
    
    // CORS設定をしてSVGを画像として読み込む
    imageEl.crossOrigin = 'Anonymous';
    imageEl.src = url;
    

    가장 중요한 포인트



    Canvas에 그리는 SVG는 완전히 독립형이어야합니다.

    즉 드로잉에 필요한 정보는 모두 부딪치는 것!

    BLOB로 만들 때 MIME


    new Blob(['<svg xmlns...'], { type: 'image/svg+xml' });
    

    문자 코드 필요 없음

    MDN에 쓰여진 대로image/svg+xml;charset=utf-8그러면 일부 브라우저에서 SVG가 파괴됩니다.

    (어째서일까?)

    루트 SVG에 필요한 속성


  • xmlns
  • viewBox
  • width
  • height


  • CSS 포함


    style 요소에 CSS를 문자열 전개해 직접 붓는다!
    <style>
      h1 {
        color: red;
      }
    </style>
    

    이미지 포함



    Base64로 인코딩하여 DataURL로 부딪힌다!
    <img src="data:image/png;base64,iVBOR..." width="400" height="382" alt="" />
    

    글꼴이라든가



    이미지와 마찬가지로 DataURL이어야합니다.
  • 데이터 재배포에 해당하므로 저작권이나 주의
  • 아이콘은 글꼴이 아닌 SVG입니다. k


  • 죄송합니다.


  • IE는 무엇입니까?
  • foreignObject 요소가 포함된 SVG를 Canvas에 그리면 tainted 라고 되어 toDataURL
  • Chrome, Safari 만?
  • 제대로 조사하지 않았다
  • chromium의 issue는 여기
  • Canvas taint (오염)에 대해서는 여기


  • React는 foreignObject 요소가 지원되지 않기 때문에 dangerouslySetInnerHTML
  • v15.3.2 현재
  • 향후 지원 될 것입니다


  • ※1페이지째의 정정을 읽어 주세요.

    고마워요

    좋은 웹페이지 즐겨찾기