Skip to content

Instantly share code, notes, and snippets.

@gaogao-9
Last active July 26, 2016 08:00
Show Gist options
  • Save gaogao-9/80be5d94c63a8321fb7e0df852e9bc17 to your computer and use it in GitHub Desktop.
Save gaogao-9/80be5d94c63a8321fb7e0df852e9bc17 to your computer and use it in GitHub Desktop.
'use strict';
/**
* 画像を非同期で読み込む関数
* @param {string} source - 画像URL
* @return {Promise} Imageをthenコールバックの第1引数として渡すPromise
*/
function loadImageAsync(source)
{
return new Promise((resolve, reject) => {
const image = new Image;
const onLoad = () => {
image.removeEventListener('load', onLoad);
image.removeEventListener('error', onError);
resolve(image);
};
const onError = () => {
image.removeEventListener('load', onLoad);
image.removeEventListener('error', onError);
reject(new Error('Failed to load image: ' + source));
};
image.addEventListener('load', onLoad);
image.addEventListener('error', onError);
image.src = source;
});
}
/**
* 画像を合成する関数
* @param {Array} imageSources - 本体画像のURLの配列
* @param {string} colorSource - 色付けに用いる画像のURL
* @param {string} shadeSource - シェーディングに用いる画像のURL
* @param {string} canvasId - canvas要素のid属性値
* @return {Promise} 次の処理に繋げるためのPromise
*/
function synthesizeImage(imageSources, colorSource, shadeSource, canvasId)
{
// 幅,高さ,コンテキストを定義
const width = 580;
const height = 1620;
const context = document.getElementById(canvasId).getContext('2d');
context.clearRect(0, 0, width, height);
// すべてを読み込み終わった後にthenコールバックを実行
// そしてこの関数の返り値もPromiseにし,「synthesizeImageが終わった後の処理」を外部からも書けるようにする
return Promise
.all([shadeSource, colorSource, ...imageSources].map(loadImageAsync))
.then(images => {
// 配列を分解代入 (colorSourceとimageSourcesに対応するImageはotherImagesにまとめる)
const [shadeImage, ...otherImages] = images;
// otherImagesの全要素についてsource-overで描画を実行
for (const image of otherImages) {
context.globalCompositeOperation = 'source-over';
context.globalAlpha = 1.0;
context.drawImage(image, 0, 0, width, height);
}
// shadeImageについてmultiplyで描画を実行
context.globalCompositeOperation = 'multiply';
context.drawImage(shadeImage, 0, 0, width, height);
if (sources === SRC_ARR.back) return;
if (sources === SRC_ARR.right) return;
if (sources === SRC_ARR.left) return;
// 条件を満たすとき,BTN_FRONTを読み込んだ後,描画を実行し,Draw Finish!と表示する
// そして,次のthenコールバックをこのPromiseの後に続けるためにreturnする
return loadImageAsync(BTN_FRONT).then(image => {
context.globalCompositeOperation = 'source-over';
context.globalAlpha = 1.0;
context.drawImage(image, 0, 0, width, height);
console.log('Draw Finish!');
});
});
}
'use strict';
synthesizeImage(/* ...(適宜引数を入れる) */)
.then(() => console.log('All Finish!!')) // 最後にここが実行される
.catch(e => {
console.error((e&&e.stack)||e); // エラー時はここが実行される
});
@gaogao-9
Copy link
Author

teratailの文章の方、編集してコードを2つに分割して、「そしてこれを呼び出す場合には以下のように書きます~」みたいに続けて2つ目のコードを貼っ付ければいいと思います()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment