Skip to content

Commit

Permalink
XCD-147 Implement an example of annotation touch create
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalDybizbanskiCreoox committed Sep 3, 2024
1 parent fb7f0ae commit 1b6ba65
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 0 deletions.
245 changes: 245 additions & 0 deletions examples/annotations/annotations_createWithTouch.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>xeokit Example</title>
<link href="../css/pageStyle.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.

<style>

.annotation-marker {
color: #ffffff;
line-height: 1.8;
text-align: center;
font-family: "monospace";
font-weight: bold;
position: absolute;
width: 25px;
height: 25px;
border-radius: 15px;
border: 2px solid #ffffff;
background: black;
visibility: hidden;
box-shadow: 5px 5px 15px 1px #000000;
z-index: 0;
}

.annotation-label {
position: absolute;
max-width: 250px;
min-height: 50px;
padding: 8px;
padding-left: 12px;
padding-right: 12px;
background: #ffffff;
color: #000000;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 8px;
border: #ffffff solid 2px;
box-shadow: 5px 5px 15px 1px #000000;
z-index: 90000;
}

.annotation-label:after {
content: '';
position: absolute;
border-style: solid;
border-width: 8px 12px 8px 0;
border-color: transparent white;
display: block;
width: 0;
z-index: 1;
margin-top: -11px;
left: -12px;
top: 20px;
}

.annotation-label:before {
content: '';
position: absolute;
border-style: solid;
border-width: 9px 13px 9px 0;
border-color: transparent #ffffff;
display: block;
width: 0;
z-index: 0;
margin-top: -12px;
left: -15px;
top: 20px;
}

.annotation-title {
font: normal 20px arial, serif;
margin-bottom: 8px;
}

.annotation-desc {
font: normal 14px arial, serif;
}

</style>
</head>

<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
<img class="info-icon" src="../../assets/images/annotation_icon.png"/>
<h1>AnnotationsPlugin</h1>
<h2>Click or tap the model to create annotations</h2>
<h3>Components Used</h3>
<ul>
<li>
<a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
target="_other">Viewer</a>
</li>
<li>
<a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
target="_other">XKTLoaderPlugin</a>
</li>
<li>
<a href="../../docs/class/src/plugins/AnnotationsPlugin/AnnotationsPlugin.js~AnnotationsPlugin.html"
target="_other">AnnotationsPlugin</a>
</li>
</ul>
<h3>Resources</h3>
<ul>
<li>
<a href="http://openifcmodel.cs.auckland.ac.nz/Model/Details/274"
target="_other">Model source</a>
</li>
</ul>
</div>
</body>

<script type="module">

//------------------------------------------------------------------------------------------------------------------
// Import the modules we need for this example
//------------------------------------------------------------------------------------------------------------------

import { AnnotationsPlugin, PointerCircle, touchPointSelector, Viewer, XKTLoaderPlugin } from "../../dist/xeokit-sdk.min.es.js";

//------------------------------------------------------------------------------------------------------------------
// Create a Viewer and arrange the camera
//------------------------------------------------------------------------------------------------------------------

const viewer = new Viewer({
canvasId: "myCanvas"
});

viewer.camera.eye = [-3.93, 2.85, 27.01];
viewer.camera.look = [4.40, 3.72, 8.89];
viewer.camera.up = [-0.01, 0.99, 0.039];

//------------------------------------------------------------------------------------------------------------------
// Load a model
//------------------------------------------------------------------------------------------------------------------

const xktLoader = new XKTLoaderPlugin(viewer);

const sceneModel = xktLoader.load({
id: "myModel",
src: "../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt",
edges: true
});

//------------------------------------------------------------------------------------------------------------------
// Create an AnnotationsPlugin, with which we'll create annotations
//------------------------------------------------------------------------------------------------------------------

