MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Canvas のコードスニペット

<canvas> を利用するための一般的な情報については、canvas のトピックページ を参照してください。

ウェブコンテンツで役に立つコード

canvas 内にある特定の色のピクセルの数を取得する

以下の関数は、canvas 内にある r、g、b で指定した RGB 色を持つピクセルの数を返します。これは こちらのブログ記事 で説明しているように、例えばある領域と、その上にユーザーが描いた領域を比較するときにとても役に立ちます。

function getpixelamount(canvas, r, g, b) {
  var cx = canvas.getContext('2d');
  var pixels = cx.getImageData(0, 0, canvas.width, canvas.height);
  var all = pixels.data.length;
  var amount = 0;
  for (i = 0; i < all; i += 4) {
    if (pixels.data[i] === r &&
        pixels.data[i + 1] === g &&
        pixels.data[i + 2] === b) {
      amount++;
    }
  }
  return amount;
};

canvas 内のピクセルの色を取得する

以下のスニペットは、canvas の x および y で示した位置にあるピクセルの色を、RGBA 値で表すオブジェクトを返します。これは、マウスカーソルがある図形の内部にあるか否かを調べるために役立ちます。

function getpixelcolour(canvas, x, y) {
  var cx = canvas.getContext('2d');
  var pixel = cx.getImageData(x, y, 1, 1);
  return {
    r: pixel.data[0],
    g: pixel.data[1],
    b: pixel.data[2],
    a: pixel.data[3]
  };
}

メソッドを連結する

以下のクラスは、jQuery のように連続して 2D コンテキストのメソッドやプロパティにアクセスする機能を提供します。

function Canvas2DContext(canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  if (!(this instanceof Canvas2DContext)) {
    return new Canvas2DContext(canvas);
  }
  this.context = this.ctx = canvas.getContext('2d');
  if (!Canvas2DContext.prototype.arc) {
    Canvas2DContext.setup.call(this, this.ctx);
  }
}
Canvas2DContext.setup = function () {
  var methods = ['arc','arcTo','beginPath','bezierCurveTo','clearRect','clip',
    'closePath','drawImage','fill','fillRect','fillText','lineTo','moveTo',
    'quadraticCurveTo','rect','restore','rotate','save','scale','setTransform',
    'stroke','strokeRect','strokeText','transform','translate'];

  var getterMethods = ['createPattern','drawFocusRing','isPointInPath','measureText', // drawFocusRing not currently supported
    // The following might instead be wrapped to be able to chain their child objects
    'createImageData','createLinearGradient',
    'createRadialGradient', 'getImageData','putImageData'
  ];

  var props = ['canvas','fillStyle','font','globalAlpha','globalCompositeOperation',
    'lineCap','lineJoin','lineWidth','miterLimit','shadowOffsetX','shadowOffsetY',
    'shadowBlur','shadowColor','strokeStyle','textAlign','textBaseline'];

  for (let m of methods) {
    let method = m;
    Canvas2DContext.prototype[method] = function () {
      this.ctx[method].apply(this.ctx, arguments);
      return this;
    };
  }

  for (let m of getterMethods) {
    let method = m;
    Canvas2DContext.prototype[method] = function () {
      return this.ctx[method].apply(this.ctx, arguments);
    };
  }

  for (let p of props) {
    let prop = p;
    Canvas2DContext.prototype[prop] = function (value) {
      if (value === undefined)
        return this.ctx[prop];
      this.ctx[prop] = value;
      return this;
    };
  }
};

var canvas = document.getElementById('canvas');

// Use context to get access to underlying context
var ctx = Canvas2DContext(canvas)
  .strokeStyle("rgb(30,110,210)")
  .transform(10, 3, 4, 5, 1, 0)
  .strokeRect(2, 10, 15, 20)
  .context;

// Use property name as a function (but without arguments) to get the value
var strokeStyle = Canvas2DContext(canvas)
  .strokeStyle("rgb(50,110,210)")
  .strokeStyle();

特権を持つコードに限り役に立つコード

以下のスニペットは拡張機能や特権を持つアプリなど、特権を持つコード内に限り役に立ちます。

canvas のイメージをファイルに保存する

