Dialog / 28 ペーパーフォールド|Paper Fold
デザイン見本
Paper Fold Dialog
紙がパタパタと広がるような3Dアニメーションを持つダイアログです。
紙や手紙を意識したクリーンな白背景のデザイン。表示される際に `perspective` と `rotateX` を用いて、上から下に折り紙がパタパタと展開されるような3Dフォールドアニメーションを実装しています。
実装コード
HTML
<button id="dialog-btn-28">Paper Fold<br>Dialog</button>
<div id="dialog-28" class="dialog">
<div class="dialog-content-28">
<div class="paper-header">
<span>Paper Fold Dialog</span>
</div>
<div class="paper-body">
<p>紙がパタパタと広がるような3Dアニメーションを持つダイアログです。</p>
</div>
<div class="paper-footer">
<button class="close-btn-28">Discard</button>
<button class="close-btn-28 primary">Save</button>
</div>
</div>
</div>
CSS
#dialog-btn-28 {
background-color: #fff;
color: #333;
border: 1px solid #ddd;
padding: 12px 24px;
border-radius: 2px;
cursor: pointer;
font-size: 16px;
font-weight: 500;
min-width: 200px;
min-height: 60px;
display: block;
margin: 0 auto;
text-align: center;
box-shadow: 2px 4px 10px rgba(0,0,0,0.05);
transition: all 0.3s;
position: relative;
overflow: hidden;
}
#dialog-btn-28::after {
content: '';
position: absolute;
bottom: 0; right: 0;
width: 0; height: 0;
border-style: solid;
border-width: 0 0 15px 15px;
border-color: transparent transparent #ccc #eee;
transition: all 0.3s;
}
#dialog-btn-28:hover {
box-shadow: 2px 6px 15px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
#dialog-btn-28:hover::after {
border-width: 0 0 20px 20px;
}
#dialog-28 {
display: none;
position: fixed;
z-index: 2147483647;
left: 0; top: 0; width: 100%; height: 100%;
background-color: rgba(200, 200, 200, 0.6);
perspective: 1000px;
animation: fadeIn-28 0.3s;
}
.dialog-content-28 {
background: #fff;
width: 80%;
max-width: 450px;
margin: 10% auto;
position: relative;
padding: 40px;
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
transform-origin: top center;
animation: paperFoldOut-28 0.6s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}
/* 紙の折り目エフェクト(簡略化) */
.dialog-content-28::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.02) 0%, rgba(255,255,255,0) 10%, rgba(255,255,255,0) 90%, rgba(0,0,0,0.02) 100%);
pointer-events: none;
}
.paper-header {
margin-bottom: 25px;
border-bottom: 1px dashed #ccc;
padding-bottom: 15px;
}
.paper-header span {
font-size: 22px;
font-weight: 600;
color: #444;
font-family: 'Georgia', serif;
}
.paper-body p {
font-size: 15px;
line-height: 1.8;
margin-bottom: 30px;
color: #555;
}
.paper-footer {
display: flex;
justify-content: flex-end;
gap: 15px;
padding-top: 20px;
border-top: 1px dotted #e0e0e0;
}
.close-btn-28 {
background: transparent;
color: #666;
border: none;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
transition: color 0.2s;
}
.close-btn-28.primary {
background: #f0f0f0;
color: #333;
border-radius: 2px;
}
.close-btn-28:hover {
color: #000;
}
.close-btn-28.primary:hover {
background: #e4e4e4;
}
@keyframes fadeIn-28 {
from { opacity: 0; } to { opacity: 1; }
}
@keyframes paperFoldOut-28 {
0% { transform: rotateX(-90deg) scaleY(0); opacity: 0; }
50% { transform: rotateX(10deg) scaleY(1.1); }
100% { transform: rotateX(0deg) scaleY(1); opacity: 1; }
}
@media (max-width: 768px) {
.dialog-content-28 { width: 90%; padding: 25px; }
}
JS
(function () {
var btn = document.getElementById('dialog-btn-28');
var dialog = document.getElementById('dialog-28');
var closeBtns = dialog.querySelectorAll('.close-btn-28');
if (!btn || !dialog) return;
function openDialog() {
dialog.style.display = 'block';
document.body.style.overflow = 'hidden';
}
function closeDialog() {
dialog.style.display = 'none';
document.body.style.overflow = 'auto';
}
btn.addEventListener('click', openDialog);
closeBtns.forEach(function(b) { b.addEventListener('click', closeDialog); });
dialog.addEventListener('click', function (e) {
if (e.target === dialog) {
closeDialog();
}
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && dialog.style.display === 'block') {
closeDialog();
}
});
})();