JavaScript > Canvas要素に描画した画像の回転
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>キャンバス画像の回転サンプル</title> | |
<link rel="stylesheet" href="bootstrap.min.css" media="all"> | |
<link rel="stylesheet" href="bootstrap-responsive.min.css" media="all"> | |
<link rel="stylesheet" href="rotate.css" media="all"> | |
<script src="jquery-1.8.2.min.js"></script> | |
<script src="bootstrap.min.js"></script> | |
<script src="rotate.js"></script> | |
</head> | |
<body> | |
<div class="container" style="margin-top: 1em;"> | |
<p>canvas要素に描画した画像の回転。</p> | |
<!-- メインコンテンツ --> | |
<div class="row"> | |
<!-- ファイルアップロード --> | |
<div id="upload-wrapper"><input id="upload" name="upload" type="file" value="File Upload"></div> | |
<div id="view" class="view"> | |
<p style="color: white; font-size: 2em; line-height: 428px; text-align: center">画像をドラッグ&ドロップしてください。</p> | |
</div> | |
<div class="tuple"> | |
<button id="rotate" class="btn btn-large btn-info">右90度回転</button> | |
</div><!-- tuple --> | |
</div><!-- /row --> | |
</div><!-- /container --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "utf-8"; | |
/** | |
* Copyright 2012 Sawai Hiroshi | |
* http://www.info-town.jp | |
* | |
*/ | |
body { | |
line-height: 1.5; | |
} | |
h1 { | |
color: #0088CC; | |
} | |
#header { | |
margin-bottom: 2em; | |
} | |
#upload-wrapper { | |
margin-bottom: 1em; | |
} | |
.row { | |
margin-bottom: 2em; | |
} | |
.tuple { | |
margin: 1em 0; | |
} | |
.btn { | |
width: 170px; | |
} | |
.view { | |
position: relative; | |
height: 428px; | |
background: #000; | |
} | |
.num-input { | |
width: 44px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Canvasを時計回りに90度回転 | |
* | |
* @author Hiroshi Sawai <info@info-town.jp> | |
*/ | |
jQuery(function($) { | |
var img; | |
var canvas = $('<canvas>').appendTo($('#view')).get(0); | |
var cxt = canvas.getContext('2d'); | |
// 画像が読み込まれていればtrueを返す。読み込まれていなければアラートを表示しfalseを返す | |
function checkImage (img) { | |
if ((img.width > 0) === false ) { | |
alert('画像がありません。'); | |
return false; | |
} | |
return true; | |
} | |
// 適切な画像タイプならばtrue。対応していないタイプならばアラートを表示してfalseを返す | |
function checkFileType(text) { | |
// ファイルタイプの確認 | |
if (text.match(/^image\/(png|jpeg|gif)$/) === null) { | |
alert('対応していないファイル形式です。\nファイルはPNG, JPEG, GIFに対応しています。'); | |
return false; | |
} | |
return true; | |
} | |
/* | |
* 画像ファイル読み込み・表示 | |
* 画像をキャンパスへ描画する基本的な流れ | |
* <ul> | |
* <li>img要素を作成(ノードには追加しない) | |
* <li>img要素に画像を読込 | |
* <li>img要素をcanvasへ描画 | |
* </ul> | |
*/ | |
// img要素から画像データを | |
function loadImg(width, height) { | |
return function() { | |
// 画像ファイル読込はoriginalを初期化 | |
if (typeof width === 'undefined' || typeof height === 'undefined') { | |
original = null; | |
} | |
// サイズの設定 | |
width = width || this.width; | |
height = height || this.height; | |
canvas.width = width; | |
canvas.height = height; | |
// 読込 | |
try { | |
cxt.clearRect(0, 0, canvas.width, canvas.height); | |
cxt.drawImage(this, 0, 0, width, height); | |
if (original === null) { | |
original = cxt.getImageData(0, 0, width, height); | |
$('#org-width').val(width); | |
$('#org-height').val(height); | |
} | |
$(this).remove(); | |
} catch (e) { | |
alert('画像を開けませんでした。'); | |
} | |
}; | |
} | |
// 画像読込ハンドラ | |
function readFile(reader) { | |
return function() { | |
if ($('#view p').length > 0) { | |
$('#view p').remove(); | |
} | |
// imgへオブジェクトを読み込む | |
img = $('<img>').get(0); | |
img.onload = loadImg(); | |
img.setAttribute('src', reader.result); | |
}; | |
} | |
// 参照ボタンで読込処理 | |
$('#upload').change (function() { | |
var file, reader; | |
// 選択したファイル情報 | |
file = this.files[0]; | |
// ファイルタイプの確認 | |
if (checkFileType(file.type) === false) { | |
return false; | |
} | |
// canvasに描画 | |
reader = new FileReader(); | |
reader.onload = readFile(reader); | |
reader.readAsDataURL(file); | |
}); | |
// ドラッグアンドドロップで読込 | |
$('#view').get(0).ondragover = function() { | |
return false; | |
}; | |
// bind('ondrop', function() {});はうまく動かなかった(2012.11.07) | |
$('#view').get(0).ondrop = function(event) { | |
var file, reader; | |
if (event.dataTransfer.files.length === 0) { | |
alert('画像を開けませんでした。'); | |
return false; | |
} | |
// ドロップされたファイル情報 | |
file = event.dataTransfer.files[0]; | |
// ファイルタイプの確認 | |
if (checkFileType(file.type) === false) { | |
return false; | |
} | |
// Canvasへの描画 | |
reader = new FileReader(); | |
reader.onload = readFile(reader); | |
reader.readAsDataURL(file); | |
// バブリング・デフォルト処理停止 | |
event.stopPropagation(); | |
event.preventDefault(); | |
}; | |
/* | |
* 回転 | |
*/ | |
function rotate(img) { | |
return function() { | |
var width = canvas.width; | |
var height = canvas.height; | |
canvas.width = height; | |
canvas.height = width; | |
cxt.clearRect(0, 0, canvas.width, canvas.height); | |
cxt.translate(canvas.width / 2, canvas.height / 2); | |
cxt.rotate(90 * Math.PI / 180); | |
cxt.translate(- img.width / 2, -img.height / 2); | |
cxt.drawImage(img, 0, 0, img.width, img.height); | |
}; | |
} | |
// 回転 | |
$('#rotate').click(function (event) { | |
var canvasData = canvas.toDataURL(); | |
var img = $('<img>').get(0); | |
img.onload = rotate(img); | |
img.setAttribute('src', canvasData); | |
// バブリング・デフォルト停止 | |
event.stopPropagation(); | |
event.preventDefault(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment