LoginSignup
2
0

More than 3 years have passed since last update.

年末まで毎日webサイトを作り続ける大学生 〜51日目 簡単なお絵かきアプリを作る〜

Last updated at Posted at 2019-12-08

はじめに

こんにちは!@70days_jsです。

今日は簡単なお絵かきアプリを作ってみました。
といっても、機能は2つです。笑

  1. 線を描画する
  2. 線のサイズを変更する

色の変更や消しゴム機能はありません。
canvas使ってません。

今日は51日目。(2019/12/8)
よろしくお願いします。

サイトURL

やったこと

test3.gif

やったことは2つです。

  1. 線を描画する
  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難しい。でも頑張る。

参考

  1. JavaScriptの非同期処理を並列処理と勘違いしていませんか? - Qiita

ありがとうございます!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0