cinemato.htm

戻る

<!DOCTYPE HTML>
<HTML LANG="ja">

<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>活動写真</TITLE>
<svg height=0 color-interpolation-filters="sRGB" style="height:0">
<filter id="svg-blur">
<feGaussianBlur in="SourceGraphic" stdDeviation=1.5></feGaussianBlur>
</filter>
</svg>
</HEAD>

<BODY STYLE="background-color:#CCFFFF">
<BR>
<DIV STYLE="text-align:center">
<B><SPAN STYLE="color:#CC0000">活動写真</SPAN></B>
<BR><BR>

<FORM>
<TABLE STYLE="margin-left:auto; margin-right:auto"><TR><TD STYLE="text-align:left; white-space:nowrap">
<B>ファイル:</B><BR>
<INPUT TYPE=FILE ID="file" onChange="sel_file()" STYLE="min-width:30em"><BR><BR>
<INPUT TYPE=BUTTON ID="play" VALUE="映写" DISABLED onClick="play_stop()">
<LABEL><INPUT TYPE=RADIO NAME="aud" onClick="aud_off()" CHECKED STYLE="margin-left:2em"> サイレント</LABEL>
<LABEL><INPUT TYPE=RADIO NAME="aud" onClick="aud_on()" STYLE="margin-left:1em"> トーキー</LABEL>
</TD></TR></TABLE>
</FORM>
<BR>

<DIV ID="scr" STYLE="padding:10px; display:inline-block; background-color:#E0E0E0">
<DIV ID="frm" STYLE="position:relative; width:638px; height:478px; display:inline-block; overflow:hidden">
<CANVAS ID="frm1" WIDTH=1 HEIGHT=1
  STYLE="position:absolute; filter:grayscale(100%) url(#svg-blur); -webkit-filter:grayscale(100%) url(#svg-blur)">
</CANVAS>
<CANVAS ID="frm2" WIDTH=688 HEIGHT=528 STYLE="position:absolute; visibility:hidden"></CANVAS>
<CANVAS ID="frm3" WIDTH=1 HEIGHT=1 STYLE="position:absolute; left:0; top:0"></CANVAS>
</DIV>
</DIV>
</DIV>

<SCRIPT TYPE="text/javascript">
<!--

function sel_file() {
  if(url_cre)
    URL.revokeObjectURL(elem_video.src);
  elem_video.src = URL.createObjectURL(elem_file.files.item(0));
  url_cre = true;
}

function canplay() {
  if(!elem_video.videoWidth) {
    elem_play.disabled = true;
    alert("映写できません。");
    return;
  }

  video_width  = elem_video.videoWidth;
  video_height = elem_video.videoHeight;
  if(video_width > 640 || video_height > 480) {
    if(video_width * 480 > video_height * 640) {
      video_height = video_height * 640 / video_width;
      video_width = 640;
    }
    else {
      video_width = video_width * 480 / video_height;
      video_height = 480;
    }
  }

  frame_width_h  = (frame_width  = video_width  - 2) / 2;
  frame_height_h = (frame_height = video_height - 2) / 2;
  frame_r2 = frame_width_h * frame_width_h + frame_height_h * frame_height_h;
  with(elem_frm.style) {
    width  = String(frame_width)  + "px";
    height = String(frame_height) + "px";
  }
  with(elem_frm1) {
    width  = video_width;
    height = video_height;
    style.width  = String(video_width)  + "px";
    style.height = String(video_height) + "px";
  }
  with(elem_frm3) {
    width  = frame_width;
    height = frame_height;
    style.width  = String(frame_width)  + "px";
    style.height = String(frame_height) + "px";
  }
  ctx_frm3.lineCap = "round";

  elem_play.disabled = false;
}

function ended() {
  stop();
}

function error() {
  elem_play.disabled = true;
  alert("映写できません。");
}

function play_stop() {
  if(int_id) {  // 再生中
    // 停止
    elem_video.pause()
    stop();
    return;
  }

  elem_file.disabled = true;
  elem_play.value = "停止";
  elem_scr.style.backgroundColor = "gray";
  elem_frm2.style.visibility = "visible";
  if(aud_ctx.resume !== undefined)  // Opera 60 以上でも動くようにするため
    aud_ctx.resume();
  elem_video.play();
  int_id = setInterval(frame, 42);
}

function aud_off() {
  audio.disconnect();
  audio.connect(dummy);  // Opera で必要
}

function aud_on() {
  audio.disconnect();  // Opera で必要
  audio.connect(lpf5);
}

