const TOML = require('./mini-st.js') let deleteHotspot = null let grabHotspot = null /** * Sets listener and attributes on model-viewer to * allow for click registering of a new hotspot */ readyAddHotspot = function() { disableViewer('AddingHotspot', clickAddHotspot) } /** * Event listener callback to retrieve the info * about the model surface point selected by the * mouse and add that information to the editor * text input * * @param {PointerEvent} e */ clickAddHotspot = function(e) { let hsPosition = null let targetModel = enableViewer() if (targetModel) { hsPosition = targetModel.positionAndNormalFromPoint(e.clientX, e.clientY) } if (hsPosition) { let currentText = $('#wpTextbox1').val() let [_, mvconfig] = extractMvconfig(currentText) let hsOutput = {} hsOutput['data-position'] = hsPosition.position.toString().replaceAll(/(\d{5})(\d*?m)/g,"$1m") hsOutput['data-normal'] = hsPosition.normal.toString().replaceAll(/(\d{5})(\d*?m)/g,"$1m") hsOutput['data-orbit'] = orb2degree(targetModel.getCameraOrbit().toString(),[2,2,5]) let targetObj = targetModel.getCameraTarget() hsOutput['data-target'] = `${targetObj.x.toFixed(5)}m ${targetObj.y.toFixed(5)}m ${targetObj.z.toFixed(5)}m` hsOutput['field-of-view'] = Number.parseFloat(targetModel.getFieldOfView()).toFixed(5) + 'deg' mvconfig.annotations['Hotspot ' + (Object.keys(mvconfig.annotations).length + 1)] = hsOutput let newText = currentText.replace(/(.*?)[\S\s]*?(<\/mvconfig>.*)/,`$1\n${TOML.stringify(mvconfig, null, 2)}\n$2`) $('#wpTextbox1').val(newText) } readMvconfig() } /** * Set flag and attributes on model-viewer to * delete the next hotspot that is clicked */ readyDelHotspot = function() { deleteHotspot = true disableViewer('DeletingHotspot', cancelDeleteHotspot) } /** * Unset deleting flag and return normal * function and style to model viewer */ cancelDeleteHotspot = function() { deleteHotspot = null enableViewer() } /** * Delete the selected hotspot * * @param {element} hs hotspot element to delete */ clickDeleteHotspot = function (hs) { deleteHotspot = null enableViewer() const anName = hs.target.childNodes[0].innerText let purgeAnnotation = new RegExp('(?<="annotationSets"[\\S\\s]*?)(^.*?' + anName + '.*\n)','gm') hs.target.remove() const editText = $('#wpTextbox1').val() const newText = editText.replace(purgeAnnotation,'') const finalText = newText.replace(/(,)(\n\s+])/gm,'$2') $('#wpTextbox1').val(finalText) writeMvconfig() readMvconfig() } /** * Check status of delete function */ isDeleting = function() { return deleteHotspot } /** * Prepare to drag a hotspot * * @param {MouseEvent} event */ grabAnnotation = function(e) { if (e.ctrlKey) { grabHotspot = {x: e.x, y: e.y} const contEl = $('.glmv-container')[0] contEl.addEventListener('mousemove', moveAnnotation) const mvEl = $('model-viewer')[0] } else { grabHotspot = null } } /** * Drag currently clicked hotspot * * @param {MouseEvent} event */ moveAnnotation = function(e) { if (grabHotspot) { grabHotspot.move = true e.target.style['transform'] = `translate(${e.x - grabHotspot.x}px, ${e.y - grabHotspot.y}px) scale(1.1,1.1)` } } /** * End dragging a hotspot and update information * * @param {MouseEvent} event */ releaseAnnotation = function(e) { if (grabHotspot && grabHotspot.move) { e.target.style['transform']='' const contEl = $('.glmv-container')[0] contEl.removeEventListener('mousemove', moveAnnotation) const mvEl = $('model-viewer')[0] let newPosition = mvEl.positionAndNormalFromPoint(e.clientX, e.clientY) const newPos = newPosition.position.toString().replaceAll(/(\d{5})(\d*?m)/g,"$1m") const newNorm = newPosition.normal.toString().replaceAll(/(\d{5})(\d*?m)/g,"$1m") mvEl.updateHotspot({ name: e.target.slot, position: newPos, normal: newNorm }) const newOrb = orb2degree(mvEl.getCameraOrbit().toString(),[2,2,5]) e.target.setAttribute('data-orbit', newOrb) let targetObj = mvEl.getCameraTarget() const newTarg = `${targetObj.x.toFixed(5)}m ${targetObj.y.toFixed(5)}m ${targetObj.z.toFixed(5)}m` e.target.setAttribute('data-target', newTarg) const newFov = Number.parseFloat(mvEl.getFieldOfView()).toFixed(5) + 'deg' e.target.setAttribute('field-of-view', newFov) let currentText = $('#wpTextbox1').val() let [_, mvconfig] = extractMvconfig(currentText) mvconfig.annotations[e.target.childNodes[0].innerText] = { "data-position": newPos, "data-normal": newNorm, "data-orbit": newOrb, "data-target": newTarg, "field-of-view": newFov } const newText = currentText.replace(/(.*?)[\S\s]*?(<\/mvconfig>.*)/,`$1\n${TOML.stringify(mvconfig, null, 2)}\n$2`) $('#wpTextbox1').val(newText) } grabHotspot = null } /** * Change the currently selected annotation set * * @param {string} newSet name of annotation set to select */ selectAnnotationSet = function(newSet) { $('model-viewer').attr('currentSet',newSet) readMvconfig() }