kaleido.htm

戻る

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

<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>万華鏡</TITLE>
</HEAD>

<BODY onLoad="init()" STYLE="background-color:#CCFFFF">

<DIV STYLE="text-align:center">
<BR>
<B>万華鏡</B>
<BR><BR>

<FORM>
<LABEL><INPUT TYPE=CHECKBOX ID="move" DISABLED onClick="move_scope()">使用する画像の範囲を変化させる</LABEL>
</FORM>
<BR>

<CANVAS ID="view" WIDTH=480 HEIGHT=480></CANVAS>
</DIV>

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

function init() {
  if(navigator.mozGetUserMedia == undefined) {
    if(navigator.webkitGetUserMedia == undefined)
      navigator.getUserMedia({video:true, audio:false}, success, error);
    else
      navigator.webkitGetUserMedia({video:true, audio:false}, success, error);
  }
  else {
    navigator.mozGetUserMedia({video:true, audio:false}, success, error);
  }
}

function success(stream) {
  elem_video = document.createElement("VIDEO");
  elem_video.autoplay = true;
  elem_video.addEventListener("canplay", wait, false);
  if(elem_video.mozSrcObject === undefined) {
    if(elem_video.srcObject === undefined)
      elem_video.src = (window.URL == undefined || window.URL.createObjectURL == undefined)
                         ? stream : window.URL.createObjectURL(stream);
    else
      elem_video.srcObject = stream;
  }
  else {
    elem_video.mozSrcObject = stream;
  }
  elem_video.play();
}

function error(err) {
  alert("カメラが使用できません");
}

function wait() {
  if(elem_video.videoWidth) {
    src_x = (elem_video.videoWidth  >> 1) - 42;
    src_y = (elem_video.videoHeight >> 1) - 48;
    max_src_x = elem_video.videoWidth - 84
    max_src_y = elem_video.videoHeight - 73
    elem_move.disabled = false;

    setInterval(frame, 200);
    return;
  }

  setTimeout(wait, 50);
}

function move_scope() {
  if(elem_move.checked) {
    move_cnt = 0;
  }
  else {
    move_cnt = -1;
    src_x = (elem_video.videoWidth  >> 1) - 42;
    src_y = (elem_video.videoHeight >> 1) - 48;
  }
}

