0.環境確認
このサンプルは「色の入力欄」、「レンジ入力欄」を使用しています。
ご利用の環境では動作しない場合がありますので以下のページより確認してください。
以下のとおり「input type=range」、「input type=color」ともに「Yes」であればOK。
1.index.htmlを準備する。
1−1.canvasとlog出力領域を実装する。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>TouchPaint</title>
</head>
<body>
<canvas id="canvas">
This browser is not supported
</canvas>
<p id="log"></p>
<script>
</script>
</body>
</html>
2.canvasにイベントを登録し動作を確認する。
2−1.定義
var canvas = document.getElementById("canvas");
var log = document.getElementById ("log");
2−2.canvasのサイズを指定する
canvas.width = document.width;
canvas.height = document.height - 200;
2−3.イベントを登録する。
canvas.addEventListener("touchstart", touchStartHandler, false);
canvas.addEventListener("touchmove", touchMoveHandler, false);
canvas.addEventListener("touchend", touchEndHandler, false);
function touchStartHandler(e) {
log.innerHTML += "<p>Touch Event: touchstart</p>";
}
function touchMoveHandler(e) {
log.innerHTML += "<p>Touch Event: touchmove</p>";
}
function touchEndHandler(e) {
log.innerHTML += "<p>Touch Event: touchend</p>";
}
2−3.実行結果
3.canvasにマークしてみる
3−1.定義
var context = canvas.getContext("2d");
var touches;
3−2.touchMoveHandlerを書き換える
function touchMoveHandler(e) {
touches = e.touches.item(0);
context.fillRect(touches.pageX - this.offsetLeft, touches.pageY - this.offsetTop, 5, 5);
}
3−3.実行結果
4.点を線で結んでみる
4−1.定義
var drawPath = new Array;
var isMoved = false;
4−2.touchStartHandlerを書き換える
function touchStartHandler(e) {
touches = e.changedTouches;
drawPath.push(touches[0]);
}
4−3.touchMoveHandlerを書き換える
function touchMoveHandler(e) {
touches = e.changedTouches;
context.beginPath();
context.moveTo(drawPath[0].pageX - this.offsetLeft, drawPath[0].pageY - this.offsetTop);
context.lineTo(touches[0].pageX - this.offsetLeft, touches[0].pageY - this.offsetTop);
context.closePath();
context.stroke();
drawPath.splice(0, 1, touches[0]);
e.preventDefault();
}
4−4.touchEndHandlerを書き換える
function touchEndHandler(e) {
if (!isMoved) {
context.beginPath();
context.closePath();
context.fill();
}
isMoved=false;
drawPath.length = 0;
}
4−5.実行結果
5.線の色や太さを変えてみる
5−1.タグを追加
<div class="desc">
<label>Color: <input type="color" class="strokeColor" id="strokeColor"></label>
<label>Line width:
<input type="range" min="5" max="20" step="5" value="5" class="strokeWidth" id="strokeWidth">
</label>
</div>
<button class="clearBtn" id="clearBtn">Clear!</button>
5−2.定義
var strokeColor;
var strokeWidth = 5;
var strokeColorSel = document.getElementById("strokeColor");
var strokeWidthSel = document.getElementById("strokeWidth");
var clearBtn = document.getElementById("clearBtn");
5−3.イベント登録
strokeColorSel.addEventListener("change", changeStrokeColor, false);
strokeWidthSel.addEventListener("change", changeStrokeWidth, false);
clearBtn.addEventListener("click", clearCanvas, false);
function changeStrokeColor() {
strokeColor = this.value;
}
function changeStrokeWidth() {
strokeWidth = this.value;
}
function clearCanvas() {
context.clearRect (0, 0, canvas.width, canvas.height);
}
5−4.functionを追加
function drawPathSetting(idx) {
for (var i = 0; i < drawPath.length; i++) {
var _idx = drawPath[i].identifier;
if (_idx === idx) {
return i;
}
}
return -1;
}
5−5.touchMoveHandlerを書き換える
function touchMoveHandler(e) {
touches = e.changedTouches;
context.lineWidth = strokeWidth;
context.strokeStyle = strokeColor;
context.lineJoin = "round";
for (var i = 0; i < touches.length; i++) {
var idx = drawPathSetting(touches[i].identifier);
context.beginPath();
context.moveTo(drawPath[idx].pageX - this.offsetLeft, drawPath[idx].pageY - this.offsetTop);
context.lineTo(touches[i].pageX - this.offsetLeft, touches[i].pageY - this.offsetTop);
context.closePath();
context.stroke();
drawPath.splice(idx, 1, touches[i])
}
e.preventDefault();
}
5−6.touchEndHandlerを書き換える
function touchEndHandler(e) {
if (!isMoved) {
var startPoint = (Math.PI/180)*0;
var endPoint = (Math.PI/180)*360;
context.fillStyle = strokeColor;
context.beginPath();
context.arc(touches[0].pageX - this.offsetLeft, touches[0].pageY - this.offsetTop, strokeWidth/2, startPoint, endPoint, true);
context.closePath();
context.fill();
}
isMoved=false;
drawPath.length = 0;
}
5−7.実行結果
6.スタイルシートで見栄えを整えてみる。
6−1.スタイルシートを準備する。
style.css
* {
margin:0;padding:0;
}
html, body {
width:100%;height:100%;background:#ddd;
}
h2 {
padding:10px 15px;color:#6587ac;
}
.canvas { width:100%;background:#fff;}
.desc { display:table;width:100%;padding:5px 10px;text-align:right; }
.desc label { display:table-cell;width:50%;white-space:nowrap; }
.desc label:first-child { text-align:left; }
.strokeWidth { width:85px; }
button {
float:right;margin-right:15px;
}
input, button {
vertical-align:middle;
}
@media screen and (max-device-height : 800px) {
.addHeight {height:360px;}
}
@media screen and (min-device-height : 801px) {
.addHeight {height:480px;}
}
6−2.htmlのヘッダー部に追加する
index.html
<link rel="stylesheet" type="text/css" href="css/style.css"/>
6−3.実行結果
7.完成
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>TouchPaint</title>
<link rel="stylesheet" type="text/css" href="css/style.css"/>
</head>
<body>
<canvas id="canvas">
This browser is not supported
</canvas>
<div class="desc">
<label>Color: <input type="color" class="strokeColor" id="strokeColor"></label>
<label>Line width:
<input type="range" min="5" max="20" step="5" value="5" class="strokeWidth" id="strokeWidth">
</label>
</div>
<button class="clearBtn" id="clearBtn">Clear!</button>
<script>
var canvas = document.getElementById("canvas");
var log = document.getElementById ("log");
var context = canvas.getContext("2d");
var strokeColor;
var strokeWidth = 5;
var strokeColorSel = document.getElementById("strokeColor");
var strokeWidthSel = document.getElementById("strokeWidth");
var clearBtn = document.getElementById("clearBtn");
canvas.width = document.width;
canvas.height = document.height - 200;
canvas.addEventListener("touchstart", touchStartHandler, false);
canvas.addEventListener("touchmove", touchMoveHandler, false);
canvas.addEventListener("touchend", touchEndHandler, false);
strokeColorSel.addEventListener("change", changeStrokeColor, false);
strokeWidthSel.addEventListener("change", changeStrokeWidth, false);
clearBtn.addEventListener("click", clearCanvas, false);
var drawPath = new Array;
var isMoved = false;
function touchStartHandler(e) {
touches = e.changedTouches;
drawPath.push(touches[0]);
}
var touches;
function touchMoveHandler(e) {
touches = e.changedTouches;
context.lineWidth = strokeWidth;
context.strokeStyle = strokeColor;
context.lineJoin = "round";
for (var i = 0; i < touches.length; i++) {
var idx = drawPathSetting(touches[i].identifier);
context.beginPath();
context.moveTo(drawPath[idx].pageX - this.offsetLeft, drawPath[idx].pageY - this.offsetTop);
context.lineTo(touches[i].pageX - this.offsetLeft, touches[i].pageY - this.offsetTop);
context.closePath();
context.stroke();
drawPath.splice(idx, 1, touches[i])
}
e.preventDefault();
}
function touchEndHandler(e) {
if (!isMoved) {
var startPoint = (Math.PI/180)*0;
var endPoint = (Math.PI/180)*360;
context.fillStyle = strokeColor;
context.beginPath();
context.arc(touches[0].pageX - this.offsetLeft, touches[0].pageY - this.offsetTop, strokeWidth/2, startPoint, endPoint, true);
context.closePath();
context.fill();
}
isMoved=false;
drawPath.length = 0;
}
function changeStrokeColor() {
strokeColor = this.value;
}
function changeStrokeWidth() {
strokeWidth = this.value;
}
function clearCanvas() {
context.clearRect (0, 0, canvas.width, canvas.height);
}
function drawPathSetting(idx) {
for (var i = 0; i < drawPath.length; i++) {
var _idx = drawPath[i].identifier;
if (_idx === idx) {
return i;
}
}
return -1;
}
</script>
</body>
</html>
style.css
* {
margin:0;padding:0;
}
html, body {
width:100%;height:100%;background:#ddd;
}
h2 {
padding:10px 15px;color:#6587ac;
}
.canvas { width:100%;background:#fff;}
.desc { display:table;width:100%;padding:5px 10px;text-align:right; }
.desc label { display:table-cell;width:50%;white-space:nowrap; }
.desc label:first-child { text-align:left; }
.strokeWidth { width:85px; }
button {
float:right;margin-right:15px;
}
input, button {
vertical-align:middle;
}
@media screen and (max-device-height : 800px) {
.addHeight {height:360px;}
}
@media screen and (min-device-height : 801px) {
.addHeight {height:480px;}
}
最終更新:2013年07月30日 01:03