ラベル webfonts の投稿を表示しています。 すべての投稿を表示
ラベル webfonts の投稿を表示しています。 すべての投稿を表示

2013年10月23日水曜日

WebGLのTextureをCanvasに文字(Web Fonts)を書いて動的に作ってみる(jQuery/ThreeJS使用, Firefox 24.0/Safari 6.0.5で動作)

tumblrにも書いたが,こっちにも書いておく.
以前にも試みたがリンク先の情報がなくなったりFirefoxでの動作に問題があったりしたので再挑戦.





<html>
 <head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <link href='http://fonts.googleapis.com/css?family=Ewert' rel='stylesheet' type='text/css'>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
  <script src="http://mrdoob.github.com/three.js/build/three.min.js" type="text/javascript"></script>
  <script type="text/javascript">
   var camera, scene, renderer, mesh, cube;

   function resize() {
    camera.aspect= window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
   }

   function animate() {
    requestAnimationFrame(animate);
    var time= Date.now() * 0.001;
    if(mesh) {
     mesh.rotation.x= -time;
     mesh.rotation.y= time;

     var imagedata= createImageData('Hello, World!! ' + (time % 1000).toFixed(2), {
      r: 0,
      g: 0,
      b: 255,
     }, 35);
     var texture= createTexture(imagedata);
     mesh.material.map= texture;
    }
    var time= Date.now() * 0.0005;
    if(cube) {
     cube.rotation.x= time;
     cube.rotation.y= time;
    }
    renderer.render(scene, camera);
   }

   function init() {
    camera= new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000);
    camera.position.z= 10;
    scene= new THREE.Scene();
    scene.add(camera);
    renderer= new THREE.WebGLRenderer({
     antialias: true
    });
    $('#endpoint').append($(renderer.domElement));

    cube= new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({
     color: 0xff0000,
     wireframe: true,
    }));
    scene.add(cube);
    cube.scale.x= 2;
    cube.scale.y= 2;
    cube.scale.z= 2;
    cube.position.z= -5;

    var geometry= new THREE.PlaneGeometry(1, 1);
    var material= new THREE.MeshBasicMaterial({
     transparent: true,
    });
    mesh= new THREE.Mesh(geometry, material);
    scene.add(mesh);
    mesh.scale.x= 5;
    mesh.scale.y= 5;
   }

   function createTexture(imagedata) {
    var w= imagedata.width;
    var h= imagedata.height;
    var size= w * h;
    var data= new Uint8Array(4 * size);
    for(var i= 0; i < size; i++) {
     data[i * 4 + 0]= imagedata.data[i * 4 + 0];
     data[i * 4 + 1]= imagedata.data[i * 4 + 1];
     data[i * 4 + 2]= imagedata.data[i * 4 + 2];
     data[i * 4 + 3]= imagedata.data[i * 4 + 3];
    }
    var texture= new THREE.DataTexture(data, w, h, THREE.RGBAFormat);
    texture.needsUpdate= true;
    return texture;
   }

   function createImageData(message, color, fontsize) {
    var c4tex= $('#hiddenCanvas').get(0);
    var w= $(c4tex).width();
    var h= $(c4tex).height();
    var ctx= c4tex.getContext('2d');

    ctx.clearRect(0, 0, w, h);
    ctx.fillStyle= 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',.1)';
    ctx.fillRect(0, 0, w, h);
    ctx.fillStyle= 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',1.0)';
    ctx.font= fontsize + 'px \'Ewert\'';
    ctx.fillText(message, (w - ctx.measureText(message).width) * .5, (h + fontsize) * .5);

    return ctx.getImageData(0, 0, w, h);
   }

   $(document).ready(function() {
    $(window).resize(function() {
     resize();
    });

    init();
    animate();
    resize();
   });
  </script>
 </head>
 <body style="margin: 0; padding: 0;">
  <div id="endpoint"></div>
  <canvas id="hiddenCanvas" width="512" height="512" style="display: none;"></canvas>
 </body>
</html>


  • CanvasからtoDataURLメソッドを用いて,Data URI Schemeの形で得た値を返して,THREE.ImageUtils.loadTextureメソッドで生成しようとするとCORS(Cross-Origin Resource Sharing)的問題で引っかかる.
  • また,Canvasの2DコンテクストからgetImageDataメソッドを用いて作ったImageData.dataを直接THREE.DataTexture.image.dataに突っ込んでも動作しなかった(私の間違いか,やはりCORS的なナニカか,わからないけど).

2012年2月21日火曜日

