Skip to content

Instantly share code, notes, and snippets.

@ykob
Last active June 12, 2016 17:10
Show Gist options
  • Save ykob/33c6c917e0cdd9c1895a to your computer and use it in GitHub Desktop.
Save ykob/33c6c917e0cdd9c1895a to your computer and use it in GitHub Desktop.
export default class Preloader {
constructor() {
this.data = null;
this.callbackLoadedData = null;
this.callbackLoadedDataAll = null;
this.count_loaded = 0;
this.complete = false;
}
start(data, callbackLoadedData, callbackLoadedDataAll) {
if (!data.isArray) return;
this.data = data;
this.callbackLoadedData = callbackLoadedData;
this.callbackLoadedDataAll = callbackLoadedDataAll;
const reg = /(.*)(?:\.([^.]+$))/;
for (var i = 0; i < this.data.length; i++) {
const data = this.data[i];
switch (data.match(reg)[2]) {
case 'png':
case 'jpg':
case 'gif':
const image = new Image();
image.onload = () => {
this.loadedData();
};
image.src = data;
break;
case 'mp4':
const video = document.createElement('video');
video.addEventListener('loadeddata', () => {
this.loadedData();
});
video.src = data;
video.load();
break;
default:
this.loadedData();
}
}
}
loadedData() {
this.count_loaded++;
if (this.callbackLoadedData) this.callbackLoadedData();
if (this.count_loaded >= this.data.length) {
this.loadedDataAll();
}
}
loadedDataAll() {
this.complete = true;
if (this.callbackLoadedDataAll) this.callbackLoadedDataAll();
}
}
@sugarshin
Copy link

これって動いてます? if (!data.isArray) return; で必ず return されちゃうと思うんですが。あと、せっかくならちゃんとリポジトリにして OSS 化しましょうよ

@sugarshin
Copy link

sugarshin commented May 27, 2016

ぼくならこうかな

export default class Preloader {
  constructor(sources) {
    this._sources = Array.isArray(sources) ? sources : [sources];
  }
  load() {
    return Promise.all(
      this._sources.map(src => (
        this._imageRegex.test(src) && this._loadImage(src) ||
        this._videoRegex.test(src) && this._loadVideo(src) || Promise.reject(src)
      ))
    );
  }
  _loadImage(src) {
    return new Promise((resolve, reject) => {
      const image = new Image();
      image.addEventListener('load', resolve);
      image.addEventListener('error', reject);
      image.src = src;
    });
  }
  _loadVideo(src) {
    return new Promise((resolve, reject) => {
      const video = document.createElement('video');
      video.addEventListener('loadeddata', resolve);
      video.addEventListener('error', reject);
      video.src = src;
      video.load();
    });
  }
  get _imageRegex() {
    return /.+\.(png|jpe?g|gif)$/i;
  }
  get _videoRegex() {
    return /.+\.(mp4|webm)$/i;
  }
}

// Usage

import Preloader from './Preloader';

const loader = new Preloader(['../assets/example00.png', '../assets/example01.jpg', '../assets/example02.mp4']);
loader.load()
  .then(events => events.forEach(ev => console.log(`${ev.target} loaded !!!`)))
  .catch(errors => console.log(`Unkown errors ${errors}`));

@ykob
Copy link
Author

ykob commented May 30, 2016

if (!data.isArray) return;

これはテストしてない!ちゃんとテストします…
OSSはPreloadJSみたいなものがあるし、そっちに任せればいいかな。

@sugarshin
Copy link

PreloadJS は CreateJS 依存だし、非 npm フレンドリーなのでだいぶ使いづらいので、こういうライトでミニマムなものは需要あると思いますけどね!
ちなみに上のやつの progress の callback もとれる版です https://gist.github.com/sugarshin/146fb1cb1626fa784bf7be69f7cce58f

@ykob
Copy link
Author

ykob commented May 31, 2016

PreloadJS は CreateJS 依存だし、非 npm フレンドリーなのでだいぶ使いづらいので

そうなんだ!じゃあリポジトリにしようかな。
個人的には受託でもガンガン使いたいから、あまりbabelによっかかり過ぎないようにしようっていう思惑もあったりします。

@sugarshin
Copy link

Babel はどんどん利用すべきですよ!AltJSとは違って、あくまで標準仕様のJavaScriptですから!ただ未来を先取りしてるだけで、Webの性質上、古いブラウザもサポートするしがらみがある以上 Babel はおそらく、数年先も使ってると思いますよ!例えば今のブラウザたちがES2015をサポートしきったとして、ESは今後毎年リリースされるので、また新しい仕様を使うためには Babel 使うことになるからです!

@ykob
Copy link
Author

ykob commented Jun 1, 2016

個人的には完全に同意なんだけど、編集ファイルをお客さんに納品したり、技術力の低いエンジニアと一緒に作業したりするケースがあるから、ネックになるんだよね…でも、それはそのときに個別に考えたらいいかな。もらったコードで僕も勉強しつつ、リポジトリにしてみます!

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