# G's DEV19 No.3メモアプリ課題 質問回答 ID05
> ①入力した記録が入力順に並ばない(日付順にならない)
localStoarge のキーの順番は担保されておらず、恐らくブラウザによっても取り出される順番はバラバラかなと思います。
入力した順と日付順とではアプローチが変わるかなと思います。
入力した順の場合 入力順が担保される配列を利用する方法が一番手っ取り早いかなと思います。
例えば、入力された順のキーを保持しておくデータを持つとか、入力されるデータそのものを大きな配列の中に格納して 1つの `key : value` で保存するとか。
あるいは各データに順番を `key: {index: n, data: 'xxxx'}` のような感じで登録しておき、全データを取り出した後にデータ持っている順番で並び替えてから表示させる。(だたこの方法は削除機能を追加すると index は飛び飛びになってしまいます。)
日付順で表示するには、全データを格納した配列を作成して日付を比較してデータをソートしてから表示させる必要があります。
日付が `"2021-03-01"` のような文字列になっているなら `Date()` を使って数値にして比較させるようにします。
日付を タイムスタンプ という数値で保存しておく場合は、数値で比較して HTML に表示させる際に `"2021-03-01"` のような形にフォーマットします。
Date() で実装もできますが day.js などライブラリを利用するのが簡単かなと思います。
ソートについては `Array.sort()` に比較方法の関数を渡してその中で日付の比較を行うようにする感じですね〜
cf.
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
- https://chaika.hatenablog.com/entry/2020/01/04/090000
> ②Javascript クリックした後の感情ごとの動作をスマートに書きたかった
僕の場合はですが、処理を関数にまとめる考え方は次のような手順で考えています
1. 同じコードがある箇所は関数にまとめられる。
2. 部分的に異なる部分は変数や引数に置き換えられる。
質問にあった感情ごとの動作 = canvas に円を描く処理を見ていくと、
fillStyle と strokeStyle のカラーを決めるのに使う配列が異なるだけで他の処理は同じです。
なので、 fillStyle と strokeStyle を渡せば canvas にランダムなサイズの円を書く関数にまとめられるかなと思います。
```js
function drawArc(fillStyle, strokeStyle) {
console.log(fillStyle, strokeStyle);
// X値:10~400, Y値:10~350,半径:8~50
const arcXs = Math.floor(Math.random()*(400+1-10))+10;
const arcYs = Math.floor(Math.random()*(350+1-10))+10;
const radius = Math.floor(Math.random()*(50+1-8))+8;
//パスの開始
ctx.beginPath();
//丸の色指定
ctx.fillStyle = fillStyle;
//丸の外側の線の太さ
ctx.lineWidth = 10;
ctx.strokeStyle = strokeStyle;
//円の設定(X中心軸,Y中心軸、半径、円のスタート度、円のエンド度、回転)
ctx.arc(arcXs, arcYs, radius, 0, Math.PI * 2, false);
//描画
ctx.stroke()
ctx.fill();
}
function getArcColer(colorSet) {
const colorSetLength = colorSet.length;
const fillStyle = colorSet[Math.floor(Math.random()*colorSetLength)];
const strokeStyle = colorSet[Math.floor(Math.random()*colorSetLength)];
return [fillStyle, strokeStyle];
}
// Fun
const [fillStyle, strokeStyle] = getArcColer(getArcColer);
drawArc(fillStyle, strokeStyle);
// Sad
const [fillStyle, strokeStyle] = getArcColer(sadColors);
drawArc(fillStyle, strokeStyle);
// Angry
const [fillStyle, strokeStyle] = getArcColer(angryColors);
drawArc(fillStyle, strokeStyle);
// 省略した書き方
drawArc(...getArcColer(COLOR_SET));
```
> ③クリアボタンを押した時に言葉の方は消えますが、画像は再読み込みしないと消せませんでした。
jQuery の `empty()` メソッドが使われていました。
これは `$()` で指定した要素の中になる HTML 要素を消すメソッドです。
言葉は `#list` タグの中に HTML として追加されているのでこの方法で消すことができます。
対して canvas は <canvas> タグの中に描画したものが HTML 要素として追加されるわけではあありません。(Chrome の devtool を見ていると判ると思います)
ですので、canvas タグの中には HTML 要素が無いので `$(canvas).empty()` では何も消えていないという状況です。
cnvas は独特な描画方法があるのと同じで、描画した要素を消すには `ctx.clearRect()` を使います。
JS cnvas clear とか JS canvas 操作 などで検索すると情報が出てきますよ〜
cf.
- http://semooh.jp/jquery/api/manipulation/empty/_/
- https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/clearRect