import '../pierzainer_ground/ground-link'; import { loadSampleIntoApp } from './sample-loader'; import { createSampleExplorer, sampleExplorerMarkup, type Sample } from './sample-explorer'; import { createLandingGuide } from './landing-guide'; import { createIntroVideo, introVideoTriggerMarkup } from './landing-video'; import { createHeroMotion, heroMotionMarkup } from './landing-motion'; import { heroCapture } from './assets/okseong-hero-capture'; import './landing-white.css'; import './landing-typography.css'; import './sample-library-popup.css'; import { createDrawingPopup, drawingPopupMarkup } from './drawing-popup'; const appRoot = document.querySelector('.app'); const homeButton = document.querySelector('#home-from-app'); const promoImageUrl = new URL('./assets/okseong-model-hero.webp', import.meta.url).href; const companyLogosUrl = new URL('./assets/family-company-logos.png', import.meta.url).href; const landingOverlay = document.createElement('div'); landingOverlay.className = 'landing-overlay landing-white'; landingOverlay.setAttribute('role', 'dialog'); landingOverlay.setAttribute('aria-modal', 'true'); landingOverlay.setAttribute('aria-label', '프로그램 시작 선택'); const landingPanelMarkup = `

PIER & ABUT

교량 하부구조 3D 통합모델링

PIERZAINER /BRIDGE DESIGN STUDIO

설계정보 입력부터 3D 모델링, 구조검토, 철근배근, 도면작성 및 수량산출까지 하나의 플랫폼에서

${introVideoTriggerMarkup}
01 / IMPORT
Excel Import

엑셀로 시작하기

설계정보를 불러와 교각·교대 3D 모델을 자동 생성합니다.

Excel · .xlsx
02 / EXTRACT
Drawing Import

도면으로 시작하기

기존 도면에서 교각·교대 정보를 추출하여 3D 모델을 생성합니다.

프로그램 안에서 도면 추출
03 / EXPLORE
Design Library

설계 DATA 아카이브

기존 설계 프로젝트의 교각·지형·지도를 살펴보고 불러옵니다.

12개 설계 프로젝트
한맥기술, 삼안, 장헌산업, 피티씨, 장헌, 한라산업개발, 바로컨설턴트 로고
${sampleExplorerMarkup}

엑셀 입력

선택 파일 선택된 파일이 없습니다.
${drawingPopupMarkup}
`; landingOverlay.innerHTML = landingPanelMarkup; document.body.prepend(landingOverlay); const landingGuide = createLandingGuide(landingOverlay); const introVideo = createIntroVideo(landingOverlay, promoImageUrl); createHeroMotion(landingOverlay); const selectPanel = (panelId: string): void => { landingGuide.close(false); document.querySelectorAll('.landing-panel').forEach((panel) => { panel.classList.toggle('visible', panel.id === panelId); }); const visible = document.getElementById(panelId); if (visible) { visible.scrollTo({ top: 0, behavior: 'auto' }); } }; const closePanels = (): void => { document.querySelectorAll('.landing-panel').forEach((panel) => panel.classList.remove('visible')); }; const showApp = (): void => { landingOverlay.querySelector('.sample-library-popup')?.close(); landingGuide.close(false); introVideo.close(false); if (appRoot) { appRoot.hidden = false; appRoot.setAttribute('aria-hidden', 'false'); } if (homeButton) { homeButton.hidden = false; } landingOverlay.hidden = true; }; const showLanding = (): void => { if (appRoot) { appRoot.hidden = true; appRoot.setAttribute('aria-hidden', 'true'); } if (homeButton) { homeButton.hidden = true; } landingOverlay.hidden = false; landingOverlay.classList.remove('modal-open'); closePanels(); }; const selectFile = (input: HTMLInputElement): void => { input.click(); }; const excelInput = document.querySelector('#landing-excel-input'); const excelName = document.querySelector('#landing-excel-name'); const excelStart = document.querySelector('#landing-excel-start'); const ensureNoLegacyImportDialog = (): void => { const dialog = document.querySelector('#import-dialog'); if (dialog && dialog.open) dialog.close(); }; if (excelInput && excelName && excelStart) { excelInput.addEventListener('change', () => { const file = excelInput.files?.[0]; const name = file ? file.name : '선택된 파일이 없습니다.'; excelName.textContent = name; excelStart.disabled = !file; ensureNoLegacyImportDialog(); }); excelStart.addEventListener('click', () => { if (!excelInput.files?.[0]) return; ensureNoLegacyImportDialog(); showApp(); }); } const bindFilePicker = (button: Element, targetId: string, nameTargetId: string): void => { const input = document.querySelector(`#${targetId}`); const output = document.querySelector(`#${nameTargetId}`); if (!input || !output) return; button.addEventListener('click', () => selectFile(input)); input.addEventListener('change', () => { const file = input.files?.[0]; output.textContent = file ? file.name : '미선택'; }); }; const bindCard = (cardSelector: string, panelId: string, mode: 'panel' | 'picker' = 'panel'): void => { const card = document.querySelector(cardSelector); const trigger = card?.querySelector('button'); if (!trigger) return; trigger.addEventListener('click', () => { landingGuide.dismissHint(); landingGuide.close(false); if (mode === 'picker') { if (cardSelector === '[data-card="excel"]') { if (landingOverlay) { landingOverlay.hidden = false; landingOverlay.classList.add('modal-open'); } const dialog = document.querySelector('#import-dialog'); if (dialog && !dialog.open) { dialog.showModal(); } const projectName = document.querySelector('#project-name'); if (projectName) projectName.focus(); return; } } selectPanel(panelId); }); }; bindCard('[data-card="excel"]', 'landing-excel-panel', 'picker'); const drawingPopup = createDrawingPopup(landingOverlay, () => { landingGuide.dismissHint(); landingGuide.close(false); closePanels(); }); document.querySelector('[data-card="drawing"] button')!.addEventListener('click', () => drawingPopup.open()); document.querySelectorAll('[data-close-panel]').forEach((button) => { button.addEventListener('click', () => { const panelId = button.getAttribute('data-close-panel'); if (!panelId) return; const panel = document.getElementById(panelId); panel?.classList.remove('visible'); }); }); document.querySelectorAll('[data-pick-file]').forEach((button) => { const kind = button.getAttribute('data-pick-file'); if (!kind) return; const targetMap: Record = { excel: 'landing-excel-input', }; const targetId = targetMap[kind]; if (!targetId) return; const input = document.querySelector(`#${targetId}`); if (!input) return; button.addEventListener('click', () => selectFile(input)); }); bindFilePicker(document.querySelector('[data-pick-file="excel"]') as HTMLButtonElement, 'landing-excel-input', 'landing-excel-name'); const libraryPopup=landingOverlay.querySelector('.sample-library-popup')!; landingOverlay.querySelector('[data-card="sample"] button')!.addEventListener('click',()=>{landingGuide.close(false);landingGuide.dismissHint();if(!libraryPopup.open)libraryPopup.showModal();}); libraryPopup.querySelector('.sample-library-close')!.addEventListener('click',()=>libraryPopup.close()); libraryPopup.addEventListener('close',()=>{requestAnimationFrame(()=>{landingOverlay.querySelectorAll('.landing-shell,.landing-hero').forEach(element=>element.scrollTo(0,0));landingOverlay.querySelector('[data-card=sample] button')?.focus({preventScroll:true});});}); createSampleExplorer(landingOverlay,(sample:Sample)=>loadSampleIntoApp(sample,showApp,showLanding)); if (homeButton) { homeButton.addEventListener('click', () => { showLanding(); }); } if (appRoot) { appRoot.hidden = true; appRoot.setAttribute('aria-hidden', 'true'); } if (homeButton) { homeButton.hidden = true; } showLanding();