HTML5 Canvas 2D Context に Web Fonts を用いて fillText してみる / Google Web Fonts の WebFont Loader を使ってみる

動機
先のエントリーと,このpostと,この記事より.


参考
  • WebFont Loader - Google Web Fonts — Google Developers


  • やってみた
    緑色(赤色は実行内容に即して変更)の部分は上記参考ページより.

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript">
    WebFontConfig = {
    google: {
    families: [ 'Ewert', 'Fredericka the Great', 'Ubuntu' ]
    },
    active: function() {
    paint();
    },
    };
    (function() {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
    '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
    })();
    </script>

    <script type="text/javascript">
    function paint() {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = "rgba(255, 255, 255, 255)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    var fontName= document.defaultView.getComputedStyle(canvas, null).fontFamily;
    ctx.fillStyle= "rgba(0,0,0,255)";
    ctx.font = "32px 'Helvetica'";
    ctx.fillText("Helvetica", 10, 50);
    ctx.fillText("AGCDEFGHIJKLMN 12345+-", 350, 50);
    ctx.font = "32px '"+fontName+"'";
    ctx.fillText("Ewert", 10, 100);
    ctx.fillText("AGCDEFGHIJKLMN 12345+-", 350, 100);
    ctx.font = "32px 'Fredericka the Great'";
    ctx.fillText("Fredericka the Great", 10, 150);
    ctx.fillText("AGCDEFGHIJKLMN 12345+-", 350, 150);
    ctx.font = "32px 'Ubuntu'";
    ctx.fillText("Ubuntu", 10, 200);
    ctx.fillText("AGCDEFGHIJKLMN 12345+-", 350, 200);
    ctx.font = "32px 'Times'";
    ctx.fillText("Times", 10, 250);
    ctx.fillText("AGCDEFGHIJKLMN 12345+-", 350, 250);
    }
    </script>
    </head>
    <body>
    <canvas id='canvas' style="border:solid 1px;font-family:Ewert;" width="850" height="300"></canvas>
    </body>
    </html>

    FontがそろうとWebFontConfig中の'active:'が呼ばれ,activeに記述しておいたpaint関数を呼ぶ.


  • ということで繰り返し描かせるのでなく,Fontファイルがそろった所で一回だけ描画を実行するだけで,動作させることが出来た(WebFont Loaderが使える場合).
  • CSSファイル(おそらく外部からアクセス可能なURLで提供されていることが条件)の追加でWebFontsを指定することができるならWebFont Loaderが利用できるらしい(詳しくは参考ページの'Specifying providers and fonts'を参考してください.項目の一番最後にCSSファイルを自分で指定する方法があります).
  • 2012年2月20日月曜日

    HTML5 Canvas 2D Context に Web Fonts を用いて fillText してみる

    動機
    zugaさんのこのpost.

    やってみた
    Web Fontsとして, Google Web FontsからUbuntuを利用してます.

    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'>
    <script type="text/javascript">
    function init() {
    setInterval(paint, 1000);
    }
    function paint() {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = "rgba(255, 255, 255, 255)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    var fontName= 'Ubuntu';//document.defaultView.getComputedStyle(canvas, null).fontFamily;
    ctx.fillStyle= "rgba(0,0,0,255)";
    ctx.font = "32px 'Helvetica'";
    ctx.fillText("Helvetica Ubuntu", 10, 50);
    ctx.font = "32px '"+fontName+"'";
    ctx.fillText("Ubuntu Ubuntu", 10, 100);
    ctx.font = "32px 'Times'";
    ctx.fillText("Times Ubuntu", 10, 150);
    }
    </script>
    </head>
    <body onload="init();">
    <canvas id='canvas' style="border:solid 1px;font-family:Ubuntu;" width="400" height="300"></canvas>
    </body>
    </html>

    • Google Web Fontsでは, link要素でCSSを取得させる(script要素での方法も用意されている).CSS内にWebFontsのfontファイルのurlが記載されている.
    • Web Font(s)のロード時間の都合かonload時に描画させると描画されないケースが発生するので繰り返し描画させている.

      • では本文中にwebfontsで要求するfontを利用すればonload時1回の指定でも問題ないのか?ということで試してみるとFirefox 10.0.2は,この期待に応えてくれたが,Safari 5.1.3 /Chrome 17.0.963.56ではダメだった(描画されない).



    結果


    HelveticaとTimes以外はGoogleWebFontsを使用





    参考
  • How to Use Google Web Fonts in your HTML5 Canvas | Ascended Arcade
  • 第4回 CSS3のWebフォントを使ってみよう | Think IT