const annotations = new AnnotationsPlugin(viewer, {

markerHTML: "<div class='annotation-marker' style='background-color: {{markerBGColor}};'>{{glyph}}</div>",
labelHTML: "<div class='annotation-label' style='background-color: {{labelBGColor}};'><div class='annotation-title'>{{title}}</div><div class='annotation-desc'>{{description}}</div></div>",

values: {
markerBGColor: "red",
glyph: "X",
title: "Untitled",
description: "No description"
},

// Amount to offset each Annotation from its Entity surface (0.3 is the default value).
// This is useful when the Annotation is occludable, which is when it is hidden when occluded
// by other objects. When occludable, there is potential for the Annotation#worldPos to become
// visually embedded within the surface of its Entity when viewed from a distance. This happens
// as a result of limited GPU accuracy GPU accuracy, especially when the near and far view-space clipping planes,
// specified by Perspective#near and Perspective#far, or Ortho#near and Perspective#far, are far away from each other.
//
// Offsetting the Annotation may ensure that it does become visually embedded within its Entity. We may also
// prevent this by keeping the distance between the view-space clipping planes to a minimum. In general, a good
// default value for Perspective#far and Ortho#far is around ````2.000````.

surfaceOffset: 0.1
});

//------------------------------------------------------------------------------------------------------------------
// Use the AnnotationsPlugin to create an annotation wherever we tap on an object
//------------------------------------------------------------------------------------------------------------------

// This creates a function that will attach touch listeners to canvas, and handle tap events
const setupTouchSelector = touchPointSelector(
viewer,
new PointerCircle(viewer), // needed to indicate tap duration to user
(orig, dir) => {
// find an intersection of a ray from the camera through the scene entities
const pickResult = viewer.scene.pick({
origin: orig,
direction: dir,
pickSurface: true
});
return pickResult && pickResult.worldPos;
});

(function setupCreateAnnotation(id) {

// This is a handler to add a single annotation

// An annotation is created ...
const annotation = annotations.createAnnotation({
id: "myAnnotation" + id,
// occludable: true,
markerShown: true,
labelShown: true,
values: {
glyph: "A" + id,
title: "My annotation " + id,
description: "My description " + id
},
});

const setAnnotationPos = worldPos => {
if (worldPos) {
annotation.worldPos = worldPos;
}
annotation.setMarkerShown(!! worldPos);
annotation.setLabelShown(!! worldPos);
};

setAnnotationPos(null); // initialy hide the annotation until the first user interaction

// ... and touch events are handled through setupTouchSelector callbacks
setupTouchSelector(
() => setAnnotationPos(null), // onCancel continue the action
(canvasPos, worldPos) => setAnnotationPos(worldPos), // onChange update annotation's position
(canvasPos, worldPos) => { // onCommit
if (worldPos) { // if the point selected by user was on top
setAnnotationPos(worldPos); // of an attachable surface
annotation.occludable = true; // then fix the annotation in place
setupCreateAnnotation(id + 1); // and move on to next annotation
} else {
annotation.destroy(); // otherwise if the point was dragged by user
setupCreateAnnotation(id); // outside attachable surfaces then start over
}
});

})(1); // first `id` to start with

</script>
</html>
1 change: 1 addition & 0 deletions examples/annotations/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
["annotations_hoverShowLabels", "Hover annotation markers to show labels"],
["annotations_clickFlyToPosition", "Click annotation markers to go to vantage points"],
["annotations_createWithMouse", "Click on the model to create annotations"],
["annotations_createWithTouch", "Tap on the model to create annotations"],
["annotations_createWithMouse_orthoWithZMarkerOffset", "Click on the model to create annotations, control OcclusionTester.js precision"],
["annotations_createWithMouse_orthoWithZMarkerOffsetZero", "Click on the model to create annotations, control OcclusionTester.js precision"],
["annotations_createAtCenterOfClickedObject", "Click objects to create annotations at their centers"],
Expand Down

0 comments on commit 1b6ba65

Please sign in to comment.