function stop() {
  clearInterval(int_id);
  int_id = 0;
  elem_video.currentTime = 0;
  elem_file.disabled = false;
  elem_play.value = "映写";
  elem_scr.style.backgroundColor = "#E0E0E0";
  ctx_frm1.clearRect(0, 0, video_width, video_height);
  elem_frm2.style.visibility = "hidden";
  ctx_frm3.clearRect(0, 0, frame_width, frame_height);
}

function frame() {
  ctx_frm1.drawImage(elem_video, 0, 0, video_width, video_height);

  with(elem_frm2.style) {
    left = String(Math.random() * -50) + "px";
    top  = String(Math.random() * -50) + "px";
  }

  ctx_frm3.clearRect(0, 0, frame_width, frame_height);

  var n;
  var x, y;
  var grad;
  var w;

  // 画面を少し白っぽくする
  n = Math.floor(Math.random() * 40);
  if(n < 4) {
    switch(n) {
    case 0:
      y = Math.random() * frame_height;
      w = y - frame_height_h;
      grad = ctx_frm3.createLinearGradient(0, 0, frame_width_h + Math.sqrt(frame_r2 - w * w), y);
      break;
    case 1:
      x = Math.random() * frame_width;
      w = x - frame_width_h;
      grad = ctx_frm3.createLinearGradient(0, 0, x, frame_height_h + Math.sqrt(frame_r2 - w * w));
      break;
    case 2:
      y = Math.random() * frame_height;
      w = y - frame_height_h;
      grad = ctx_frm3.createLinearGradient(0, frame_height, frame_width_h + Math.sqrt(frame_r2 - w * w), y);
      break;
    default:
      x = Math.random() * frame_width;
      w = x - frame_width_h;
      grad = ctx_frm3.createLinearGradient(0, frame_height, x, frame_height_h - Math.sqrt(frame_r2 - w * w));
    }
    grad.addColorStop(0, "rgba(255,255,255," + String(Math.random() * 0.1) + ")");
    grad.addColorStop(1, "rgba(255,255,255," + String(Math.random() * 0.1) + ")");
    ctx_frm3.fillStyle = grad;
    ctx_frm3.fillRect(0, 0, frame_width, frame_height);
  }
  else if(n < 8) {
    switch(n) {
    case 4:
      grad = ctx_frm3.createLinearGradient(Math.random() * frame_width, 0, frame_width, 0);
      break;
    case 5:
      grad = ctx_frm3.createLinearGradient(0, Math.random() * frame_height, 0, frame_height);
      break;
    case 6:
      grad = ctx_frm3.createLinearGradient(Math.random() * frame_width, 0, 0, 0);
      break;
    default:
      grad = ctx_frm3.createLinearGradient(0, Math.random() * frame_height, 0, 0);
    }
    grad.addColorStop(0, "rgba(255,255,255,0)");
    grad.addColorStop(1, "rgba(255,255,255," + String(Math.random() * 0.1) + ")");
    ctx_frm3.fillStyle = grad;
    ctx_frm3.fillRect(0, 0, frame_width, frame_height);
  }

  // 斑点
  n = Math.floor(Math.random() * 10);
  if(n < 4) {
    while(n-- >= 0) {
      var x2, y2;
      x2 = x = Math.random() * frame_width;
      y2 = y = Math.random() * frame_height;
      ctx_frm3.lineWidth = w = 2 + Math.random() * 4;
      w /= 3;
      switch(Math.floor(Math.random() * 3)) {
      case 1:
        x2 += w;
        break;
      case 2:
        x2 -= w;
        break;
      }
      switch(Math.floor(Math.random() * 3)) {
      case 1:
        y2 += w;
        break;
      case 2:
        y2 -= w;
        break;
      }
      ctx_frm3.beginPath();
      ctx_frm3.moveTo(x, y);
      ctx_frm3.lineTo(x2, y2);
      ctx_frm3.globalCompositeOperation = "destination-out";
      ctx_frm3.fillStyle = "rgba(0,0,0,1)";
      ctx_frm3.stroke();
      ctx_frm3.globalCompositeOperation = "source-over";
      ctx_frm3.strokeStyle = "rgba(128,128,128,0.3)";
      ctx_frm3.stroke();
    }
  }

  // 直線
  n = Math.floor(Math.random() * 40);
  if(n < 2) {
    ctx_frm3.lineWidth = 1;
    while(n-- >= 0) {
      x = Math.random() * frame_width;
      y = Math.random() * frame_height;
      ctx_frm3.strokeStyle = (Math.random() < 0.5) ? "#404040" : "#c0c0c0";
      ctx_frm3.beginPath();
      ctx_frm3.moveTo(x, y);
      w = 10 + Math.random() * 30;
      ctx_frm3.lineTo(x + 10 + Math.random() * 30, (Math.random() < 0.5) ? y - w : y + w);
      ctx_frm3.stroke();
    }
  }

  // 曲線
  n = Math.floor(Math.random() * 40);
  if(n < 2) {
    ctx_frm3.lineWidth = 1;
    while(n-- >= 0) {
      x = Math.random() * frame_width;
      y = Math.random() * frame_height;
      ctx_frm3.strokeStyle = (Math.random() < 0.5) ? "#404040" : "#c0c0c0";
      ctx_frm3.beginPath();
      ctx_frm3.moveTo(x, y);
      var w2, w3, w4;
      w  = 10 + Math.random() * 30;
      w2 = 10 + Math.random() * 30;
      w3 = 10 + Math.random() * 30;
      w4 = 10 + Math.random() * 30;
      ctx_frm3.quadraticCurveTo((Math.random() < 0.5) ? x - w  : x + w,
                                (Math.random() < 0.5) ? y - w2 : y + w2,
                                (Math.random() < 0.5) ? x - w3 : x + w3,
                                (Math.random() < 0.5) ? y - w4 : y + w4);
      ctx_frm3.stroke();
    }
  }

  // 画像を少し揺らす
  with(elem_frm1.style) {
    left = String(Math.random() * 2 - 2) + "px";
    top  = String(Math.random() * 2 - 2) + "px";
  }
}

  elem_video = document.createElement("VIDEO");
  elem_video.addEventListener("canplay", canplay, false);
  elem_video.addEventListener("ended", ended, false);
  elem_video.addEventListener("error", error, false);

  elem_scr = document.getElementById("scr");

  elem_frm = document.getElementById("frm");

  elem_frm1 = document.getElementById("frm1");
  ctx_frm1 = elem_frm1.getContext("2d");

  elem_frm2 = document.getElementById("frm2");
  ctx_frm2 = elem_frm2.getContext("2d");

  // ランダムなノイズを生成
  ctx_frm2.fillStyle = "black";
  ctx_frm2.fillRect(0, 0, 688, 528);
  ctx_frm2.fillStyle = "white";
  for(x = 0; x < 688; x++) {
    for(y = 0; y < 528; y++) {
      if(Math.random() < 0.5)
        ctx_frm2.fillRect(x, y, 1, 1);
    }
  }
  ctx_frm2.globalCompositeOperation = "copy";
  ctx_frm2.globalAlpha = 0.02;
  ctx_frm2.drawImage(elem_frm2, 0, 0);
  ctx_frm2.globalCompositeOperation = "source-over";
  ctx_frm2.globalAlpha = 1;

  elem_frm3 = document.getElementById("frm3");
  ctx_frm3 = elem_frm3.getContext("2d");

