31

ProgramClip

Objective
  • Responder
    • View
      • Clip
        • ProgramClip

Move the pointer of the mouse over the clip. Click in the clip or press the space bar to start playing it. Click or press again the space bar to pause it, continue to play it. Use the right and left arrows to move forward or backward by one second, press the Shift key or the Ctrl key at the same time to move forward or backward by ten seconds or a hundred milliseconds. Press the 0 key to come back to the beginning. Press the plus key to play the clip faster, the minus key to play it slower, the asterisk key to play it at the normal speed.

  1. function ProgramClip() {
  2.     Clip.call(this);
  3.  
  4.     this._interval = 200;
  5.     this._timer = null;
  6. }
  7.  
  8. ProgramClip.prototype = Object.create(Clip.prototype);
  9.  
  10. Object.defineProperty(ProgramClip.prototype, 'constructor', { value: ProgramClip, enumerable: false, writable: true });
  11.  
  12. Object.defineProperty(ProgramClip.prototype, 'playbackRate', {
  13.     get:    function() {
  14.         return this._playbackRate;
  15.     },
  16.     set:    function(r) {
  17.         if (typeof r !== 'number')
  18.             throw new TypeError();
  19.  
  20.         if (r < Clip.minPlaybackRate || r > Clip.maxPlaybackRate)
  21.             throw new RangeError();
  22.  
  23.         this._playbackRate = r;
  24.  
  25.         if (this._timer)
  26.             this._startTimer();
  27.     }
  28. });
  29.  
  30. ProgramClip.prototype.drawWidget = function() {
  31.     return this;
  32. };
  33.  
  34. ProgramClip.prototype.setInterval = function(ms) {
  35.     if (!Number.isInteger(ms))
  36.         throw new TypeError();
  37.  
  38.     if (ms <= 0)
  39.         throw new RangeError();
  40.  
  41.     if (this._interval == ms)
  42.         return this;
  43.  
  44.     this._interval = ms;
  45.  
  46.     if (this._timer)
  47.         this._startTimer();
  48.  
  49.     return this;
  50. };
  51.  
  52. ProgramClip.prototype.seek = function(ms) {
  53.     if (!Number.isInteger(ms))
  54.         throw new TypeError();
  55.  
  56.     if (ms < 0)
  57.         throw new RangeError();
  58.  
  59.     let duration = this.duration;
  60.  
  61.     if (duration && ms > duration)
  62.         ms = duration;
  63.  
  64.     this._currentTime = ms;
  65.  
  66.     this._ended = false;
  67.  
  68.     this.drawWidget();
  69.  
  70.     this.notify('clipSeeked', this);
  71.  
  72.     return this;
  73. };
  74.  
  75. ProgramClip.prototype.play = function() {
  76.     if (this._timer)
  77.         return this;
  78.  
  79.     if (this._ended || this._currentTime == 0)
  80.         this.seek(0);
  81.  
  82.     this._ended = this._paused = false;
  83.  
  84.     this._startTimer();
  85.  
  86.     return this;
  87. };
  88.  
  89. ProgramClip.prototype.pause = function() {
  90.     if (!this._timer)
  91.         return this;
  92.  
  93.     this._paused = true;
  94.  
  95.     this._stopTimer();
  96.  
  97.     return this;
  98. };
  99.  
  100. ProgramClip.prototype._startTimer = function() {
  101.     if (this._timer)
  102.         window.clearInterval(this._timer);
  103.  
  104.     const duration = this.duration;
  105.  
  106.     this._timer = window.setInterval(() => {
  107.         this._currentTime += this._interval;
  108.  
  109.         if (duration && this._currentTime > duration)
  110.             this._currentTime = duration;
  111.  
  112.         this.drawWidget();
  113.  
  114.         if (duration && this._currentTime == duration) {
  115.             window.clearInterval(this._timer);
  116.  
  117.             this._timer = null;
  118.  
  119.             this._ended = this._paused = true;
  120.  
  121.             this.notify('clipEnded', this);
  122.         }
  123.     }, Math.floor(this._interval / this._playbackRate));
  124.  
  125.     return this;
  126. };
  127.  
  128. ProgramClip.prototype._stopTimer = function() {
  129.     if (this._timer) {
  130.         window.clearInterval(this._timer);
  131.  
  132.         this._timer = null;
  133.     }
  134.  
  135.     return this;
  136. };