以下の関数は canvas オブジェクトと保存先ファイルパス文字列を受け取ります。canvas は PNG ファイルに変換され、指定された場所に保存されます。この関数は、ファイルの保存が完了したときに解決する promise を返します。

function saveCanvas(canvas, path, type, options) {
    return Task.spawn(function *() {
        var reader = new FileReader;
        var blob = yield new Promise(accept => canvas.toBlob(accept, type, options));
        reader.readAsArrayBuffer(blob);

        yield new Promise(accept => { reader.onloadend = accept });

        return yield OS.File.writeAtomic(path, new Uint8Array(reader.result),
                                         { tmpPath: path + '.tmp' });
    });
}

canvas 要素にリモートのページを読み込む

以下のクラスは最初に非表示の iframe 要素を生成して、load イベントにリスナーを設定します。リモートのページが読み込まれると、remotePageLoaded メソッドを実行します。このメソッドは iframe の window への参照を取得して、window を canvas オブジェクトに描画します。

これ chrome のページで実行する場合に限り動作します。通常のウェブページで実行すると、'Security error" のコード "1000" エラーが発生します。

RemoteCanvas = function() {
    this.url = "http://developer.mozilla.org";
};

RemoteCanvas.CANVAS_WIDTH = 300;
RemoteCanvas.CANVAS_HEIGHT = 300;

RemoteCanvas.prototype.load = function() {
    var windowWidth = window.innerWidth - 25;
    var iframe;
    iframe = document.createElement("iframe");
    iframe.id = "test-iframe";
    iframe.height = "10px";
    iframe.width = windowWidth + "px";
    iframe.style.visibility = "hidden";
    iframe.src = this.url;
    // Here is where the magic happens... add a listener to the
    // frame's onload event
    iframe.addEventListener("load", this.remotePageLoaded, true);
    //append to the end of the page
    window.document.body.appendChild(iframe);
    return;    
};

RemoteCanvas.prototype.remotePageLoaded = function() {
    // Look back up the iframe by id
    var ldrFrame = document.getElementById("test-iframe");
    // Get a reference to the window object you need for the canvas
    // drawWindow method
    var remoteWindow = ldrFrame.contentWindow;

    //Draw canvas
    var canvas = document.createElement("canvas");
    canvas.style.width = RemoteCanvas.CANVAS_WIDTH + "px";
    canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + "px";
    canvas.width = RemoteCanvas.CANVAS_WIDTH;
    canvas.height = RemoteCanvas.CANVAS_HEIGHT;
    var windowWidth = window.innerWidth - 25;
    var windowHeight = window.innerHeight;

    var ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0,
                  RemoteCanvas.CANVAS_WIDTH,
                  RemoteCanvas.CANVAS_HEIGHT);
    ctx.save();
    ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
              RemoteCanvas.CANVAS_HEIGHT / windowHeight);
    ctx.drawWindow(remoteWindow,
                   0, 0,
                   windowWidth, windowHeight,
                   "rgb(255,255,255)");
    ctx.restore();
};

使用方法:

var remoteCanvas = new RemoteCanvas();
remoteCanvas.load();

画像ファイルを base64 文字列に変換する

以下のコードはリモートの画像を取得して、Data URI スキーム に変換します。

var canvas = document.createElement("canvas");
var ctxt = canvas.getContext("2d");
function loadImageFile (url, callback) {
  var image = new Image();
  image.src = url;
  return new Promise((accept, reject) => {
    image.onload = accept;
    image.onerror = reject;
  }).then(accept => {
    canvas.width = this.width;
    canvas.height = this.height;
    ctxt.clearRect(0, 0, this.width, this.height);
    ctxt.drawImage(this, 0, 0);
    accept(canvas.toDataURL());
  });
}

使用方法:

loadImageFile("myimage.jpg").then(string64 => { alert(string64); });

file タイプの <input> 要素を使用してローカルファイルの base64 コンテンツを取得したい場合は、FileReader オブジェクトを使用しなければなりません。

ドキュメントのタグと貢献者

 このページの貢献者: yyss, teoli, Mgjbot, Shimono
 最終更新者: yyss,