//with((window.webkitAudioContext == undefined) ? new AudioContext() : new webkitAudioContext()) {
  with(aud_ctx = (window.webkitAudioContext == undefined) ? new AudioContext() : new webkitAudioContext()) {
    lpf1 = createBiquadFilter();
    lpf2 = createBiquadFilter();
    lpf3 = createBiquadFilter();
    lpf4 = createBiquadFilter();
    lpf5 = createBiquadFilter();

    lpf1.type = lpf2.type = lpf3.type = lpf4.type = lpf5.type = "lowpass";
    lpf1.frequency.value = lpf2.frequency.value = lpf3.frequency.value = lpf4.frequency.value = lpf5.frequency.value = 2500;
    lpf1.Q.value = lpf2.Q.value = lpf3.Q.value = lpf4.Q.value = lpf5.Q.value = 1;

    lpf1.connect(destination);
    lpf2.connect(lpf1);
    lpf3.connect(lpf2);
    lpf4.connect(lpf3);
    lpf5.connect(lpf4);

    lpf5.channelCountMode = "explicit";
    lpf5.channelCount = 1;
    audio = createMediaElementSource(elem_video);
    dummy = createAnalyser();  // Opera で必要
    audio.connect(dummy);
  }

  url_cre = false;
  int_id = 0;

  elem_file = document.getElementById("file");
  elem_play = document.getElementById("play");

  // ページを再ロードしたときのため
  document.forms[0].reset();
  elem_file.disabled = false;
  elem_play.disabled = true;

//-->
</SCRIPT>

</BODY>

</HTML>