485 lines
17 KiB
Plaintext
485 lines
17 KiB
Plaintext
{% assign content_type = content_type | default: 'body' %}
|
|
|
|
{% if content_type == 'body' %}
|
|
|
|
{% comment %}
|
|
|
|
<div id="shx-3d-render-input-container">
|
|
<style>.custom.form__label{margin-bottom: 0.6rem}.field.custom{margin-top:0}.custom .field__input{padding-top:0.8rem}</style>
|
|
<label class="form__label custom" for="your-label">Dein Text</label>
|
|
<div class="field custom">
|
|
<input class="field__input" form="{{ 'product-form-' | append: section.id }}" type="text" id="your-label" name="properties[Your label]">
|
|
</div>
|
|
</div>
|
|
|
|
{% endcomment %}
|
|
|
|
<shx-input-forms section_id="{{ section.id }}">
|
|
</shx-input-forms>
|
|
|
|
{% elsif content_type == 'init' %}
|
|
|
|
<style>
|
|
.shx-input-forms-container {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.shx_ifc_renderButton, .shx-ifc-form_label {
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.shx-threejs-renderer-container {
|
|
margin-top: 1rem;
|
|
border-radius: 10px;
|
|
border: 0;
|
|
width: 100%;
|
|
|
|
position: relative;
|
|
overflow: hidden;
|
|
display: flex;
|
|
}
|
|
|
|
.shx-threejs-renderer {
|
|
border: 0;
|
|
width: 100%;
|
|
|
|
background-color: #514642;
|
|
}
|
|
|
|
.shx-ifc-colorselect {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
.shx-ifc-colorselect label {
|
|
cursor: pointer;
|
|
|
|
width: 40px;
|
|
height: 40px;
|
|
margin: 8px;
|
|
border-radius: 2px;
|
|
|
|
position: relative;
|
|
}
|
|
|
|
.shx-ifc-colorselect label::after {
|
|
content: '';
|
|
display: block;
|
|
position: absolute;
|
|
|
|
top: -4px;
|
|
left: -4px;
|
|
|
|
width: calc(100% + 8px);
|
|
height: calc(100% + 8px);
|
|
border-radius: 4px;
|
|
|
|
border: 1px solid #0003;
|
|
}
|
|
|
|
.shx-ifc-colorselect input[type="radio"] {
|
|
height: 1px;
|
|
width: 1px;
|
|
position: absolute;
|
|
clip: rect(0, 0, 0, 0);
|
|
overflow: hidden;
|
|
}
|
|
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
|
|
let FilamentList = {
|
|
"#10": {
|
|
"name": "Schwarz (Matt)",
|
|
"hex": "#000000"
|
|
},
|
|
"#11": {
|
|
"name": "Weiß (Matt)",
|
|
"hex": "#FFFFFF"
|
|
},
|
|
}
|
|
|
|
|
|
let globalInputFormsObjValues = {
|
|
"test1": {
|
|
"text1": "test",
|
|
"font": "LT Beverage"
|
|
},
|
|
"test2": {
|
|
"text1": "test1",
|
|
"text2": "test2"
|
|
}, "TextOne": {
|
|
"text1": "Julia",
|
|
"font": "LT Beverage",
|
|
"color": "#000000"
|
|
|
|
}
|
|
};
|
|
|
|
function SHX_IFC_genTextInput(inputID, labelText, inputName, inputVal, section_id) {
|
|
return `
|
|
<label class="form__label custom shx-ifc-form_label" for="${inputID}-label">${labelText}</label>
|
|
<div class="field custom">
|
|
<input class="field__input" form="product-form-${section_id}" type="text" id="${inputID}" name="properties[${inputName}]" value="${inputVal}">
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function SHX_IFC_genRenderButton() {
|
|
return `
|
|
<button class="button shx_ifc_renderButton" onclick="document.querySelector('shx-input-forms').renderView()">Vorschau generieren</button>
|
|
`;
|
|
|
|
}
|
|
|
|
function SHX_IFC_genDropdownSelect(inputID, labelText, inputName, inputVal, options, section_id) {
|
|
let html = `
|
|
<label class="form__label custom shx-ifc-form_label" for="${inputID}-label">${labelText}</label>
|
|
<div class="field custom">
|
|
<select id="${inputID}" form="product-form-${section_id}" name="properties[${inputName}]" class="field__input" style="height: 40px">
|
|
`;
|
|
|
|
for(let i = 0; i < options.length; i++) {
|
|
html += `<option value="${options[i]}" ${inputVal === options[i] ? 'selected' : ''}>${options[i]}</option>`;
|
|
}
|
|
html += `</select></div>`;
|
|
|
|
return html;
|
|
}
|
|
|
|
function SHX_IFC_genColorSelect(inputID, labelText, inputName, inputVal, colorWhiteList, section_id) {
|
|
|
|
let options = {};
|
|
|
|
if(!colorWhiteList || colorWhiteList.length === 0) {
|
|
options = {...FilamentList};
|
|
} else for(let i = 0; i < colorWhiteList.length; i++) {
|
|
if(FilamentList[colorWhiteList[i]]) {
|
|
options[i] = FilamentList[colorWhiteList[i]];
|
|
} else {
|
|
console.error("Color not found in FilamentList", colorWhiteList[i]);
|
|
}
|
|
}
|
|
|
|
|
|
let html = `
|
|
<label class="form__label custom shx-ifc-form_label" for="${inputID}-label">${labelText}</label>
|
|
<div id="${inputID}" class="shx-ifc-colorselect">
|
|
`;
|
|
|
|
for(let color in options) {
|
|
html += `
|
|
<input type="radio" id="${inputID}-${i}" form="product-form-${section_id}" name="properties[${inputName}]" value="${options[color].name}" ${inputVal === color ? 'checked' : ''}>
|
|
<label for="${inputID}-${i}" style="background-color: ${options[i]};"></label>
|
|
|
|
`;
|
|
}
|
|
|
|
html += `</div>`;
|
|
|
|
return html;
|
|
}
|
|
|
|
const defaultStyle = `<style>.custom.form__label{margin-bottom: 0.6rem}.field.custom{margin-top: 0.6rem}.custom .field__input{padding-top:0.8rem}</style>`;
|
|
|
|
let globalInputFormsObj = {
|
|
"test1": {
|
|
"renderHTML": (section_id) => {
|
|
let html = defaultStyle;
|
|
|
|
// elementID, labeltext, shopping cart name, initial value, section_id
|
|
html += SHX_IFC_genTextInput('shx-text1', 'Custom Text 1', 'Text', globalInputFormsObjValues['test1']['text1'], section_id);
|
|
html += SHX_IFC_genDropdownSelect('shx-font', 'Schriftart', 'Schriftart', globalInputFormsObjValues['test1']['font'], ['LT Beverage', "Rose", 'Arial'], section_id);
|
|
html += SHX_IFC_genRenderButton();
|
|
|
|
return html;
|
|
}
|
|
},"test2": {
|
|
"renderHTML": (section_id) => {
|
|
let html = defaultStyle;
|
|
|
|
html += SHX_IFC_genTextInput('custom-text-1', 'Custom Text 1', 'Custom Text 1', globalInputFormsObjValues['test2']['text1'], section_id);
|
|
html += SHX_IFC_genTextInput('custom-text-2', 'Custom Text 2', 'Custom Text 2', globalInputFormsObjValues['test2']['text2'], section_id);
|
|
html += SHX_IFC_genRenderButton();
|
|
|
|
return html;
|
|
}
|
|
}, "TextOne": {
|
|
"renderHTML": (section_id) => {
|
|
let html = defaultStyle;
|
|
|
|
html += SHX_IFC_genColorSelect('shx-color', 'Farbe', 'Farbe', globalInputFormsObjValues['TextOne']['color'], ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF'], section_id);
|
|
html += SHX_IFC_genColorSelect('shx-color2', 'Farbe2', 'Farbe2', globalInputFormsObjValues['TextOne']['color'], ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF'], section_id);
|
|
html += SHX_IFC_genColorSelect('shx-color3', 'Farbe3', 'Farbe3', globalInputFormsObjValues['TextOne']['color'], ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF'], section_id);
|
|
html += SHX_IFC_genTextInput('shx-text1', 'Custom Text 1', 'Text', globalInputFormsObjValues['TextOne']['text1'], section_id);
|
|
html += SHX_IFC_genDropdownSelect('shx-font', 'Schriftart', 'Schriftart', globalInputFormsObjValues['TextOne']['font'], ['LT Beverage', "Rose", 'Arial'], section_id);
|
|
html += SHX_IFC_genRenderButton();
|
|
|
|
return html;
|
|
}
|
|
}
|
|
};
|
|
|
|
// create new html tag called "shx-input-forms"
|
|
class InputFormsElement extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
// element functionality written in here
|
|
this.currentVariant = null;
|
|
this.container = null;
|
|
|
|
this.uuid = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
|
|
this.section_id = null;
|
|
}
|
|
|
|
iFrameListener(event) {
|
|
|
|
//console.log("event.origin||", "'"+event.origin+"'", event.origin !== "https://3d-viewer.shinnex.de")
|
|
if(event.origin !== "https://3d-viewer.shinnex.de") return;
|
|
console.log("event.data||",event.data)
|
|
|
|
if(event.data === undefined) return;
|
|
|
|
let data;
|
|
try {
|
|
data = JSON.parse(event.data)["shx-3d-viewer"];
|
|
} catch(e) {
|
|
return;
|
|
}
|
|
|
|
let uuid =this.uuid;
|
|
console.log("uuid", uuid);
|
|
if(data.id !== this.uuid) {
|
|
if(data.status === "init" ) {
|
|
const initData = JSON.stringify({"init":{"uuid":uuid}});
|
|
console.log("initData", initData );
|
|
this.Viewer3D.contentWindow.postMessage(initData, "*");
|
|
|
|
this.loadingSpinner.show();
|
|
this.renderView();
|
|
}
|
|
return;
|
|
};
|
|
|
|
if(data.status === "error") {
|
|
if(data.errorMessage === "TooLong") {
|
|
this.loadingSpinner.showErrorCharLottie("Hoppla, der von dir eingegene Text ist zu lang. Bitte kürze ihn oder wende dich an uns für eine individuelle Lösung.");
|
|
return;
|
|
}
|
|
|
|
this.loadingSpinner.showError("Hoppla, da ist etwas schief gelaufen. Bitte versuche es später erneut.");
|
|
return;
|
|
}
|
|
|
|
console.log("Message received from the child: ", data); // Message received from child
|
|
|
|
if(data.loaded === true) {
|
|
this.loadingSpinner.hide();
|
|
} else {
|
|
this.loadingSpinner.show();
|
|
}
|
|
|
|
}
|
|
|
|
connectedCallback() {
|
|
|
|
let iFrameListener = this.iFrameListener.bind(this);
|
|
|
|
window.addEventListener('message', function(event) {
|
|
iFrameListener(event);
|
|
});
|
|
|
|
this.section_id = this.getAttribute('section_id');
|
|
|
|
this.innerHTML = '<div class="shx-input-forms-container"><div class="shx-input-forms-content"></div></div>';
|
|
this.container = this.querySelector('.shx-input-forms-container');
|
|
this.container.style.height = '0px';
|
|
|
|
this.content = this.container.querySelector('.shx-input-forms-content');
|
|
|
|
this.Viewer3DContainer = document.createElement('div');
|
|
this.Viewer3DContainer.classList.add('shx-threejs-renderer-container');
|
|
this.Viewer3DContainer.innerHTML = `{% render 'shx-loading-spinner', content_type:"body" %}`;
|
|
this.loadingSpinner = this.Viewer3DContainer.querySelector('shx-loading-spinner');
|
|
this.container.appendChild(this.Viewer3DContainer);
|
|
|
|
|
|
function createIFrame() {
|
|
this.Viewer3D = document.createElement('iframe');
|
|
|
|
const Viewer3D = this.Viewer3D;
|
|
|
|
this.Viewer3D.src = "https://3d-viewer.shinnex.de/";
|
|
this.Viewer3D.classList.add('shx-threejs-renderer');
|
|
this.Viewer3D.style.width = this.container.offsetWidth + 'px';
|
|
this.Viewer3D.style.height = this.container.offsetWidth + 'px';
|
|
|
|
|
|
|
|
|
|
|
|
this.Viewer3DContainer.appendChild(this.Viewer3D);
|
|
}
|
|
|
|
setTimeout(createIFrame.bind(this), 1000);
|
|
}
|
|
|
|
initCurrentVariant(id) {
|
|
this.currentVariant = id;
|
|
|
|
// edit inner html
|
|
this.reloadCurrentVariant(id, true);
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
// Clean up the element when it is removed from the DOM.
|
|
}
|
|
|
|
renderView() {
|
|
// request data from server
|
|
let tJS = this.tJS;
|
|
|
|
// update globalInputFormsObjValues from input fields
|
|
for(let key in globalInputFormsObj) {
|
|
if(key === this.currentVariant) {
|
|
let inputs = this.content.querySelectorAll('input');
|
|
|
|
for(let i = 0; i < inputs.length; i++) {
|
|
let input = inputs[i];
|
|
|
|
if(input.type === 'radio') {
|
|
if(input.checked) {
|
|
let name = input.id.replace('shx-', '');
|
|
name = name.slice(0, name.indexOf('-'));
|
|
|
|
globalInputFormsObjValues[key][name] = input.value;
|
|
}
|
|
}
|
|
else {
|
|
let name = input.id.replace('shx-', '');
|
|
globalInputFormsObjValues[key][name] = input.value;
|
|
}
|
|
}
|
|
|
|
let selects = this.content.querySelectorAll('select');
|
|
for(let i = 0; i < selects.length; i++) {
|
|
let name = selects[i].id.replace('shx-', '');
|
|
let options = selects[i].querySelectorAll('option');
|
|
for(let j = 0; j < options.length; j++) {
|
|
if(options[j].selected) {
|
|
globalInputFormsObjValues[key][name] = options[j].value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.Viewer3D)
|
|
this.Viewer3D.contentWindow.postMessage(JSON.stringify({"changeView":{"currentVariant": this.currentVariant, values: globalInputFormsObjValues[this.currentVariant]}}), "*");
|
|
|
|
this.loadingSpinner.show();
|
|
|
|
|
|
|
|
/*fetch('https://render.shinnex.de/render/' + this.currentVariant, { method: 'POST', body: JSON.stringify(globalInputFormsObjValues[this.currentVariant]) })
|
|
.then((response) => {
|
|
// stl file
|
|
return response.blob();
|
|
}).then((blob) => {
|
|
// log size in kB
|
|
console.log(blob.size / 1024 + 'kB');
|
|
|
|
});*/
|
|
|
|
}
|
|
|
|
updateSelectSwatch(event) {
|
|
let target = event.target;
|
|
let input = target.previousElementSibling;
|
|
input.checked = true;
|
|
|
|
this.renderView();
|
|
}
|
|
|
|
reloadCurrentVariant(id, openAnimation = false) {
|
|
this.currentVariant = id;
|
|
let content = this.content;
|
|
let container = this.container;
|
|
|
|
|
|
|
|
// edit inner html
|
|
content.innerHTML = "";
|
|
this.renderView();
|
|
|
|
for(let key in globalInputFormsObj) {
|
|
if(key === this.currentVariant) {
|
|
content.innerHTML = globalInputFormsObj[key].renderHTML(this.section_id);
|
|
}
|
|
}
|
|
|
|
const inputs = content.querySelectorAll('input');
|
|
|
|
for(let i = 0; i < inputs.length; i++) {
|
|
if(inputs[i].type === 'radio') {
|
|
inputs[i].addEventListener('change', this.updateSelectSwatch.bind(this));
|
|
}
|
|
}
|
|
|
|
console.log('reloadCurrentVariant', id, openAnimation);
|
|
|
|
|
|
if(openAnimation) {
|
|
// calculate of this height
|
|
container.style.height = 'auto';
|
|
let height = container.offsetHeight;
|
|
container.style.height = '0px';
|
|
|
|
function animate() {
|
|
anime({
|
|
targets: container,
|
|
height: height,
|
|
duration: 500,
|
|
easing: 'cubicBezier(0.590, 0.190, 0.050, 0.990)',
|
|
complete: function() {
|
|
container.style.height = 'auto';
|
|
container.style.overflow = 'visible';
|
|
}
|
|
});
|
|
}
|
|
|
|
//animejs fade in
|
|
//dom ready
|
|
|
|
if (document.getElementById('animejs-script').readyState === 'complete' || document.getElementById('animejs-script').readyState === 'loaded'){
|
|
animate();
|
|
} else {
|
|
document.getElementById('animejs-script').addEventListener('load', function() {
|
|
animate();
|
|
});
|
|
}
|
|
} else {
|
|
container.style.opacity = 0;
|
|
anime({
|
|
targets: container,
|
|
opacity: 1,
|
|
duration: 500,
|
|
easing: 'cubicBezier(0.590, 0.190, 0.050, 0.990)'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
customElements.define('shx-input-forms', InputFormsElement);
|
|
|
|
|
|
</script>
|
|
|
|
{% endif %}
|
|
|