回答編集履歴
13
簡略化
answer
CHANGED
@@ -91,6 +91,6 @@
|
|
91
91
|
|
92
92
|
synthesizeImage(/* ...(適宜引数を入れる) */)
|
93
93
|
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
94
|
-
.catch(e => console.error(
|
94
|
+
.catch(e => console.error(e.stack || e)); // エラー時はここが実行される
|
95
95
|
```
|
96
96
|
|
12
改善
answer
CHANGED
@@ -24,9 +24,9 @@
|
|
24
24
|
image.removeEventListener('error', onError);
|
25
25
|
reject(new Error('Failed to load image: ' + source));
|
26
26
|
};
|
27
|
-
image.src = source;
|
28
27
|
image.addEventListener('load', onLoad);
|
29
28
|
image.addEventListener('error', onError);
|
29
|
+
image.src = source;
|
30
30
|
});
|
31
31
|
}
|
32
32
|
|
@@ -45,13 +45,12 @@
|
|
45
45
|
const height = 1620;
|
46
46
|
const context = document.getElementById(canvasId).getContext('2d');
|
47
47
|
context.clearRect(0, 0, width, height);
|
48
|
-
|
48
|
+
|
49
49
|
// すべてを読み込み終わった後にthenコールバックを実行
|
50
50
|
// そしてこの関数の返り値もPromiseにし,「synthesizeImageが終わった後の処理」を外部からも書けるようにする
|
51
51
|
return Promise
|
52
52
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
53
53
|
.then(images => {
|
54
|
-
|
55
54
|
// 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
|
56
55
|
const [shadeImage, ...otherImages] = images;
|
57
56
|
|
@@ -66,27 +65,32 @@
|
|
66
65
|
context.globalCompositeOperation = 'multiply';
|
67
66
|
context.drawImage(shadeImage, 0, 0, width, height);
|
68
67
|
|
69
|
-
if (sources
|
68
|
+
if (sources === SRC_ARR.back) return;
|
70
|
-
|
69
|
+
if (sources === SRC_ARR.right) return;
|
71
|
-
|
70
|
+
if (sources === SRC_ARR.left) return;
|
71
|
+
|
72
|
-
|
72
|
+
// 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
|
73
|
-
|
73
|
+
// そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
|
74
|
-
|
74
|
+
return loadImageAsync(BTN_FRONT).then(image => {
|
75
|
-
|
75
|
+
context.globalCompositeOperation = 'source-over';
|
76
|
-
|
76
|
+
context.globalAlpha = 1.0;
|
77
|
-
|
77
|
+
context.drawImage(image, 0, 0, width, height);
|
78
|
-
|
78
|
+
console.log('Draw Finish!');
|
79
|
-
|
79
|
+
});
|
80
|
-
}
|
81
|
-
// 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
|
82
|
-
})
|
83
|
-
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
84
|
-
.catch(e => {
|
85
|
-
console.error(e.message); // エラー時はここが実行される
|
86
|
-
throw e; // 更に外部のcatchに繋げさせる
|
87
80
|
});
|
88
81
|
}
|
89
82
|
```
|
90
83
|
|
91
84
|
- `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
|
92
|
-
- 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
|
85
|
+
- 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
|
86
|
+
|
87
|
+
これを呼び出すときは,以下のように必ずエラーに対応する処理も併せて書きます.
|
88
|
+
|
89
|
+
```JavaScript
|
90
|
+
'use strict';
|
91
|
+
|
92
|
+
synthesizeImage(/* ...(適宜引数を入れる) */)
|
93
|
+
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
94
|
+
.catch(e => console.error((e && e.stack) || e)); // エラー時はここが実行される
|
95
|
+
```
|
96
|
+
|
11
例外処理修正
answer
CHANGED
@@ -81,7 +81,10 @@
|
|
81
81
|
// 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
|
82
82
|
})
|
83
83
|
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
84
|
+
.catch(e => {
|
84
|
-
|
85
|
+
console.error(e.message); // エラー時はここが実行される
|
86
|
+
throw e; // 更に外部のcatchに繋げさせる
|
87
|
+
});
|
85
88
|
}
|
86
89
|
```
|
87
90
|
|
10
comment
answer
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
context.clearRect(0, 0, width, height);
|
48
48
|
|
49
49
|
// すべてを読み込み終わった後にthenコールバックを実行
|
50
|
-
// そ
|
50
|
+
// そしてこの関数の返り値もPromiseにし,「synthesizeImageが終わった後の処理」を外部からも書けるようにする
|
51
51
|
return Promise
|
52
52
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
53
53
|
.then(images => {
|
9
更に修正
answer
CHANGED
@@ -50,7 +50,7 @@
|
|
50
50
|
// それにPromiseを返させて,更に次のthenに繋げる
|
51
51
|
return Promise
|
52
52
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
53
|
-
.then(images =>
|
53
|
+
.then(images => {
|
54
54
|
|
55
55
|
// 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
|
56
56
|
const [shadeImage, ...otherImages] = images;
|
@@ -70,19 +70,16 @@
|
|
70
70
|
sources !== SRC_ARR.right &&
|
71
71
|
sources !== SRC_ARR.left) {
|
72
72
|
// 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
|
73
|
-
// そして,次のthenコールバックを
|
73
|
+
// そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
|
74
|
-
loadImageAsync(BTN_FRONT).then(image => {
|
74
|
+
return loadImageAsync(BTN_FRONT).then(image => {
|
75
75
|
context.globalCompositeOperation = 'source-over';
|
76
76
|
context.globalAlpha = 1.0;
|
77
77
|
context.drawImage(image, 0, 0, width, height);
|
78
78
|
console.log('Draw Finish!');
|
79
|
-
resolve();
|
80
79
|
});
|
81
|
-
return;
|
82
80
|
}
|
83
|
-
// 条件を満たさないときは
|
81
|
+
// 条件を満たさないときは何もしない (すぐに次のthenコールバックが実行される)
|
84
|
-
resolve();
|
85
|
-
})
|
82
|
+
})
|
86
83
|
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
87
84
|
.catch(() => console.error(e.message)); // エラー時はここが実行される
|
88
85
|
}
|
8
return Promise
answer
CHANGED
@@ -36,6 +36,7 @@
|
|
36
36
|
* @param {string} colorSource - 色付けに用いる画像のURL
|
37
37
|
* @param {string} shadeSource - シェーディングに用いる画像のURL
|
38
38
|
* @param {string} canvasId - canvas要素のid属性値
|
39
|
+
* @return {Promise} 次の処理に繋げるためのPromise
|
39
40
|
*/
|
40
41
|
function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
|
41
42
|
{
|
@@ -47,7 +48,7 @@
|
|
47
48
|
|
48
49
|
// すべてを読み込み終わった後にthenコールバックを実行
|
49
50
|
// それにPromiseを返させて,更に次のthenに繋げる
|
50
|
-
Promise
|
51
|
+
return Promise
|
51
52
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
52
53
|
.then(images => new Promise(resolve => {
|
53
54
|
|
@@ -82,7 +83,7 @@
|
|
82
83
|
// 条件を満たさないときは直ちにresolveを呼び出す
|
83
84
|
resolve();
|
84
85
|
}))
|
85
|
-
.then(() => console.log('All Finish!!'))
|
86
|
+
.then(() => console.log('All Finish!!')) // 最後にここが実行される
|
86
87
|
.catch(() => console.error(e.message)); // エラー時はここが実行される
|
87
88
|
}
|
88
89
|
```
|
7
例外処理
answer
CHANGED
@@ -12,13 +12,21 @@
|
|
12
12
|
*/
|
13
13
|
function loadImageAsync(source)
|
14
14
|
{
|
15
|
-
return new Promise(resolve => {
|
15
|
+
return new Promise((resolve, reject) => {
|
16
16
|
const image = new Image;
|
17
|
+
const onLoad = () => {
|
18
|
+
image.removeEventListener('load', onLoad);
|
19
|
+
image.removeEventListener('error', onError);
|
20
|
+
resolve(image);
|
21
|
+
};
|
22
|
+
const onError = () => {
|
23
|
+
image.removeEventListener('load', onLoad);
|
24
|
+
image.removeEventListener('error', onError);
|
25
|
+
reject(new Error('Failed to load image: ' + source));
|
26
|
+
};
|
17
27
|
image.src = source;
|
18
|
-
image.addEventListener('load', function self() {
|
19
|
-
|
28
|
+
image.addEventListener('load', onLoad);
|
20
|
-
|
29
|
+
image.addEventListener('error', onError);
|
21
|
-
});
|
22
30
|
});
|
23
31
|
}
|
24
32
|
|
@@ -75,6 +83,7 @@
|
|
75
83
|
resolve();
|
76
84
|
}))
|
77
85
|
.then(() => console.log('All Finish!!')); // 最後にここが実行される
|
86
|
+
.catch(() => console.error(e.message)); // エラー時はここが実行される
|
78
87
|
}
|
79
88
|
```
|
80
89
|
|
6
コメント
answer
CHANGED
@@ -5,6 +5,11 @@
|
|
5
5
|
```JavaScript
|
6
6
|
'use strict';
|
7
7
|
|
8
|
+
/**
|
9
|
+
* 画像を非同期で読み込む関数
|
10
|
+
* @param {string} source - 画像URL
|
11
|
+
* @return {Promise} Imageをthenコールバックの第1引数として渡すPromise
|
12
|
+
*/
|
8
13
|
function loadImageAsync(source)
|
9
14
|
{
|
10
15
|
return new Promise(resolve => {
|
@@ -17,27 +22,46 @@
|
|
17
22
|
});
|
18
23
|
}
|
19
24
|
|
25
|
+
/**
|
26
|
+
* 画像を合成する関数
|
27
|
+
* @param {Array} imageSources - 本体画像のURLの配列
|
28
|
+
* @param {string} colorSource - 色付けに用いる画像のURL
|
29
|
+
* @param {string} shadeSource - シェーディングに用いる画像のURL
|
30
|
+
* @param {string} canvasId - canvas要素のid属性値
|
31
|
+
*/
|
20
32
|
function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
|
21
33
|
{
|
34
|
+
// 幅,高さ,コンテキストを定義
|
22
35
|
const width = 580;
|
23
36
|
const height = 1620;
|
24
37
|
const context = document.getElementById(canvasId).getContext('2d');
|
25
38
|
context.clearRect(0, 0, width, height);
|
26
39
|
|
40
|
+
// すべてを読み込み終わった後にthenコールバックを実行
|
41
|
+
// それにPromiseを返させて,更に次のthenに繋げる
|
27
42
|
Promise
|
28
43
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
29
44
|
.then(images => new Promise(resolve => {
|
45
|
+
|
46
|
+
// 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
|
30
47
|
const [shadeImage, ...otherImages] = images;
|
48
|
+
|
49
|
+
// otherImagesの全要素についてsource-overで描画を実行
|
31
50
|
for (const image of otherImages) {
|
32
51
|
context.globalCompositeOperation = 'source-over';
|
33
52
|
context.globalAlpha = 1.0;
|
34
53
|
context.drawImage(image, 0, 0, width, height);
|
35
54
|
}
|
55
|
+
|
56
|
+
// shadeImageについてmultiplyで描画を実行
|
36
57
|
context.globalCompositeOperation = 'multiply';
|
37
58
|
context.drawImage(shadeImage, 0, 0, width, height);
|
59
|
+
|
38
60
|
if (sources !== SRC_ARR.back &&
|
39
61
|
sources !== SRC_ARR.right &&
|
40
62
|
sources !== SRC_ARR.left) {
|
63
|
+
// 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
|
64
|
+
// そして,次のthenコールバックを発火させるために,resolveを呼び出す
|
41
65
|
loadImageAsync(BTN_FRONT).then(image => {
|
42
66
|
context.globalCompositeOperation = 'source-over';
|
43
67
|
context.globalAlpha = 1.0;
|
@@ -47,9 +71,10 @@
|
|
47
71
|
});
|
48
72
|
return;
|
49
73
|
}
|
74
|
+
// 条件を満たさないときは直ちにresolveを呼び出す
|
50
75
|
resolve();
|
51
76
|
}))
|
52
|
-
.then(() => console.log('All Finish!!'));
|
77
|
+
.then(() => console.log('All Finish!!')); // 最後にここが実行される
|
53
78
|
}
|
54
79
|
```
|
55
80
|
|
5
Finish修正
answer
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
|
27
27
|
Promise
|
28
28
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
29
|
-
.then(images => {
|
29
|
+
.then(images => new Promise(resolve => {
|
30
30
|
const [shadeImage, ...otherImages] = images;
|
31
31
|
for (const image of otherImages) {
|
32
32
|
context.globalCompositeOperation = 'source-over';
|
@@ -43,10 +43,13 @@
|
|
43
43
|
context.globalAlpha = 1.0;
|
44
44
|
context.drawImage(image, 0, 0, width, height);
|
45
45
|
console.log('Draw Finish!');
|
46
|
+
resolve();
|
46
47
|
});
|
48
|
+
return;
|
47
49
|
}
|
48
|
-
|
50
|
+
resolve();
|
49
|
-
})
|
51
|
+
}))
|
52
|
+
.then(() => console.log('All Finish!!'));
|
50
53
|
}
|
51
54
|
```
|
52
55
|
|
4
constつけ忘れた
answer
CHANGED
@@ -27,7 +27,7 @@
|
|
27
27
|
Promise
|
28
28
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
29
29
|
.then(images => {
|
30
|
-
[shadeImage, ...otherImages] = images;
|
30
|
+
const [shadeImage, ...otherImages] = images;
|
31
31
|
for (const image of otherImages) {
|
32
32
|
context.globalCompositeOperation = 'source-over';
|
33
33
|
context.globalAlpha = 1.0;
|
3
case統一
answer
CHANGED
@@ -17,11 +17,11 @@
|
|
17
17
|
});
|
18
18
|
}
|
19
19
|
|
20
|
-
function synthesizeImage(imageSources, colorSource, shadeSource,
|
20
|
+
function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
|
21
21
|
{
|
22
22
|
const width = 580;
|
23
23
|
const height = 1620;
|
24
|
-
const context = document.getElementById(
|
24
|
+
const context = document.getElementById(canvasId).getContext('2d');
|
25
25
|
context.clearRect(0, 0, width, height);
|
26
26
|
|
27
27
|
Promise
|
@@ -38,7 +38,7 @@
|
|
38
38
|
if (sources !== SRC_ARR.back &&
|
39
39
|
sources !== SRC_ARR.right &&
|
40
40
|
sources !== SRC_ARR.left) {
|
41
|
-
loadImageAsync(
|
41
|
+
loadImageAsync(BTN_FRONT).then(image => {
|
42
42
|
context.globalCompositeOperation = 'source-over';
|
43
43
|
context.globalAlpha = 1.0;
|
44
44
|
context.drawImage(image, 0, 0, width, height);
|
@@ -48,4 +48,7 @@
|
|
48
48
|
console.log('All Finish!');
|
49
49
|
});
|
50
50
|
}
|
51
|
-
```
|
51
|
+
```
|
52
|
+
|
53
|
+
- `btn_front`はグローバル変数のようなので,それと分かるように`SRC_ARR`同様すべて大文字にしました.
|
54
|
+
- 上を除き,原則的にJavaScriptでは`canvas_id`のようにスネークケースではなく`canvasId`のようにキャメルケースにすべて統一する文化のようです.
|
2
ミス
answer
CHANGED
@@ -26,7 +26,8 @@
|
|
26
26
|
|
27
27
|
Promise
|
28
28
|
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
29
|
+
.then(images => {
|
29
|
-
|
30
|
+
[shadeImage, ...otherImages] = images;
|
30
31
|
for (const image of otherImages) {
|
31
32
|
context.globalCompositeOperation = 'source-over';
|
32
33
|
context.globalAlpha = 1.0;
|
1
変数名
answer
CHANGED
@@ -8,16 +8,16 @@
|
|
8
8
|
function loadImageAsync(source)
|
9
9
|
{
|
10
10
|
return new Promise(resolve => {
|
11
|
-
const
|
11
|
+
const image = new Image;
|
12
|
-
|
12
|
+
image.src = source;
|
13
|
-
|
13
|
+
image.addEventListener('load', function self() {
|
14
|
-
|
14
|
+
image.removeEventListener('load', self);
|
15
|
-
resolve(
|
15
|
+
resolve(image);
|
16
16
|
});
|
17
17
|
});
|
18
18
|
}
|
19
19
|
|
20
|
-
function synthesizeImage(
|
20
|
+
function synthesizeImage(imageSources, colorSource, shadeSource, canvas_id)
|
21
21
|
{
|
22
22
|
const width = 580;
|
23
23
|
const height = 1620;
|
@@ -25,22 +25,22 @@
|
|
25
25
|
context.clearRect(0, 0, width, height);
|
26
26
|
|
27
27
|
Promise
|
28
|
-
.all([
|
28
|
+
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
|
29
|
-
.then((
|
29
|
+
.then((shadeImage, ...otherImages) => {
|
30
|
-
for (const
|
30
|
+
for (const image of otherImages) {
|
31
31
|
context.globalCompositeOperation = 'source-over';
|
32
32
|
context.globalAlpha = 1.0;
|
33
|
-
context.drawImage(
|
33
|
+
context.drawImage(image, 0, 0, width, height);
|
34
34
|
}
|
35
35
|
context.globalCompositeOperation = 'multiply';
|
36
|
-
context.drawImage(
|
36
|
+
context.drawImage(shadeImage, 0, 0, width, height);
|
37
37
|
if (sources !== SRC_ARR.back &&
|
38
38
|
sources !== SRC_ARR.right &&
|
39
39
|
sources !== SRC_ARR.left) {
|
40
|
-
loadImageAsync(btn_front).then(
|
40
|
+
loadImageAsync(btn_front).then(image => {
|
41
41
|
context.globalCompositeOperation = 'source-over';
|
42
42
|
context.globalAlpha = 1.0;
|
43
|
-
context.drawImage(
|
43
|
+
context.drawImage(image, 0, 0, width, height);
|
44
44
|
console.log('Draw Finish!');
|
45
45
|
});
|
46
46
|
}
|