LoginSignup
0
0

More than 3 years have passed since last update.

MathBox でスライドを作る

Last updated at Posted at 2019-06-26

 今回はスライドを作ってみます。 MathBox は一般的なプレゼンテーションソフトのように「スライドの中にグラフィックスを埋め込む」のではなく、「グラフィックスの中にスライドを埋め込む」という発想のようですので、それを意識すると理解しやすいかもしれません。

基本のコード

 前回のコードにプレゼンテーションスライドを作成するコードとスライドのページ送りするためのコードを追加しました。

 プレゼンテーションスライドを作成するコードは以下の部分です。また、これ以降で view と書かれていた部分は present に置換します。

present = view.present({
  index: 1
})

 全体は以下のようになります。

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8">
    <title>MathBox - XYZW Test</title>
    <script src="../../build/mathbox-bundle.js"></script>
    <link rel="stylesheet" href="../../build/mathbox.css">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1">
    </head>
    <body>
    <div style="position: absolute;
            left: 50%;
            bottom: 21px;">
        <span onclick="prevSlide()" style="display: inline-block;
               height: 34px;
               width: 55px;
               background-color: ghostwhite;
               text-align: center;
               vertical-align: middle;
               border: solid 2px black;
               border-radius: 8px;">Prev</span>
        <span onclick="nextSlide()" style="display: inline-block;
               height: 34px;
               width: 55px;
               background-color: ghostwhite;
               text-align: center;
               vertical-align: middle;
               border: solid 2px black;
               border-radius: 8px;">Next</span>
    </div>
    <script>
     mathbox = mathBox({
         plugins: ['core', 'controls', 'cursor'],
         controls: {
         klass: THREE.OrbitControls
         },
     });
     three = mathbox.three;

     three.camera.position.set(2.3, 1, 2);
     three.renderer.setClearColor(new THREE.Color(0xFFFFFF), 1.0);

     view = mathbox.cartesian({
         range: [[-6, 6], [-1, 1], [-1, 1]],
         scale: [6, 1, 1],
     });

     present = view.present({
         index: 1
     })

     function prevSlide () {
         present.set('index', present.get('index') - 1);
     }

     function nextSlide () {
         present.set('index', present.get('index') + 1);
     }

     present.interval({
         width: 2,
         expr: function (emit, x, i, time) {
         emit(x, 0);
         },
         items: 1,
         channels: 2,
     }).line({
         color: 0x3090FF,
         width: 10,
     });

     present.interval({
         width: 128,
         expr: function (emit, x, i, time) {
         var d = Math.sin((x + time) * 2);
         emit(x, d * .5);
         },
         items: 1,
         channels: 2,
     }).line({
         color: 0xFF3090,
         width: 10,
     });

     present.grid({
         stroke: 'dashed',
     });
    </script>
    </body>
</html>

スライドを埋め込む

 直線と Sin カーブそれぞれにスライドを埋め込んでみます。それぞれ present.slide() として続けるとスライドを埋め込む事ができます。以下のように変更すると、ページ間を行き来できるようになります。

present.slide().interval({
  width: 2,
  expr: function (emit, x, i, time) {
    emit(x, 0);
  },
  items: 1,
  channels: 2,
}).line({
  color: 0x3090FF,
  width: 10,
});

present.slide().interval({
  width: 128,
  expr: function (emit, x, i, time) {
    var d = Math.sin((x + time) * 2);
    emit(x, d * .5);
  },
  items: 1,
  channels: 2,
}).line({
  color: 0xFF3090,
  width: 10,
});

メソッドチェーンでまとめる

 このコードをメソッドチェーンを使うと、直線と Sin のコードブロックを繋げて次のように書けます。直線のブロックの最後に .end() を置いて .slide() と続けます。 end() はメソッドチェーンをして生じた要素の親子関係を切るために使います。ドキュメントから引用すると group().child().child().end().sibling(); となります。
 ちなみに二枚目のスライドに対応する end() が入っていませんが、無くても不都合がないため省略しています。

present.slide().interval({
  width: 2,
  expr: function (emit, x, i, time) {
    emit(x, 0);
  },
  items: 1,
  channels: 2,
}).line({
  color: 0x3090FF,
  width: 10,
}).end()
  .slide().interval({
    width: 128,
    expr: function (emit, x, i, time) {
      var d = Math.sin((x + time) * 2);
      emit(x, d * .5);
    },
    items: 1,
    channels: 2,
  }).line({
    color: 0xFF3090,
    width: 10,
  });

重ねて描画したい場合

 上記のコードだと、直線が描画されなくなって、Sin カーブの描画がされます。一方で .end() を削除してみると、直線の描画を続けたまま Sin カーブも描画されるようになります。Sin カーブが直線の子要素になったという事が分かります。
 このように次々と重ねて描画したい場合は、 .end() を入れずに親子関係を維持したまま続ければ実現できます。

コード全体

 ここまでのコード全体は下記の通りです。

<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8">
    <title>MathBox - XYZW Test</title>
    <script src="../../build/mathbox-bundle.js"></script>
    <link rel="stylesheet" href="../../build/mathbox.css">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1">
    </head>
    <body>
    <div style="position: absolute;
            left: 50%;
            bottom: 21px;">
        <span onclick="prevSlide()" style="display: inline-block;
               height: 34px;
               width: 55px;
               background-color: ghostwhite;
               text-align: center;
               vertical-align: middle;
               border: solid 2px black;
               border-radius: 8px;">Prev</span>
        <span onclick="nextSlide()" style="display: inline-block;
               height: 34px;
               width: 55px;
               background-color: ghostwhite;
               text-align: center;
               vertical-align: middle;
               border: solid 2px black;
               border-radius: 8px;">Next</span>
    </div>
    <script>
     mathbox = mathBox({
         plugins: ['core', 'controls', 'cursor'],
         controls: {
         klass: THREE.OrbitControls
         },
     });
     three = mathbox.three;

     three.camera.position.set(2.3, 1, 2);
     three.renderer.setClearColor(new THREE.Color(0xFFFFFF), 1.0);

     view = mathbox.cartesian({
         range: [[-6, 6], [-1, 1], [-1, 1]],
         scale: [6, 1, 1],
     });

     present = view.present({
         index: 1
     })

     function prevSlide () {
         present.set('index', present.get('index') - 1);
     }

     function nextSlide () {
         present.set('index', present.get('index') + 1);
     }

     present.slide().interval({
         width: 2,
         expr: function (emit, x, i, time) {
         emit(x, 0);
         },
         items: 1,
         channels: 2,
     }).line({
         color: 0x3090FF,
         width: 10,
     }).end()
        .slide().interval({
            width: 128,
            expr: function (emit, x, i, time) {
            var d = Math.sin((x + time) * 2);
            emit(x, d * .5);
            },
            items: 1,
            channels: 2,
        }).line({
            color: 0xFF3090,
            width: 10,
        });

     present.grid({
         stroke: 'dashed',
     });
    </script>
    </body>
</html>

See the Pen slide by Yuichi Sato (@satoyuichi) on CodePen.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0