Spaces:
Running
Running
| class ArtworkModal extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 9998; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 0.4s cubic-bezier(0.33, 1, 0.68, 1); | |
| } | |
| :host([open]) { | |
| opacity: 1; | |
| pointer-events: all; | |
| } | |
| .modal-backdrop { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.88); | |
| backdrop-filter: blur(20px); | |
| -webkit-backdrop-filter: blur(20px); | |
| } | |
| .modal-container { | |
| position: relative; | |
| width: 90%; | |
| max-width: 1200px; | |
| max-height: 90vh; | |
| background: white; | |
| border-radius: 24px; | |
| overflow: hidden; | |
| box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); | |
| transform: scale(0.95); | |
| transition: transform 0.4s cubic-bezier(0.33, 1, 0.68, 1); | |
| z-index: 1; | |
| } | |
| :host([open]) .modal-container { | |
| transform: scale(1); | |
| } | |
| .modal-content { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| height: 100%; | |
| } | |
| .modal-image { | |
| height: 100%; | |
| background-size: cover; | |
| background-position: center; | |
| } | |
| .modal-details { | |
| padding: 3rem; | |
| overflow-y: auto; | |
| } | |
| .close-button { | |
| position: absolute; | |
| top: 1.5rem; | |
| right: 1.5rem; | |
| width: 2.5rem; | |
| height: 2.5rem; | |
| border-radius: 50%; | |
| background: white; | |
| border: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| z-index: 2; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); | |
| transition: all 0.3s ease; | |
| } | |
| .close-button:hover { | |
| transform: rotate(90deg); | |
| } | |
| </style> | |
| <div class="modal-backdrop"></div> | |
| <div class="modal-container"> | |
| <button class="close-button"> | |
| <i data-feather="x"></i> | |
| </button> | |
| <div class="modal-content"> | |
| <div class="modal-image"></div> | |
| <div class="modal-details"> | |
| <h3 class="artwork-title"></h3> | |
| <p class="artwork-meta"></p> | |
| <p class="artwork-description"></p> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| this.closeButton = this.shadowRoot.querySelector('.close-button'); | |
| this.closeButton.addEventListener('click', () => this.close()); | |
| this.shadowRoot.querySelector('.modal-backdrop').addEventListener('click', () => this.close()); | |
| } | |
| open(artworkData) { | |
| const image = this.shadowRoot.querySelector('.modal-image'); | |
| const title = this.shadowRoot.querySelector('.artwork-title'); | |
| const meta = this.shadowRoot.querySelector('.artwork-meta'); | |
| const desc = this.shadowRoot.querySelector('.artwork-description'); | |
| image.style.backgroundImage = `url(${artworkData.image})`; | |
| title.textContent = artworkData.title; | |
| meta.textContent = `${artworkData.medium} | ${artworkData.year}`; | |
| desc.textContent = artworkData.description; | |
| this.setAttribute('open', ''); | |
| document.body.style.overflow = 'hidden'; | |
| feather.replace(); | |
| } | |
| close() { | |
| this.removeAttribute('open'); | |
| document.body.style.overflow = ''; | |
| } | |
| } | |
| customElements.define('artwork-modal', ArtworkModal); |