はじめに
こんにちは!@70days_jsです。
今日は簡単なお絵かきアプリを作ってみました。
といっても、機能は2つです。笑
- 線を描画する
- 線のサイズを変更する
色の変更や消しゴム機能はありません。
canvas使ってません。
今日は51日目。(2019/12/8)
よろしくお願いします。
サイトURL
やったこと
やったことは2つです。
- 線を描画する
- 線のサイズを変更する
まずhtmlから(全文)↓
<body>
<div id="mouseMoveWrapper">
<div id="positionDisplay">描画停止中</div>
<div>
<div>
<input type="range" min="1" id="range" max="100" step="1" value="1" />
<span id="rangeDisplay">1</span>
</div>
</div>
<div id="mouseMove"></div>
</div>
</body>
id=positionDisplayで描画中かどうか表示しています。
id="range"が文字サイズを変更できるバーです。1〜100の調整ができます。
id=mouseMoveで線を描画します。
次にcss(全文)↓
body {
margin: 0;
overflow: hidden;
}
# mouseMoveWrapper {
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
# mouseMove {
height: 90vh;
width: 90vw;
border: solid 1px black;
}
.dot {
position: absolute;
background-color: black;
width: 1px;
height: 1px;
transform: translateY(-50%) translateX(-50%);
}
.dotクラスが線を描画してくれるクラスです。
transformをつけているのは、カーソルの位置を中心に線を描き始めるためです。
というのも、線は本当は線ではなくてdivで作っており、これがないとカーソルの位置にdivの左上端の部分がきて、ずれているように見えるからです。
最後にJavaScriptです。
長いですが載せます。(全文)↓
let mouseMove = document.getElementById("mouseMove");
let positionDisplay = document.getElementById("positionDisplay");
let rangeWidth = 1;
let rangeHeigt = 1;
let x;
let y;
let flag = false;
mouseMove.addEventListener("mousedown", function() {
flag = true;
});
mouseMove.addEventListener("mouseup", function() {
flag = false;
});
mouseMove.addEventListener("mousemove", function(e) {
drawStatusDisplay();
if (flag) {
x = e.pageX;
y = e.pageY;
let div = document.createElement("div");
div.setAttribute("class", "dot");
div.style.top = y + "px";
div.style.left = x + "px";
div.style.width = rangeWidth + "px";
div.style.height = rangeHeigt + "px";
mouseMove.appendChild(div);
}
});
function drawStatusDisplay() {
if (flag) {
positionDisplay.innerHTML = "描画中";
} else {
positionDisplay.innerHTML = "描画停止中";
}
}
// _____ここからステータスバー_______
let range = document.getElementById("range");
let rangeDisplay = document.getElementById("rangeDisplay");
let dotElements = document.getElementsByClassName("dot");
function rangeChange() {
rangeDisplay.innerHTML = range.value;
rangeWidth = range.value;
rangeHeigt = range.value;
}
range.addEventListener("input", rangeChange);
mousedownとmouseupでマウスを押しているかどうかを判定しています。
押していたらflag変数にtrueを入れ、押していないときはfalseが入っています。
このflag変数を使い、drawStatusDisplay()関数で描画中かどうかを表示しています。
また、描画そのものに関してもこのflag変数を使うことで、マウスが押されていると描画、押されていないと描画しないという風にしています。↓
mouseMove.addEventListener("mousemove", function(e) {
drawStatusDisplay();
if (flag) ←コレ!
rangeについては、rangeWidthとrangeWidthという変数を用意し、描画にもそれを使うことでサイズの変更を実現しています。
他に調べたこと
実は今日promiseで何か作ろうと思っていました。
ですが、なかなか理解できなくて断念。
というわけで、途中までですが調べたことをアウトプットしておきます。
[x] 前提
- JavaScriptはシングルスレッド
- コールバック関数・・・関数が関数を呼び出すこと
[x] 同期処理と非同期処理の違い
- 同期処理・・・記述順に実行する(varとか一部違うけど)
- 非同期処理・・・処理の順番はシャッフル化、実行は1つずつ(ex: イベント処理)
[x] 並列処理と非同期処理の違い
- 並列処理・・・マルチスレッド
- 非同期処理・・・シングルスレッド(ex: promise)
[x] なぜpromise?
- 非同期処理でコールバックを多用すると読みづらい
- → 順序がめちゃくちゃだから
- → 同期的に書こう
- → つまりpromiseとは、実行は非同期処理で、読み方は同期処理
[x] promiseの特徴
- 非同期の関数は本来返したい戻り値の代わりに、呼び出し元にpromiseオブジェクトを返しておく
- 実行できるようになったら、呼び出し元にpromiseオブジェクトを通して値を渡す
[x] JavaScriptのスレッドでやらなくても良い仕事
- タイマー処理
- HTTP通信
- DB周りの処理
感想
divで線を作ると綺麗に書けなかったので、お絵かきアプリを作るならやっぱりcanvasなのかなぁとか思いました。
あと、promise難しい。でも頑張る。
参考
ありがとうございます!