class FlatCube extends HTMLElement {
constructor() {
super();
this.faces = 'URFDLB'.split('');
this.facelet = false;
// We attach an open shadow root to the custom element
this._shadowRoot = this.attachShadow({ mode: 'open' });
this.template = this.createTemplate();
this.render();
}
style() {
return `
:host {
display: inline-block;
--flat-cube-face-width: var(--flat-cube-face, 100px);
}
.flat-cube {
position: relative;
height: calc(3 * var(--flat-cube-face-width));
margin: 0 auto;
width: calc(4 * var(--flat-cube-face-width));
}
.face {
display: flex;
height: var(--flat-cube-face-width);
width: var(--flat-cube-face-width);
outline: 1px solid var(--flat-cube-outer, black);
position: absolute;
flex-wrap: wrap;
justify-content: space-between;
}
.U-face {top:0; left: var(--flat-cube-face-width); }
.L-face {top:var(--flat-cube-face-width); left: 0; }
.F-face {top:var(--flat-cube-face-width); left: var(--flat-cube-face-width); }
.R-face {top:var(--flat-cube-face-width); left: calc(2 * var(--flat-cube-face-width)); }
.B-face {top:var(--flat-cube-face-width); left: calc(3 * var(--flat-cube-face-width)); }
.D-face {top:calc(2 * var(--flat-cube-face-width)); left: var(--flat-cube-face-width); }
.face > div {
width: calc(var(--flat-cube-face-width)/3);
height: calc(var(--flat-cube-face-width)/3);
outline: 1px solid var(--flat-cube-inner, black);
}
.U-piece {background-color: var(--flat-cube-up, #ebed2b); }
.L-piece {background-color: var(--flat-cube-left, #ff6b16); }
.F-piece {background-color: var(--flat-cube-front, #6cfe3b); }
.R-piece {background-color: var(--flat-cube-right, #ec1d35); }
.B-piece {background-color: var(--flat-cube-back, #4db4d7); }
.D-piece {background-color: var(--flat-cube-down, #fffbf8); }
`;
}
createTemplate() {
const template = document.createElement('template');
template.innerHTML = `<style>${this.style()}</style>`;
const cubeElement = document.createElement('div');
cubeElement.classList.add('flat-cube');
this.faces.forEach((face, i) => {
const faceElement = document.createElement('div');
faceElement.classList.add('face');
faceElement.classList.add(`${face}-face`);
for (let j=0; j < 9; j++) {
faceElement.appendChild(this.preparePiece(i, j));
}
cubeElement.appendChild(faceElement);
});
template.content.appendChild(cubeElement);
return template;
}
updateTemplate() {
const update = this.template.content.cloneNode(true);
update.querySelectorAll('.face').forEach((face, i) => {
face.querySelectorAll('div').forEach((piece, j) => {
this.preparePiece(i, j, piece);
});
});
return update;
}
preparePiece(i, j, piece = document.createElement('div')) {
const start = (i * 9) + j;
const end = (i * 9) + j + 1;
piece.className = !this.facelet ? `${this.faces[i]}-piece` : `${this.facelet.slice(start, end)}-piece`;
return piece;
}
render() {
this._shadowRoot.innerHTML = '';
this._shadowRoot.appendChild(this.updateTemplate());
}
static get observedAttributes() {
return ['facelet'];
}
attributeChangedCallback(name, oldValue, newValue) {
this.facelet = newValue;
this.render();
}
}
if (!window.customElements.get('flat-cube')) {
customElements.define('flat-cube', FlatCube);
}