diff --git a/includes/GlModelHooks.php b/includes/GlModelHooks.php index f969621..6908c24 100644 --- a/includes/GlModelHooks.php +++ b/includes/GlModelHooks.php @@ -76,11 +76,18 @@ class GlModelHooks { $previewViewer = $mvTransform->toHtml([ 'preview' => true]); $addButtonAttr = array( - 'class' => 'AddHotspot', + 'class' => 'preview-button AddHotspot', 'onclick' => 'readyAddHotspot()' ); + + $readButtonAttr = array( + 'class' => 'preview-button ReadHotspots', + 'onclick' => 'readMetadata()' + ); + $addHsButton = array( - Html::rawElement('button',$addButtonAttr,'Add a new hotspot') + Html::rawElement('button',$addButtonAttr,'Add a new hotspot'), + Html::rawElement('button',$readButtonAttr,'Update hotspots') ); $previewHTML = Html::rawElement('div',NULL,$previewViewer.implode($addHsButton)); diff --git a/modules/glmv.js b/modules/glmv.js index 7f763ff..bf66af0 100644 --- a/modules/glmv.js +++ b/modules/glmv.js @@ -9,6 +9,89 @@ modelLoaded = function() { $('.awaiting-model').css('display', 'flex').removeClass('awaiting-model') } +/** + * Reads the json string in the edit panel + * and updates hotspot elements + * + * @return {bool} true on successful read and update + */ +readMetadata = function() { + let hotspotsObj = [] + var metadata + try { + [_, metadata] = extractMetadata() + } catch (err) { + console.warn('Failed to read model metadata:' + err.message) + return false + } + Object.keys(metadata.annotations).forEach((hs, idx) => { + let newHs = document.createElement('button') + newHs.classList.add('Hotspot') + newHs.setAttribute('slot',`hotspot-${idx + 1}`) + newHs.setAttribute('ontouchstart', 'event.stopPropagation()') + newHs.setAttribute('onclick', 'onAnnotation(event)') + newHs.setAttribute('onmousedown', 'grabAnnotation(event)') + newHs.setAttribute('onmouseup', 'releaseAnnotation(event)') + Object.keys(metadata.annotations[hs]).forEach((prop) => { + newHs.setAttribute(prop, metadata.annotations[hs][prop]) + }) + let newAn = document.createElement('div') + newAn.classList.add('HotspotAnnotation', 'HiddenAnnotation') + newAn.innerText = hs + newHs.appendChild(newAn) + newLabel = document.createElement('span') + newLabel.innerText = idx + 1 + newHs.appendChild(newLabel) + hotspotsObj.push(newHs) + }) + $('model-viewer button').remove() + const mView = $('model-viewer')[0] + hotspotsObj.forEach(hs => { + mView.appendChild(hs) + }) + return true +} + +/** + * Parses the current hotspots into json object + * and writes the json string to the edit panel + * + * @return {bool} true on successful write to edit panel + */ +writeMetadata = function () { + let annotationsObj = {} + currentButtons = $('.Hotspot').each(function() { + let buttonEl = $(this)[0] + annotationsObj[buttonEl.childNodes[0].innerText] = { + "data-position": buttonEl.getAttribute('data-position'), + "data-normal": buttonEl.getAttribute('data-normal'), + "data-orbit": buttonEl.getAttribute('data-orbit'), + "data-target": buttonEl.getAttribute('data-target') + } + }) + if (Object.keys(annotationsObj).length === 0) return false + const [currentText, metadata] = extractMetadata() + metadata.annotations = annotationsObj + const newText = currentText.replace(/(.*?
)[\S\s]*?(<\/pre>.*)/,`$1\n${JSON.stringify(metadata, null, 2)}\n$2`)
+ $('#wpTextbox1').val(newText)
+ return true
+}
+
+/**
+ * Convert text in the preview text editor to js object
+ *
+ * @return object containing metadata information
+ */
+extractMetadata = function() {
+ const editText = $('#wpTextbox1').val()
+ const extractMetadata = editText.match(/([\S\s]*?)<\/pre>/)
+ let metadata = (extractMetadata.length >= 2) ? JSON.parse(extractMetadata[1]) : {viewerConfig: {}, annotations: {}, annotationSets: {}}
+ if (metadata.annotations === undefined) {
+ metadata.annotations = {}
+ }
+ return [editText, metadata]
+}
+
/**
* Sets listener and attributes on model-viewer to
* allow for click registering of a new hotspot
@@ -41,7 +124,7 @@ clickAddHotspot = function(e) {
}
if (hsPosition) {
let currentText = $('#wpTextbox1').val()
- let metadata = extractMetadata(currentText)
+ let [_, metadata] = extractMetadata(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")
@@ -53,6 +136,7 @@ clickAddHotspot = function(e) {
let newText = currentText.replace(/(.*?)[\S\s]*?(<\/pre>.*)/,`$1\n${JSON.stringify(metadata, null, 2)}\n$2`)
$('#wpTextbox1').val(newText)
}
+ readMetadata()
}
/**
@@ -224,7 +308,7 @@ moveAnnotation = function(e) {
* @param {MouseEvent} event
*/
releaseAnnotation = function(e) {
- if (grabHotspot.move) {
+ if (grabHotspot && grabHotspot.move) {
console.log(e.target)
e.target.style['transform']=''
const contEl = $('.glmv-container')[0]
@@ -256,20 +340,4 @@ releaseAnnotation = function(e) {
$('#wpTextbox1').val(newText)
}
grabHotspot = null
-}
-
-/**
- * Convert text in the preview text editor to js object
- *
- * @param {string} editText
- *
- * @return object containing metadata information
- */
-extractMetadata = function(editText) {
- let extractMetadata = editText.match(/([\S\s]*?)<\/pre>/)
- let metadata = (extractMetadata.length >= 2) ? JSON.parse(extractMetadata[1]) : {viewerConfig: {}, annotations: {}, annotationSets: {}}
- if (metadata.annotations === undefined) {
- metadata.annotations = {}
- }
- return metadata
}
\ No newline at end of file