English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
前書き
RequireJSの登場により、フロントエンドコードのモジュール化が容易になりました。プロジェクトが大きくなり、コードが増えると、モジュール化されたコードはプロジェクト構造をより明確にし、開発中に考え方が明確になるだけでなく、後期のメンテナンスも容易になります。以下は、RequireJSを学んだ後で開発した簡単な描画プログラムで、ブラウザ上で以下のように動作します:
RequireJSについてまだ十分に理解していない場合は、私のRequireJS学習ノートを見てください:http://blog.csdn.net/yubo_725/記事/詳細/52913853
始めます
この簡単な描画プログラムのプロジェクト構造は以下の図の通りです:
その中でindex.htmlはプロジェクトのホームページで、jsディレクトリにはすべてのjsファイルが保存されています、js/appディレクトリにはカスタムモジュールファイルが保存されています、js/libディレクトリには一時的にファイルがありませんが、プロジェクトに他のフロントエンドフレームワーク(jQueryなど)が使用される場合、js/libディレクトリにはこれらのフレームワークのjsファイルが保存されています、js/main.jsはrequirejsの設定ファイルで、主にパスの設定を行います、js/require.min.jsはRequireJSフレームワークのファイルです。以下に従って簡単な描画プログラムを一つずつ進めてみましょう!
一、requirejsの設定
このプロジェクトの設定ファイルコードはjsに置かれています/main.js中、コード内容は以下の通りです:
require.config({ baseUrl: 'js'/ lib', paths: {/app: '.. } })
/主にプロジェクトのルートディレクトリを'js/lib'、そして'app'という名前のパスを設定し、パスは'..'です。/app'、すなわち'js
app'ディレクトリ。
二、モジュールコードの作成
このプロジェクトのモジュールには以下のものがあります:point.js, line.js, rect.js, arc.js, utils.js。それぞれ説明します:
point.js:
/** point.jsこのモジュールはポイント(x, y)を表すもので、以下のようにコードされています: */ define(function() { ポイント return function(x, y) { this.x = x; this.y = y; this.equals = function(point) { }; }; })
return this.x === point.x && this.y === point.y;
上記のコードではdefineでポイントモジュールを定義し、コールバック関数でクラスを返して、このクラスにはx、yの2つの引数と、2つのポイントが等しいかどうかを比較するequalsメソッドがあります。
require(['app/このモジュールを使用するには以下のようにコードを使用できます: //point'], function(Point) { ポイントクラスのオブジェクトを新たに作成3, 5); })
var point = new Point(
ここでは注意が必要です。require()関数の最初の引数は配列であり、コールバック関数内のPointはポイントクラスを表しており、new Point()の方法でポイントクラスのオブジェクトを作成します。
line.js:
/** line.jsモジュールは直線を表すもので、以下のようにコードされています: */ define(function() { 直線 this.startPoint = startPoint; return function(startPoint, endPoint) { this.drawMe = function(context) { context.strokeStyle = "#000000"; context.beginPath(); this.endPoint = endPoint; context.moveTo(this.startPoint.x, this.startPoint.y); context.closePath(); context.stroke(); } } })
context.lineTo(this.endPoint.x, this.endPoint.y);
直線モジュールの定義はポイントモジュールの定義と似ており、defineのコールバック関数でクラスを返します。直線クラスのコンストラクタにはポイントクラスの2つの引数が含まれており、これが直線の始点と終点を表します。直線クラスにはdrawMeメソッドもあり、contextオブジェクトを渡すことで自身を描画します。
rect.js:
/** rect.jsモジュールは矩形を表すもので、以下のようにコードされています: */ 矩形/point'], function() { return function(startPoint, width, height) { this.startPoint = startPoint; this.width = width; this.height = height; this.drawMe = function(context) { context.strokeStyle = "#000000"; context.strokeRect(this.startPoint.x, this.startPoint.y, this.width, this.height); } } })
其中startPoint是矩形左上角的点的坐标,是一个point类,width和height分别代表矩形的宽高,同时还有一个drawMe方法将矩形自身画出来。
arc.js:
arc.js模块代表一个圆形,代码如下:
/** 圆形 */ define(function() { return function(startPoint, radius) { this.startPoint = startPoint; this.radius = radius; this.drawMe = function(context) { context.beginPath(); context.arc(this.startPoint.x, this.startPoint.y, this.radius, 0, 2 * Math.PI); context.closePath(); context.stroke(); } } })
其中startPoint代表圆形所在的矩形的左上角的点的坐标,radius代表圆的半径,drawMe方法是画圆的方法。
在以上几个模块中,直线类、矩形类、圆形类都包含有drawMe()方法,这里涉及到了canvas绘图的知识,如果有不太清楚的,可以查一下文档:HTML 5 Canvas 参考手册
utils.js
utils.js模块主要是用来处理各种图形绘制的工具类,包括直线、矩形、圆形的绘制,也包括记录绘制轨迹、清除绘制轨迹,代码如下:
/** 管理绘图的工具 */ define(function() { var history = []; //用来保存历史绘制记录的数组,里面存储的是直线类、矩形类或者圆形类的对象 function drawLine(context, line) { line.drawMe(context); } function drawRect(context, rect) { rect.drawMe(context); } function drawArc(context, arc) { arc.drawMe(context); } /** 描画トラッキングを追加 */ function addHistory(item) { history.push(item); } /** 履歴トラッキングを描画 */ function drawHistory(context) { for(var i = 0; i < history.length; i++) { var obj = history[i]; obj.drawMe(context); } } /** 履歴トラッキングをクリア */ function clearHistory() { history = []; } return { drawLine: drawLine, drawRect: drawRect, drawArc: drawArc, addHistory: addHistory, drawHistory: drawHistory, clearHistory: clearHistory }; })
3. インターフェースコードの作成、マウスイベントの処理
上記では、今回の簡単な描画プログラムのモジュールすべてを定義しました。図形を描画する際には、上記のモジュールを使用します。以下では、メインインターフェースのコードの作成を始めます。メインインターフェースには、四つのボタンが含まれており、大きなキャンバスが描画に使用されます。以下にindex.htmlファイルのコードを示します:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>簡単な描画プログラム</title> <style type="text/css"> canvas { background-color: #ECECEC; cursor: default; /** マウスカーソルをデフォルトの指針に設定 */ } .tool-bar { margin-bottom: 10px; } </style> </head> <body> <div class="tool-bar"> <button id="btn-line">直線を描画</button> <button id="btn-rect">矩形を描画</button> <button id="btn-oval">円を描画</button> <button id="btn-clear">キャンバスをクリア</button> <span id="hint" style="color: red;">現在の操作:直線を描画</span> </div> <canvas id="canvas" width="800" height="600"></canvas> <script type="text/javascript" src="js/require.min.js" data-main="js/main"></script> <script type="text/javascript"> require(['app/point', 'app/line', 'app/rect', 'app/arc', 'app/utils'], function(Point, Line, Rect, Arc, Utils) { var canvas = document.getElementById("canvas"); var context = canvas.getContext('2d'); var canvasRect = canvas.getBoundingClientRect(); //キャンバスの矩形を取得 canvas.addEventListener('mousedown', handleMouseDown); canvas.addEventListener('mousemove', handleMouseMove); canvas.addEventListener('mouseup', handleMouseUp); bindClick('btn-clear', menuBtnClicked); bindClick('btn-line', menuBtnClicked); bindClick('btn-rect', menuBtnClicked); bindClick('btn-oval', menuBtnClicked); var mouseDown = false; var selection = 1; // 0, 1, 2それぞれ直線、矩形、円を描画する var downPoint = new Point(0, 0), movePoint = new Point(0, 0), upPoint = new Point(0, 0); var line; var rect; var arc; /** 処理マウスダウンイベント */ function handleMouseDown(event) { downPoint.x = event.clientX - canvasRect.left; downPoint.y = event.clientY - canvasRect.top; if(selection === 0) { line = new Line(downPoint, downPoint); line.startPoint = downPoint; } 1) { rect = new Rect(new Point(downPoint.x, downPoint.y), 0, 0); } 2) { arc = new Arc(new Point(downPoint.x, downPoint.y), 0); } mouseDown = true; } /** マウス移動イベントを処理します */ function handleMouseMove(event) { movePoint.x = event.clientX - canvasRect.left; movePoint.y = event.clientY - canvasRect.top; if(movePoint.x == downPoint.x && movePoint.y == downPoint.y) { return ; } if(movePoint.x == upPoint.x && movePoint.y == upPoint.y) { return ; } if(mouseDown) { clearCanvas(); if(selection == 0) { line.endPoint = movePoint; Utils.drawLine(context, line); } else if(selection == 1) { rect.width = movePoint.x - downPoint.x; rect.height = movePoint.y - downPoint.y; Utils.drawRect(context, rect); } else if(selection == 2) { var x = movePoint.x - downPoint.x; var y = movePoint.y - downPoint.y; arc.radius = x > y &63; (y / 2) : (x / 2); if(arc.radius < 0) { arc.radius = -arc.radius; } arc.startPoint.x = downPoint.x + arc.radius; arc.startPoint.y = downPoint.y + arc.radius; Utils.drawArc(context, arc); } Utils.drawHistory(context); } } /** マウスアップイベントを処理します */ function handleMouseUp(event) { upPoint.x = event.clientX - canvasRect.left; upPoint.y = event.clientY - canvasRect.top; if(mouseDown) { mouseDown = false; if(selection == 0) { line.endPoint = upPoint; if(!downPoint.equals(upPoint)) { Utils.addHistory(new Line(new Point(downPoint.x, downPoint.y), new Point(upPoint.x, upPoint.y))); } } else if(selection == 1) { rect.width = upPoint.x - downPoint.x; rect.height = upPoint.y - downPoint.y; Utils.addHistory(new Rect(new Point(downPoint.x, downPoint.y), rect.width, rect.height)); } else if(selection == 2) { Utils.addHistory(new Arc(new Point(arc.startPoint.x, arc.startPoint.y), arc.radius)); } clearCanvas(); Utils.drawHistory(context); } } /** キャンバスをクリアする */ function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); } /** メニューボタンのクリックイベントハンドラ */ function menuBtnClicked(event) { var domID = event.srcElement.id; if(domID === 'btn-clear') { clearCanvas(); Utils.clearHistory(); } else if(domID == 'btn-line') { selection = 0; showHint('現在の操作:線を描く'); } else if(domID == 'btn-rect') { selection = 1; showHint('現在の操作:矩形を描く'); } else if(domID == 'btn-oval') { selection = 2; showHint('現在の操作:円を描く'); } } function showHint(msg) { document.getElementById('hint').innerHTML = msg; } /** 対応するidのdom要素にクリックイベントをバインドする */ function bindClick(domID, handler) { document.getElementById(domID).addEventListener('click', handler); } }); </script> </body> </html>
index.htmlファイルには多くのコードがありますが、最も重要なコードはマウスの押下、移動、リリースの3つのイベントのリスニングと処理です。また、マウスがcanvas内の座標を取得する際には注意が必要です:eventオブジェクトから取得されたclientXとclientYは、マウスがページに対する座標です。canvas内の座標を取得するために、canvasの矩形エリアを取得し、clientX-canvas.left、clientY-canvas.top、マウスがcanvas内の位置を取得するために使用されます。
ソースコード
このブログのソースコードはgithubにホストされています。ここをクリックして確認してください。ソースコード
既知のバグ
円を描く際には、左上から右下にマウスをドラッグして円を描く必要があります。そうでない場合、円の場所に問題が発生します。
これでこの記事はすべて終わりです。皆様の学習に役立てば幸いです。また、呐喊チュートリアルを多くのサポートをお願いします。
声明:この記事の内容はインターネットから収集され、著作権者に帰属します。インターネットユーザーが自発的に貢献し、自己でアップロードしました。このサイトは所有権を持ちません。人工編集は行われていません。また、関連する法的責任を負いません。著作権侵害の疑いがある場合は、以下のメールアドレスにご連絡ください:notice#oldtoolbag.com(メール送信時、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がついたら、このサイトは即座に侵害疑いのコンテンツを削除します。)