@mbostock
Building a better computational medium. Founder @observablehq. Creator @d3. Former @nytgraphics. Pronounced BOSS-tock.
Published (unlisted)
Insert cell
Insert cell
Removed in parent
Insert cell
Changed in fork
-
html`${await files[lindex - 1].image()}`
+
html`${await file.image()}`
Insert cell
Insert cell
Removed in parent
Insert cell
Removed in fork
mutable lindex = 1
Insert cell
Removed in fork
mutable animationSpeed = 1000
Insert cell
Removed in fork
llast = files.length
Insert cell
Removed in fork
mutable animationForward = false
Insert cell
Removed in fork
mutable animationPlay = true
Insert cell
Removed in fork
mutable animationType = "loop"
Insert cell
Removed in fork
viewof a = animationControls()
Insert cell
Removed in fork
play()
Insert cell
Removed in fork
function* play() {
  while (animationPlay) {
    var increment = 1;
    if (lindex >= llast) {
      if (animationType == 'once') {
        mutable animationPlay = false;
        break;
      } else if (animationType == 'loop') {
        mutable lindex = 1;
        break;
      } else if (animationType == 'reflect') {
        increment = -1;
      }
    }
    yield Promises.delay(animationSpeed, (mutable lindex += increment));
  }
}
Insert cell
Removed in fork
async function animationControls() {
  const firstButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "first.png"
  ).url()}"></button>`;
  const prevButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "prev.png"
  ).url()}"></button>`;
  const reverseButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "reverse.png"
  ).url()}"></button>`;
  const pauseButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "pause.png"
  ).url()}"></button>`;
  const playButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "play.png"
  ).url()}" onclick="play()"></button>`;
  const nextButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "next.png"
  ).url()}"></button>`;
  const lastButton = html`<button type="button" class="btn btn-default"><img src="${await FileAttachment(
    "last.png"
  ).url()}"></button>`;
  const slowerButton = html`<button type="button" class="btn btn-default">Slower</button>`;
  const fasterButton = html`<button type="button" class="btn btn-default">Faster</button>`;

  const onceRadio = html`<label class="radio-inline"><input type="radio" name="state" value="once" checked>Once</label>`;
  const loopRadio = html`<label class="radio-inline"><input type="radio" name="state" value="loop" >Loop</label>`;
  const reflectRadio = html`<label class="radio-inline"><input type="radio" name="state" value="reflect">Reflect</label>`;

  firstButton.onclick = function(event) {
    mutable animationPlay = false;
    mutable animationForward = false;
    mutable lindex = 1;
  };
  prevButton.onclick = function(event) {
    mutable animationPlay = false;
    mutable animationForward = false;
    if (lindex > 1) {
      mutable lindex--;
    }
  };
  reverseButton.onclick = function(event) {
    mutable animationPlay = false;
    mutable animationForward = true;
  };
  pauseButton.onclick = function(event) {
    mutable animationPlay = false;
    mutable animationForward = false;
  };
  playButton.onclick = function(event) {
    mutable animationPlay = true;
    mutable animationForward = false;
  };
  nextButton.onclick = function(event) {
    mutable animationPlay = false;
    mutable animationForward = false;
    if (lindex < llast) {
      mutable lindex++;
    }
  };
  lastButton.onclick = function(event) {
    mutable lindex = llast;
    mutable animationPlay = false;
    mutable animationForward = false;
  };

  slowerButton.onclick = function(event) {
    mutable animationSpeed += 100;
  };

  fasterButton.onclick = function(event) {
    if (animationSpeed > 0) mutable animationSpeed -= 100;
  };

  onceRadio.onclick = function(event) {
    mutable animationType = "once";
  };
  loopRadio.onclick = function(event) {
    mutable animationType = "loop";
  };
  reflectRadio.onclick = function(event) {
    mutable animationType = "reflect";
  };

  return html`
       <div class="controls">  
                <div class="playControls">
                    <div class="btn-group btn-group-xm">
                        ${firstButton}
                        ${prevButton}
                        ${reverseButton}
                        ${pauseButton}
                        ${playButton}
                        ${nextButton}
                        ${lastButton}
                    </div>
                    <div>
                        <div class="btn-group btn-group-xm">
                            ${slowerButton}
                            ${fasterButton}
                        </div>
                    </div>
                    <div>
                        ${onceRadio}
                        ${loopRadio}
                        ${reflectRadio}
                    </div>
                </div>           
        </div>
`;
}
Insert cell
Removed in fork
style = html`<style>
       .controls {
            width: 500px;
        }
        .fa {
            cursor: pointer;
            opacity: 0.7 !important;
        }
        .playControls {
            margin: 10px;
            text-align: center;
        }
        .playControls>div {
            padding: 4px;
        }
<\style>`
Insert cell
Removed in fork
html`<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">`
Insert cell
Removed in fork
html`<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">`
Insert cell