show.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. 'use strict';
  2. (() => {
  3. function Show(parent, files, delay) {
  4. this.index = 0;
  5. this.elapsed = 0;
  6. this.playing = true;
  7. this.list = [];
  8. this.updated = Date.now();
  9. this.delay = !isNaN(delay) ? delay : 3000;
  10. this.parent = parent;
  11. this.parent.innerHTML = '';
  12. this.parent.appendChild(document.createElement('span'));
  13. (async () => {
  14. await this.parse(files);
  15. window.requestAnimationFrame(() => { this.render(); });
  16. window.addEventListener('keyup', (e) => {
  17. if (!e.keyCode) return;
  18. if (e.keyCode === 32) { this.toggle(); }
  19. else if (e.keyCode === 37) { this.prev(); }
  20. else if (e.keyCode === 39) { this.next(); }
  21. }, false);
  22. })();
  23. };
  24. Show.prototype.toggle = function() { this.playing = !this.playing; };
  25. Show.prototype.next = function() {
  26. if (++this.index >= this.list.length) this.index = 0;
  27. this.elapsed = 0;
  28. };
  29. Show.prototype.prev = function() {
  30. if (--this.index < 0) this.index = this.list.length-1;
  31. this.elapsed = 0;
  32. };
  33. Show.prototype.format = function(f, a) {
  34. f = f.replaceAll('%s', a);
  35. for (let start = f.indexOf('%'); f.length > start+3 && f[start+3] === 's'; ) {
  36. let c = String(f[start+1]);
  37. let w = parseInt(f[start+2]);
  38. let r = (String(a).length >= w) ? a : (new Array(w).join(c)).concat(a).slice(-w);
  39. f = f.replace(f.slice(start, start+4), r);
  40. }
  41. return f;
  42. };
  43. Show.prototype.preload = async function(file, delay) {
  44. const o = { p: file };
  45. if (o.p.endsWith('.mp4') || o.p.endsWith('.webm') || o.p.endsWith('.ogg')) {
  46. o.e = document.createElement('video');
  47. o.e.addEventListener('error', () => { this.list.splice(this.list.indexOf(o), 1); }, {once: true});
  48. o.e.addEventListener('canplay', () => { o.d = (isNaN(delay) ? 1 : delay) * o.e.duration * 1000; }, {once: true});
  49. o.e.muted = true;
  50. o.e.loop = true;
  51. o.e.src = o.p;
  52. } else {
  53. o.e = document.createElement('img');
  54. o.e.addEventListener('error', () => { this.list.splice(this.list.indexOf(o), 1); }, {once: true});
  55. o.d = isNaN(delay) ? this.delay : delay;
  56. o.e.src = o.p;
  57. }
  58. this.list.push(o);
  59. }
  60. Show.prototype.parse = async function(files) {
  61. if (!(files instanceof Array)) return;
  62. files.map((o) => {
  63. if (typeof o === 'string') {
  64. this.preload(o);
  65. } else if (o instanceof Object && !(o instanceof Array) && typeof o.file !== 'undefined' && typeof o.file === 'string') {
  66. if (o.file.indexOf('%') > -1 && typeof o.range !== 'undefined' && o.range instanceof Array) {
  67. if (o.range.length === 2 && !(isNaN(o.range[2]) && isNaN(o.range[1])) && parseInt(o.range[0]) < parseInt(o.range[1])) {
  68. for (let i = parseInt(o.range[0]); i <= parseInt(o.range[1]); i++) {
  69. this.preload(this.format(o.file, i), o.delay);
  70. }
  71. } else {
  72. for (let i of o.range) {
  73. this.preload(this.format(o.file, i), o.delay);
  74. }
  75. }
  76. } else {
  77. this.preload(o.file, o.delay);
  78. }
  79. }
  80. });
  81. };
  82. Show.prototype.render = function() {
  83. if (!this.list.length) return;
  84. let d = Date.now();
  85. let o = this.list[this.index];
  86. let vid = (o.e.tagName == 'VIDEO') ? 'video' : 'natural';
  87. if (o.e.src === this.parent.firstChild.src) o.e.className = this.parent.firstChild.className = (o.e[vid+'Width'] / o.e[vid+'Height'] < this.parent.clientWidth / this.parent.clientHeight) ? 'fillheight' : 'fillwidth';
  88. if (this.parent.firstChild !== o.e && !o.loading) {
  89. o.loading = true;
  90. let parent = this.parent;
  91. o.e.addEventListener(vid === 'video' ? 'canplay' : 'load', () => {
  92. if (vid === 'video') {
  93. parent.replaceChild(o.e, parent.firstChild);
  94. } else if (vid === 'natural' && parent.firstChild.tagName === 'VIDEO') {
  95. parent.replaceChild(document.createElement('img'), parent.firstChild);
  96. }
  97. if (parent.firstChild.tagName === 'IMG') parent.firstChild.src = o.p;
  98. if (vid === 'video') o.e.play();
  99. delete o.loading
  100. }, {once: true});
  101. let tmp = o.e.src; o.e.src = ''; o.e.src = tmp;
  102. }
  103. if (this.playing && document.hasFocus() && (this.elapsed += (d - this.updated)) && this.elapsed >= o.d) this.next();
  104. s.updated = d;
  105. window.requestAnimationFrame(() => { this.render(); });
  106. }
  107. window.Show = Show;
  108. })();