Files
invitation-maker/css/style.css

545 lines
9.8 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
background: #f5f5f5;
overflow: hidden;
-webkit-user-select: none;
user-select: none;
}
.app {
display: flex;
flex-direction: column;
height: 100vh;
}
/* 顶部工具栏 */
.toolbar {
display: flex;
justify-content: center;
gap: 8px;
padding: 12px 16px;
background: #fff;
border-bottom: 1px solid #e0e0e0;
flex-shrink: 0;
}
.btn {
min-width: 72px;
height: 40px;
padding: 0 12px;
font-size: 15px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
color: #333;
cursor: pointer;
transition: all 0.2s;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
}
.btn:active {
background: #f0f0f0;
}
.btn-primary {
min-width: 100px;
background: #4a90e2;
color: #fff;
border-color: #4a90e2;
}
.btn-primary:active {
background: #3a7bc8;
}
/* 文本输入框删除按钮 */
.text-input .text-delete-btn {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
background: #e74c3c;
color: #fff;
border: none;
border-radius: 50%;
font-size: 12px;
line-height: 20px;
text-align: center;
cursor: pointer;
display: none;
z-index: 10;
}
.text-input.selected:not(.editing) .text-delete-btn {
display: block;
}
/* 编辑器工具栏(文本/图片共用) */
.editor-toolbar {
position: absolute;
top: 65px;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
padding: 8px 12px;
background: #fff;
border-bottom: 1px solid #e0e0e0;
flex-shrink: 0;
visibility: hidden;
opacity: 0;
transition: opacity 0.2s;
z-index: 100;
}
/* 编辑模式:粘在视口顶部始终可见 */
.editor-toolbar.editing-mode {
position: fixed;
top: 0;
border-bottom: 1px solid #e0e0e0;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
z-index: 10000;
}
.editor-toolbar.active {
visibility: visible;
opacity: 1;
}
.toolbar-group {
display: none;
justify-content: center;
align-items: center;
gap: 4px;
}
.toolbar-group.active {
display: flex;
}
.toolbar-btn {
width: 36px;
height: 36px;
font-size: 16px;
font-weight: bold;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
color: #333;
cursor: pointer;
transition: all 0.2s;
}
.toolbar-btn:active {
background: #f0f0f0;
}
.toolbar-btn.active {
background: #4a90e2;
color: #fff;
border-color: #4a90e2;
}
.toolbar-btn.italic {
font-style: italic;
}
.toolbar-divider {
width: 1px;
height: 24px;
background: #ddd;
margin: 0 2px;
}
.toolbar-label {
display: flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: #666;
}
.toolbar-label select {
padding: 4px 6px;
font-size: 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: #fff;
cursor: pointer;
}
.opacity-slider {
width: 100px;
height: 32px;
cursor: pointer;
accent-color: #4a90e2;
margin: 0;
}
.scale-slider {
width: 100px;
height: 32px;
cursor: pointer;
accent-color: #4a90e2;
margin: 0;
}
/* 字号滚轮选择器 */
.roller-picker {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
min-width: 65px;
height: 36px;
}
.roller-arrow {
font-size: 10px;
color: #666;
cursor: pointer;
padding: 2px 4px;
user-select: none;
transition: color 0.2s;
}
.roller-arrow:hover {
color: #4a90e2;
}
.roller-value {
font-size: 14px;
min-width: 24px;
text-align: center;
color: #333;
}
#fontPicker {
min-width: 55px;
}
.toolbar-label input[type="color"] {
width: 36px;
height: 36px;
padding: 2px;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
}
/* 图片展示区 */
.canvas-area {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
overflow: auto;
position: relative;
}
/* 空提示 - 移到预览白板中 */
.empty-tip {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #999;
font-size: 14px;
text-align: center;
pointer-events: none;
z-index: 5;
}
/* 预览区域固定 3:5 比例,打开即显示空白面板 */
.preview {
overflow: hidden;
}
.image-container {
display: flex;
position: relative;
width: 100%;
max-width: 360px;
aspect-ratio: 960 / 1361;
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
background: #fff;
overflow: hidden;
touch-action: pan-x;
margin: 0 auto;
contain: layout style paint;
}
.image-container.empty {
background: #f0f0f0;
border: 2px dashed #ddd;
}
/* 背景图层 - 用于滑动调整位置,溢出隐藏 */
.preview-bg-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
/* 层叠图层 - 位于背景图之上、文字之下、提示文字之上 */
.overlay-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 6;
}
.overlay-layer .overlay-image {
position: absolute;
pointer-events: auto;
cursor: move;
touch-action: none;
}
.overlay-layer .overlay-image.selected {
outline: 2px dashed rgba(74, 144, 226, 0.8);
outline-offset: 2px;
}
.overlay-layer .overlay-image .resize-handle {
display: none;
}
.overlay-layer .overlay-image.selected .resize-handle {
display: block;
}
.overlay-layer .overlay-image .delete-btn {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
background: #e74c3c;
color: #fff;
border: none;
border-radius: 50%;
font-size: 12px;
line-height: 20px;
text-align: center;
cursor: pointer;
display: none;
z-index: 10;
}
.overlay-layer .overlay-image.selected .delete-btn {
display: block;
}
/* 输入框图层 - 与背景图层隔离 */
.preview-input-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 7;
}
/* 输入框可交互 */
.preview-input-layer .text-input {
pointer-events: auto;
z-index: 8;
}
/* 背景图 - 保持比例,可滑动调整位置 */
#bgImage {
display: block;
position: absolute;
max-width: none;
-webkit-user-drag: none;
}
#bgImage[src=""] {
display: none;
}
/* 文字输入框 - 透明无边框设计,黑色微软雅黑16px */
.text-input {
position: absolute;
min-width: 80px;
min-height: 32px;
padding: 0;
font-size: 16px;
color: #000;
font-family: "Microsoft YaHei", "微软雅黑", sans-serif;
background: transparent;
outline: 2px solid transparent;
border-radius: 4px;
cursor: grab;
white-space: nowrap;
line-height: 1.4;
-webkit-user-select: none;
user-select: none;
transition: outline-color 0.2s;
z-index: 10;
overflow: visible;
max-width: none;
box-sizing: border-box;
}
/* 选中状态(单击/长按) - 仅显示虚线轮廓 */
.text-input.selected {
outline: 2px dashed rgba(74, 144, 226, 0.6);
cursor: grab;
}
/* 空输入框显示 placeholder */
.text-input.show-placeholder::before {
content: attr(data-placeholder);
color: #999;
pointer-events: none;
}
/* 编辑状态(双击) - 显示实线轮廓 */
.text-input.editing {
outline: 2px solid #4a90e2;
background: rgba(255,255,255,0.1);
cursor: text;
-webkit-user-select: text;
user-select: text;
-webkit-touch-callout: default;
pointer-events: auto;
}
/* 拖拽状态 */
.text-input.dragging {
opacity: 0.8;
cursor: grabbing;
}
/* 隐藏元素 */
.hidden {
display: none !important;
}
/* 隐藏空提示 */
.empty-tip.hidden {
display: none;
}
/* 长按提示 */
.long-press-tip {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
padding: 8px 16px;
background: rgba(0,0,0,0.7);
color: #fff;
font-size: 12px;
border-radius: 16px;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
z-index: 1000;
}
.long-press-tip.show {
opacity: 1;
}
/* 右键菜单 */
.context-menu {
position: fixed;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
padding: 4px 0;
z-index: 1000;
min-width: 140px;
}
.context-menu-item {
padding: 10px 16px;
font-size: 14px;
color: #333;
cursor: pointer;
transition: background 0.2s;
}
.context-menu-item:hover {
background: #f5f5f5;
}
.context-menu-item:active {
background: #e8e8e8;
}
/* 拖拽辅助线 */
.guide-line {
position: absolute;
pointer-events: none;
z-index: 1000;
display: none;
}
.guide-horizontal {
left: 0;
right: 0;
height: 1px;
background: #e74c3c;
box-shadow: 0 0 4px rgba(231, 76, 60, 0.5);
}
.guide-vertical {
top: 0;
bottom: 0;
width: 1px;
background: #e74c3c;
box-shadow: 0 0 4px rgba(231, 76, 60, 0.5);
}
.guide-line.visible {
display: block;
}
/* 1px 网格线 */
.grid-lines {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
z-index: 5;
display: none;
background-image:
linear-gradient(to right, rgba(0, 0, 0, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
background-size: 10px 10px;
}
.grid-lines.visible {
display: block;
}