今回はスライドを作ってみます。 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.