2016/06/13

[JavaScript]canvasタグ内の画像を回転させる

canvas内にレンダリングされた画像を回転させるにはどうすればいいのだろうか?

jsdo.itのforked: canvasで表示した画像を回転する(rotate)
にやり方が書いてあって、これをclass化させて、もっと汎用的に使えたならと考えて下のようなプラグイン的なものを作ってみた。

class RotateImage
  constructor: (options) ->
    defaults = {
      baseSelector:''
      img:''
    }
    
    @settings = {}
    
    for k of defaults
      @settings[k] = defaults[k]

    for k of options
      @settings[k] = options[k]

    @_init()

    return @

  _init:()->

    if @settings.baseSelector is '' or typeof @settings.baseSelector is 'undefined' or @settings.baseSelector is null
      return

    if @settings.img is '' or typeof @settings.img is 'undefined' or @settings.img is null
      return

    if not @settings.img instanceof Image
      return

    @img = @settings.img
    @canvas = document.querySelector @settings.baseSelector

  rotate:(d)->
    @_rotate d

  _rotate:(d)->
    width = @img.width
    height = @img.height

    ctx = @canvas.getContext '2d'
    ctx.clearRect 0, 0, @canvas.width, @canvas.height
    ctx.save()
    #ラジアンに変換
    rad = d * Math.PI / 180
    ctx.translate (width/2) , (height/2)
    ctx.rotate rad
    ctx.translate ( -1 * width/2) , (-1 * height/2 )
    ctx.drawImage @img, 0, 0
    ctx.restore()
コンパイルした結果は
// Generated by CoffeeScript 1.8.0
var RotateImage;

RotateImage = (function() {
  function RotateImage(options) {
    var defaults, k;
    defaults = {
      baseSelector: '',
      img: ''
    };
    this.settings = {};
    for (k in defaults) {
      this.settings[k] = defaults[k];
    }
    for (k in options) {
      this.settings[k] = options[k];
    }
    this._init();
    return this;
  }

  RotateImage.prototype._init = function() {
    if (this.settings.baseSelector === '' || typeof this.settings.baseSelector === 'undefined' || this.settings.baseSelector === null) {
      return;
    }
    if (this.settings.img === '' || typeof this.settings.img === 'undefined' || this.settings.img === null) {
      return;
    }
    if (!this.settings.img instanceof Image) {
      return;
    }
    this.img = this.settings.img;
    return this.canvas = document.querySelector(this.settings.baseSelector);
  };

  RotateImage.prototype.rotate = function(d) {
    return this._rotate(d);
  };

  RotateImage.prototype._rotate = function(d) {
    var ctx, height, rad, width;
    width = this.img.width;
    height = this.img.height;
    ctx = this.canvas.getContext('2d');
    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    ctx.save();
    rad = d * Math.PI / 180;
    ctx.translate(width/2 , height/2);
    ctx.rotate(rad);
    ctx.translate(-1 * width / 2, -1 * height / 2);
    ctx.drawImage(this.img, 0, 0);
    return ctx.restore();
  };

  return RotateImage;

})();
使い方は下のように使えばおk
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body{
  margin:0;
}
</style>
</head>
<body>
  <canvas class="_canvas"></canvas>
  <p><input type="file" class="_file"></p>
  <p><input type="text" value="0" name="d">回転</p>
  <p><input type="button" value="回転"></p>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="./rotateImage.1.0.0.js"></script>
<script>
jQuery(function(){
  var rotateImage;
  $('input[type="button"]').on('click',function(){
    rotateImage.rotate($('input[name="d"]').val())
  });

  $('._file').on('change',function(e){
    var currentTarget = e.currentTarget;
    var $currentTarget = $(currentTarget);

    var file = currentTarget.files[0];
    var dataUrl = URL.createObjectURL(file);
    var image = new Image();

    image.onload = function(){

      var $canvas = $('._canvas');
      var canvas = $canvas[0];

      var width = image.width;
      var height = image.height;
      canvas.width = height;
      canvas.height = width;

      var ctx = canvas.getContext('2d');
      ctx.drawImage(image , 0, 0);

      rotateImage = new RotateImage({
        baseSelector:'._canvas',
        img:image
      });
    };
    image.src = dataUrl;
  });

});
</script>
</body>
</html>

0 コメント:

コメントを投稿