258 lines
8.9 KiB
HTML
258 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title>View options demo</title>
|
||
<meta charset="UTF-8" />
|
||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraph.css" />
|
||
<script type="text/javascript" charset="UTF-8" src="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraphcore.js"></script>
|
||
</head>
|
||
<body>
|
||
|
||
<a href="../">↩ Back to index</a>
|
||
|
||
<h1>View options demo</h1>
|
||
|
||
<!-- central projection; depth ordering for points -->
|
||
|
||
<h2>Central projection; depth ordering for points</h2>
|
||
<p>
|
||
This demo shows how the new <code>projection</code> and <code>depthOrderPoints</code> options of a <code>View3D</code> affect the view. Use the controls to:
|
||
<ul>
|
||
<li>Switch between parallel and central projection (<code>projection</code> set to <code>'parallel'</code> and <code>'central'</code>, respectively).</li>
|
||
<li>Switch depth ordering of points on and off (<code>depthOrderPoints</code> set to <code>true</code> or <code>false</code>).
|
||
</ul>
|
||
To see what depth ordering does, rotate the view to make two points overlap, and then rotate again to switch which point is in front.
|
||
</p>
|
||
<div>
|
||
<label for="proj">Projection:</label>
|
||
<select id="proj">
|
||
<option value="parallel">Parallel</option>
|
||
<option value="central">Central</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<input id="depth-ordering-ctl" type="checkbox" />
|
||
<label for="depth-ordering-ctl">Depth-order points</label>
|
||
</div>
|
||
<div id="proj-depth-board" class="jxgbox" style="width:600px; height:600px"></div>
|
||
|
||
<script type="text/javascript">
|
||
// to prevent variable name conflicts, we define variables locally using `let`
|
||
// and put the code for each board in its own block
|
||
{
|
||
// create a JSXGraph board and draw a 3D view on it
|
||
let board = JXG.JSXGraph.initBoard(
|
||
'proj-depth-board',
|
||
{
|
||
boundingbox: [-8, 8, 8,-8],
|
||
axis: false,
|
||
showCopyright: false,
|
||
showNavigation: false
|
||
}
|
||
);
|
||
let view = board.create(
|
||
'view3d',
|
||
[[-4.5, -4.5], [9, 9],
|
||
[[0, 3], [0, 3], [0, 3]]],
|
||
{
|
||
xPlaneRear: {fillOpacity: 0.2, gradient: null},
|
||
yPlaneRear: {fillOpacity: 0.2, gradient: null},
|
||
zPlaneRear: {fillOpacity: 0.2, gradient: null}
|
||
}
|
||
);
|
||
|
||
// create a list of individually styled Point3D elements to use as the
|
||
// vertices of a polygon
|
||
let vertices1 = [];
|
||
coords1 = [
|
||
[2, 1, 1],
|
||
[2, 2, 1],
|
||
[1, 2, 1],
|
||
[1, 2, 2],
|
||
[1, 1, 2],
|
||
[1, 1, 1]
|
||
];
|
||
colors1 = [
|
||
'orangered',
|
||
'gold',
|
||
'mediumseagreen',
|
||
'darkturquoise',
|
||
'purple',
|
||
'deeppink'
|
||
];
|
||
for (i in coords1) {
|
||
vertices1.push(view.create(
|
||
'point3d',
|
||
coords1[i],
|
||
{
|
||
withLabel: false,
|
||
size: 5,
|
||
strokeColor: 'none',
|
||
fillColor: 'white',
|
||
gradientSecondColor: colors1[i],
|
||
highlightStrokeWidth: 1,
|
||
highlightStrokeColor: '#777'
|
||
}
|
||
));
|
||
}
|
||
|
||
// create a polygon from a list of vertices (given as Point3D elements)
|
||
let polygon1 = view.create(
|
||
'polygon3d',
|
||
vertices1,
|
||
{
|
||
borders: {
|
||
strokeColor: '#777',
|
||
highlightStrokeColor: '#999'
|
||
}
|
||
}
|
||
);
|
||
|
||
// create a polygon from a list of vertices (given in coordinates)
|
||
let coords2 = [
|
||
[0.5, 1.5, 1.5],
|
||
[1.5, 1.5, 1.5],
|
||
[1.5, 2.5, 1.5],
|
||
[0.5, 2.5, 1.5]
|
||
];
|
||
let polygon2 = view.create(
|
||
'polygon3d',
|
||
coords2,
|
||
{
|
||
vertices: {
|
||
withLabel: false,
|
||
strokeColor: 'none',
|
||
fillColor: 'white',
|
||
gradientSecondColor: '#444',
|
||
highlightStrokeWidth: 1,
|
||
highlightStrokeColor: 'black'
|
||
},
|
||
borders: {
|
||
strokeColor: 'black',
|
||
highlightStrokeColor: 'gray'
|
||
}
|
||
}
|
||
);
|
||
|
||
// switch between parallel and central projection
|
||
proj = document.querySelector('#proj');
|
||
function inputProjectionType() {
|
||
view.setAttribute({'projection': proj.value});
|
||
}
|
||
proj.addEventListener('input', inputProjectionType);
|
||
inputProjectionType();
|
||
|
||
// switch depth ordering of points on and off
|
||
let depthOrderingCtl = document.querySelector('#depth-ordering-ctl');
|
||
function inputDepthOrderingCtl() {
|
||
view.setAttribute({'depthOrderPoints': depthOrderingCtl.checked});
|
||
}
|
||
depthOrderingCtl.addEventListener('input', inputDepthOrderingCtl);
|
||
inputDepthOrderingCtl();
|
||
}
|
||
</script>
|
||
|
||
<!-- virtual trackball; bank angle slider -->
|
||
|
||
<h2>Virtual trackball; bank angle slider</h2>
|
||
<p>
|
||
In the default orientation control mode, dragging the mouse changes the Tait-Bryan angles of the camera.
|
||
<ul>
|
||
<li>Dragging horizontally changes the azimuth.</li>
|
||
<li>Dragging vertically changes the elevation.</li>
|
||
<li>As of <a href="https://jsxgraph.org/wp/2024-06-28-release-of-version-1.9.2/">version 1.9.2</a>, doing a scroll gesture with the mouse button down changes the bank angle.</li>
|
||
</ul>
|
||
The Tait-Bryan angles can also be controlled with sliders, which are hidden by default. To show them, set the following attributes:
|
||
<ul>
|
||
<li><code>az: {slider: {visible: true}}</code></li>
|
||
<li><code>el: {slider: {visible: true}}</code></li>
|
||
<li><code>bank: {slider: {visible: true}}</code> (as of <a href="https://jsxgraph.org/wp/2024-06-28-release-of-version-1.9.2/">version 1.9.2</a>)</li>
|
||
</ul>
|
||
</p>
|
||
<p>
|
||
<a href="https://jsxgraph.org/wp/2024-06-28-release-of-version-1.9.2/">Version 1.9.2</a> introduces a new orientation control mode: the <em>virtual trackball</em>. In this mode, dragging from near the center of the board rolls the view along the drag direction, while dragging from near the edge of the board rotates the view in the plane of the board. These two motions transition smoothly into each other as the drag start position changes. To enable the virtual trackball, set the <code>trackball</code> attribute of the <code>View3D</code> to <code>{enabled: true}</code>.
|
||
</p>
|
||
<p>
|
||
This demo is based on the <a href="https://github.com/jsxgraph/jsxgraph/blob/main/examples/trackball.html">virtual trackball example</a> in the <a href="https://github.com/jsxgraph/jsxgraph/tree/main/examples">examples folder</a> included with the source code.
|
||
</p>
|
||
</p>
|
||
<div>
|
||
<label for="ori-ctl">Orientation control:</label>
|
||
<select id="ori-ctl">
|
||
<option value="angles">Tait–Bryan angles</option>
|
||
<option value="trackball">Virtual trackball</option>
|
||
</select>
|
||
</div>
|
||
<div id="trackball-board" class="jxgbox" style="width:600px; height:600px"></div>
|
||
|
||
<script type="text/javascript">
|
||
// to prevent variable name conflicts, we define variables locally using `let`
|
||
// and put the code for each board in its own block
|
||
{
|
||
// create a JSXGraph board and draw a 3D view on it
|
||
let board = JXG.JSXGraph.initBoard(
|
||
'trackball-board',
|
||
{
|
||
boundingbox: [-8, 8, 8,-8],
|
||
axis: false,
|
||
showCopyright: false,
|
||
showNavigation: false
|
||
}
|
||
);
|
||
let view = board.create(
|
||
'view3d',
|
||
[[-4.5, -4.5], [9, 9],
|
||
[[0, 5], [0, 5], [0, 5]]],
|
||
{
|
||
xPlaneRear: {fillOpacity: 0.2, gradient: null},
|
||
yPlaneRear: {fillOpacity: 0.2, gradient: null},
|
||
zPlaneRear: {fillOpacity: 0.2, gradient: null},
|
||
axis: true,
|
||
axesPosition: 'center',
|
||
xAxis: {
|
||
name: 'x',
|
||
strokeColor: 'red',
|
||
strokeWidth: 3,
|
||
withLabel: true,
|
||
label:{position: 'last', autoPosition: true}
|
||
},
|
||
yAxis: {
|
||
name: 'y',
|
||
strokeColor: 'green',
|
||
strokeWidth: 3,
|
||
withLabel: true,
|
||
label:{position: 'last', autoPosition: true}
|
||
},
|
||
zAxis: {
|
||
name: 'z',
|
||
strokeColor: 'blue',
|
||
strokeWidth: 3,
|
||
withLabel: true,
|
||
label:{position: 'last', autoPosition: true}
|
||
},
|
||
projection: 'central',
|
||
az: {
|
||
slider: {visible: true, min: -0.75*Math.PI, max: 1.25*Math.PI}
|
||
},
|
||
el: {
|
||
slider: {visible: true}
|
||
},
|
||
bank: {
|
||
slider: {visible: true, min: -(4/3)*Math.PI, max: (2/3)*Math.PI}
|
||
}
|
||
}
|
||
);
|
||
|
||
// switch between virtual trackball navigation and Tait-Bryan angle navigation
|
||
let ori_ctl = document.querySelector('#ori-ctl');
|
||
function inputOriCtl() {
|
||
view.setAttribute({'trackball': {enabled: ori_ctl.value === 'trackball'}});
|
||
}
|
||
ori_ctl.addEventListener('input', inputOriCtl);
|
||
inputOriCtl();
|
||
}
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|