Test
  1. <?php $id=uniqid('id'); ?>
  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="solarsystem"></div>
  3. </div>
  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  3. <?php head('javascript', '/objectivejs/View.js'); ?>
  4. <?php head('javascript', '/objectivejs/Clip.js'); ?>
  5. <?php head('javascript', '/objectivejs/ProgramClip.js'); ?>
  6. <?php head('javascript', '/objectivejs/tests/SolarSystemClip.js'); ?>
  1. const container = document.querySelector('#<?php echo $id; ?>');
  2.  
  3. const display = container.querySelector('.solarsystem');
  4.  
  5. const clip = new SolarSystemClip();
  6.  
  7. clip.setWidget(display);
  8.  
  9. clip.enablePlayer();
  1. window.onload = () => clip.drawWidget();
  1. function SolarSystemClip() {
  2.     ProgramClip.call(this);
  3.  
  4.     this._width = this._height = 300;
  5.  
  6.     this._duration = 60*1000;
  7.     this._interval = 40;
  8.  
  9.     this._sun = document.createElement('img');
  10.     this._moon = document.createElement('img');
  11.     this._earth = document.createElement('img');
  12.  
  13.     this._sun.src = '/objectivejs/tests/solarsystem_sun.png';
  14.     this._moon.src = '/objectivejs/tests/solarsystem_moon.png';
  15.     this._earth.src = '/objectivejs/tests/solarsystem_earth.png';
  16.  
  17.     this._ctx = null;
  18. }
  19.  
  20. SolarSystemClip.prototype = Object.create(ProgramClip.prototype);
  21.  
  22. Object.defineProperty(SolarSystemClip.prototype, 'constructor', { value: SolarSystemClip, enumerable: false, writable: true });
  23.  
  24. SolarSystemClip.prototype.setWidget = function(w) {
  25.     const canvas = document.createElement('canvas');
  26.  
  27.     canvas.width = this._width;
  28.     canvas.height = this._height;
  29.  
  30.     const ctx = canvas.getContext('2d');
  31.  
  32.     ctx.fillStyle = 'black';
  33.     ctx.fillRect(0, 0, this._width, this._height);
  34.  
  35.     this._ctx = ctx;
  36.  
  37.     w.appendChild(canvas);
  38.  
  39.     Clip.prototype.setWidget.call(this, canvas);
  40.  
  41.     return this;
  42. };
  43.  
  44. SolarSystemClip.prototype.drawWidget = function() {
  45.     const ms = this._currentTime;
  46.     const ctx = this._ctx;
  47.  
  48.     ctx.globalCompositeOperation = 'destination-over';
  49.     ctx.clearRect(0, 0, 300, 300);
  50.  
  51.     ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
  52.     ctx.strokeStyle = 'rgba(0, 153, 255, 0.4)';
  53.     ctx.save();
  54.     ctx.translate(150, 150);
  55.  
  56.     // earth
  57.     ctx.rotate(((2 * Math.PI) / 60000) * ms);
  58.     ctx.translate(105, 0);
  59.     ctx.fillRect(0, -12, 40, 24);   // shadow
  60.     ctx.drawImage(this._earth, -12, -12);
  61.  
  62.     // moon
  63.     ctx.save();
  64.     ctx.rotate(((2 * Math.PI) / 6000) * ms);
  65.     ctx.translate(0, 28.5);
  66.     ctx.drawImage(this._moon, -3.5, -3.5);
  67.     ctx.restore();
  68.  
  69.     ctx.restore();
  70.  
  71.     ctx.beginPath();
  72.     ctx.arc(150, 150, 105, 0, Math.PI * 2, false);  // earth orbit
  73.     ctx.stroke();
  74.  
  75.     ctx.drawImage(this._sun, 0, 0, 300, 300);
  76.  
  77.     return this;
  78. };
SEE ALSO

Clip, AnimateClip, VideoClip, Draggable, Editing a programmed clip

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].