function frame() {
  ctx_src.drawImage(elem_video, src_x, src_y, 84, 73, 0, 0, 84, 73);

  ctx_view.clearRect(0, 0, 480, 480);
  ctx_view.save();
  ctx_view.clip();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_src, 1, 1, 82, 71,  76, y, 82, 71);
    ctx_view.drawImage(elem_src, 1, 1, 82, 71, 322, y, 82, 71);
    y += 71;
    ctx_view.drawImage(elem_src, 1, 1, 82, 71, -47, y, 82, 71);
    ctx_view.drawImage(elem_src, 1, 1, 82, 71, 199, y, 82, 71);
    ctx_view.drawImage(elem_src, 1, 1, 82, 71, 445, y, 82, 71);
    y += 71;
  }

  ctx_work.save();
  // translate(0, 71)
  // rotate(120°)
  // translate(-82, -71)
  ctx_work.setTransform(-0.5, SIN120, - SIN120, -0.5, 102.48780366869515, 35.485916889676031);
  ctx_work.drawImage(elem_src, 0, 0, 84, 73, -1, -1, 84, 73);
  ctx_work.restore();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_work, 158, y);
    ctx_view.drawImage(elem_work, 404, y);
    y += 71;
    ctx_view.drawImage(elem_work,  35, y);
    ctx_view.drawImage(elem_work, 281, y);
    y += 71;
  }

  ctx_work.save();
  // translate(41, 0)
  // rotate(240°)
  // translate(-82, -71)
  ctx_work.setTransform(-0.5, - SIN120, SIN120, -0.5, 20.512196331304856, 106.51408311032397);
  ctx_work.drawImage(elem_src, 0, 0, 84, 73, -1, -1, 84, 73);
  ctx_work.restore();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_work,  -6, y);
    ctx_view.drawImage(elem_work, 240, y);
    y += 71;
    ctx_view.drawImage(elem_work, 117, y);
    ctx_view.drawImage(elem_work, 363, y);
    y += 71;
  }

  ctx_work.clearRect(0, 0, 82, 71);
  ctx_work.save();
  ctx_work.clip();
  // scale(1, -1)
  ctx_work.setTransform(1, 0, 0, -1, 0, 0);
  ctx_work.drawImage(elem_src, 1, 1, 82, 71, 0, -71, 82, 71);
  ctx_work.restore();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_work, -47, y);
    ctx_view.drawImage(elem_work, 199, y);
    ctx_view.drawImage(elem_work, 445, y);
    y += 71;
    ctx_view.drawImage(elem_work,  76, y);
    ctx_view.drawImage(elem_work, 322, y);
    y += 71;
  }

  ctx_work.clearRect(0, 0, 82, 71);
  ctx_work.save();
  ctx_work.clip();
  // translate(41, 71)
  // rotate(120°)
  // translate(-82, 0)
  // scale(1, -1)
  ctx_work.setTransform(-0.5, SIN120, SIN120, 0.5, 82, -0.014083110323969035);
  ctx_work.drawImage(elem_src, 0, 0, 84, 73, -1, -72, 84, 73);
  ctx_work.restore();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_work, 117, y);
    ctx_view.drawImage(elem_work, 363, y);
    y += 71;
    ctx_view.drawImage(elem_work,  -6, y);
    ctx_view.drawImage(elem_work, 240, y);
    y += 71;
  }

  ctx_work.clearRect(0, 0, 82, 71);
  ctx_work.save();
  ctx_work.clip();
  // rotate(240°)
  // translate(-82, 0)
  // scale(1, -1)
  ctx_work.setTransform(-0.5, - SIN120, - SIN120, 0.5, 41, 71.01408311032397);
  ctx_work.drawImage(elem_src, 0, 0, 84, 73, -1, -72, 84, 73);
  ctx_work.restore();

  for(var y = -20; y <= 477; ) {
    ctx_view.drawImage(elem_work,  35, y);
    ctx_view.drawImage(elem_work, 281, y);
    y += 71;
    ctx_view.drawImage(elem_work, 158, y);
    ctx_view.drawImage(elem_work, 404, y);
    y += 71;
  }

  ctx_view.restore();

  if(move_cnt >= 0) {  // 使用する画像の範囲を変化させる
    if(move_cnt) {
      move_cnt--;
    }
    else {
      move_dir = Math.floor(Math.random() * 4);
      move_cnt = 8;
    }

    switch(move_dir) {
    case 0:
      if((src_x -= 2) < 0) {
        move_dir = 1;
        src_x += 4;
      }
      break;
    case 1:
      if((src_x += 2) > max_src_x) {
        move_dir = 0;
        src_x -= 4;
      }
      break;
    case 2:
      if((src_y -= 2) < 0) {
        move_dir = 3;
        src_y += 4;
      }
      break;
    case 3:
      if((src_y += 2) > max_src_y) {
        move_dir = 2;
        src_y -= 4;
      }
      break;
    }
  }
}

  ctx_view = document.getElementById("view").getContext("2d");
  ctx_view.beginPath();
  ctx_view.arc(240, 240, 240, 0, Math.PI * 2, false);
  ctx_view.closePath();

  // 作業用 Canvas

  elem_src = document.createElement("CANVAS");
  elem_src.width = 84;
  elem_src.height = 73;
  ctx_src = elem_src.getContext("2d");

  elem_work = document.createElement("CANVAS");
  elem_work.width = 82;
  elem_work.height = 71;
  ctx_work = elem_work.getContext("2d");
  ctx_work.beginPath();
  ctx_work.moveTo(0, 0);
  ctx_work.lineTo(82, 0);
  ctx_work.lineTo(41, 71);
  ctx_work.closePath();

  elem_move = document.getElementById("move");
  move_cnt = -1;

  SIN120 = 0.8660254037844386;  // sin(120°)

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

//-->
</SCRIPT>

</BODY>

</HTML>