| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- #업종별
- #해피CGI
- CGIMALL
- 홈페이지제작
- #CSS
- #happycgi
- #뉴스
- CSS
- #이미지
- #cgimall
- 해피씨지아이
- javascript
- jquery
- #jQuery
- #솔루션
- #image
- #홈페이지제작
- 해피CGI
- 홈페이지
- 게시판
- 이미지
- 솔루션
- 웹솔루션
- #웹솔루션
- #쇼핑몰
- php
- #홈페이지
- #동영상
- happycgi
- 사이트제작
- Today
- Total
웹솔루션개발 26년 노하우! 해피CGI의 모든것
[해피CGI][cgimall] pencere – 이미지·동영상·아이프레임 지원 접근성 갤러리 라이트박스 본문
웹프로그램밍 자료실/JAVA 자료
[해피CGI][cgimall] pencere – 이미지·동영상·아이프레임 지원 접근성 갤러리 라이트박스
해피CGI윤실장 2026. 6. 22. 09:14pencere – 이미지·동영상·iframe 지원 접근성 갤러리 라이트박스
※ "pencere"는 터키어로 "창문"이라는 뜻입니다.

# 짧은 설명
JavaScript/TypeScript 기반의 미디어 뷰어 라이브러리로, 이미지·동영상·iframe·커스텀 HTML 콘텐츠를 반응형 갤러리 라이트박스로 표시합니다. View Transitions API를 활용해 썸네일에서 라이트박스로 부드럽게 전환되는 모핑 효과를 제공하며, 프레임워크에 종속되지 않으면서도 React, Vue, Svelte, Solid, Web Components용 어댑터를 모두 지원합니다.
# 라이센스
MIT License (상업적 이용 가능, 자유로운 수정·배포 가능)
# 설치방법
① NPM 설치
npm install pencere
import { PencereViewer } from "pencere"
② CDN 방식
③ JavaScript로 갤러리 생성
const viewer = new PencereViewer({ items: [ { type: "image", src: "/photos/coast.jpg", alt: "Coastal cliffs", caption: "Pacific Coast" }, { type: "image", src: "/photos/forest.jpg", alt: "Redwood forest" }, ], loop: true, viewTransition: true, // 썸네일→라이트박스 모핑 효과 routing: true, // URL 해시(#p1, #p2)에 슬라이드 위치 기록 }) document.querySelector('#gallery-trigger') ?.addEventListener('click', (e) => viewer.open(0, e.currentTarget))
④ HTML 선언적 사용 (bindPencere)
HTML 마크업만으로 자동 갤러리 그룹화가 가능합니다.
<a href="/photos/coast.jpg" data-pencere data-gallery="nature" data-caption="Pacific Coast"> <img src="/photos/coast-thumb.jpg" alt="Coastal cliffs" /> </a> <a href="/photos/forest.jpg" data-pencere data-gallery="nature" data-caption="Redwood Forest"> <img src="/photos/forest-thumb.jpg" alt="Redwood forest" /> </a> <script type="module"> import { bindPencere } from "pencere" const unbind = bindPencere("[data-pencere]") </script>
⑤ 프레임워크별 사용
- React: import { useLightbox } from "pencere/react"
- Vue: import { usePencere } from "pencere/vue"
- Svelte: import { pencere } from "pencere/svelte" (use: 디렉티브)
- Web Component: <pencere-lightbox> 커스텀 엘리먼트 등록
# 중요 옵션
| items | 표시할 콘텐츠 배열 (type은 image/video/iframe/html) | 필수 |
| startIndex | 처음 열 슬라이드 인덱스 (0부터) | 0 |
| loop | 마지막→처음 순환 탐색 | false |
| container | 뷰어를 마운트할 특정 DOM 요소 | body |
| strings / i18n | UI 문자열 개별 오버라이드 / 전체 번역 함수 | - |
| keyboard | 키 바인딩 재매핑 또는 비활성화 | - |
| image | 생성되는 <img>의 crossOrigin, referrerPolicy 설정 | - |
| reducedMotion | 애니메이션 정책 (auto / always / never) | auto |
| useNativeDialog | 네이티브 <dialog> 요소로 렌더링 | true |
| lockScroll | 뷰어 열림 중 페이지 스크롤 잠금 | - |
| nonce | CSP nonce (구형 브라우저용 fallback <style>에 적용) | - |
| dir | 텍스트 방향 (ltr / rtl / auto) | auto |
| haptics | 터치 디바이스 진동 피드백 활성화 | false |
| routing | URL 해시에 슬라이드 위치 기록 (#p1, #p2…) | false |
| fullscreen | 전체화면 컨트롤 노출 (iOS Safari는 CSS fallback) | false |
| viewTransition | View Transitions API로 썸네일→뷰어 모핑 활성화 | false |
| renderers | 커스텀 콘텐츠 렌더러 등록 (3D 모델 등) | [ ] |
옵션명 설명 기본값
주요 API 메서드
| viewer.open(index, thumbnailElement) | 지정 인덱스로 열기 (썸네일 요소를 두번째 인자로 넘기면 모핑 효과 활성화) |
| viewer.close() | 뷰어 프로그래밍 방식 닫기 |
| viewer.next() / viewer.prev() | 다음/이전 슬라이드 |
| viewer.goTo(index) | 특정 인덱스로 이동 |
| viewer.openFromLocation() | URL 해시 기반으로 해당 슬라이드 열기 |
| viewer.enterFullscreen() / viewer.toggleFullscreen() | 전체화면 진입 / 토글 |
메서드 설명
라이프사이클 이벤트
willOpen, change, slideLoad, didRender, didNavigate, close (close 시 reason: escape / backdrop / user / api)
# 특징 및 설명
콘텐츠 타입
- 이미지, 동영상, iframe, 커스텀 HTML을 단일 라이트박스에서 모두 처리
- 커스텀 렌더러 등록 가능 (예: <model-viewer> 같은 3D 모델 웹 컴포넌트)
- <picture> 태그 자동 생성으로 AVIF/WebP 형식 자동 협상 (sources 배열 사용 시)
- srcset, sizes로 반응형 이미지 지원
- ThumbHash·BlurHash 플레이스홀더 크로스페이드
모션 & 인터랙션
- View Transitions API 기반 네이티브 썸네일→라이트박스 모핑 효과
- 핀치 줌, 더블탭 토글, 마우스 휠 줌, 확대 이미지 드래그 팬
- 아래로 스와이프해서 닫기 (배경 페이드 효과)
- 전체화면 API 지원 (iOS Safari는 CSS 고정 위치 오버레이로 fallback)
접근성 (WCAG 2.2 AA 완전 준수)
- 포커스 관리, 44×44px 터치 타겟, 키보드 사용자용 드래그 대체 수단
- IME 안전 키보드 단축키 (한글 등 조합 입력 중에는 단축키 무시)
- prefers-reduced-motion 미디어 쿼리 자동 반응
- 14개 언어 내장 번역 (한국어, 일본어, 중국어 간체, 아랍어 등 포함)
- RTL 자동 감지 → 화살표·스와이프·레이아웃 자동 반전 (아랍어·히브리어)
라우팅 & 공유
- 해시 기반 딥링크: 슬라이드 변경 시 URL fragment(#p1, #p2) 자동 기록
- 페이지 로드 시 URL 해시 읽어서 해당 슬라이드 자동 오픈
- 브라우저 뒤로가기 버튼이 뷰어를 닫음 (popstate 감지)
- 해시 패턴 커스터마이징 가능
보안 & 배포 안정성
- Strict CSP 호환: adoptedStyleSheets 사용으로 style-src 우회 (Chrome 73+, Firefox 101+, Safari 16.4+)
- 구형 브라우저는 nonce 기반 fallback <style> 지원
- HTML 캡션용 Trusted Types 정책 헬퍼 제공
- SLSA 검증된 npm 릴리스, CDN용 SRI 해시 제공
테마 & 커스터마이징
- 모든 시각 속성을 CSS 커스텀 프로퍼티로 노출 (--pc-bg, --pc-fg, --pc-font, --pc-focus 등)
- 어디서든 CSS cascade로 오버라이드 가능
프레임워크 지원
- 프레임워크 무관 코어 + React, Vue, Svelte, Solid, Web Components용 어댑터 별도 제공
- 모바일 환경에서 옵션 활성화 시 햅틱 피드백 (Vibration API)
추천 활용처
포트폴리오 사이트(썸네일 그리드에서 풀해상도 모핑 오버레이), 이커머스 상품 페이지(이미지·동영상·3D 모델을 하나의 라이트박스에), 뉴스·에디토리얼 사이트(외부 URL에서 특정 갤러리 슬라이드로 딥링크).
참고 링크
- GitHub 원본: https://github.com/productdevbook/pencere
- 라이브 데모: cssscript.com 데모
- demo/demo.html 을 만들어 두었습니다. (cdn 이용하는 방식)
'웹프로그램밍 자료실 > JAVA 자료' 카테고리의 다른 글
| [해피CGI][cgimall] Autumn Note - 위지윅 에디터 (0) | 2026.06.19 |
|---|---|
| [해피CGI][cgimall] Textarea auto-expand 입력되는 내용에 따라 높이가 조절되는 textarea (0) | 2026.06.17 |
| [해피CGI][cgimall] 부드러운 다크/라이트 모드 전환 라이브러리 - DayniteJS (0) | 2026.05.21 |
| [해피CGI][cgimall] FilePond – 드래그앤드롭을 지원하는 JavaScript 파일 업로드 라이브러 (0) | 2026.05.12 |
| [해피CGI][cgimall] Flatpickr - 가볍고 강력한 날짜, 시간 선택 라이브러리 (0) | 2026.05.11 |
Comments

