mirror of
https://github.com/iqijun/obsidian-image-share.git
synced 2026-07-22 05:43:50 +00:00
modal resize
This commit is contained in:
parent
04a85d8874
commit
fbb7927a74
3 changed files with 139 additions and 41 deletions
30
main.css
30
main.css
File diff suppressed because one or more lines are too long
118
main.ts
118
main.ts
|
|
@ -28,6 +28,10 @@ class ImageGenerator {
|
|||
tempDiv.style.padding = '24px';
|
||||
tempDiv.style.boxSizing = 'border-box';
|
||||
tempDiv.style.wordBreak = 'break-word';
|
||||
// 添加文本换行处理,确保内容不会溢出
|
||||
tempDiv.style.overflowWrap = 'break-word';
|
||||
tempDiv.style.wordWrap = 'break-word';
|
||||
tempDiv.style.hyphens = 'auto';
|
||||
// tempDiv.style.fontSize = '15px';
|
||||
// tempDiv.style.lineHeight = '1.5';
|
||||
// tempDiv.style.whiteSpace = 'pre-wrap';
|
||||
|
|
@ -287,7 +291,7 @@ class ImageGenerator {
|
|||
width: this.currentTemplate.width,
|
||||
height: finalHeight,
|
||||
backgroundColor: this.currentTemplate.id === 'dark' ? '#2d3436' : '#e8ecf9',
|
||||
scale: 3, // 增加到3提高清晰度
|
||||
scale: window.devicePixelRatio * 2, // 根据设备像素比自动调整清晰度
|
||||
windowWidth: this.currentTemplate.width,
|
||||
windowHeight: finalHeight,
|
||||
logging: false, // 减少日志输出
|
||||
|
|
@ -367,10 +371,39 @@ class TextPreviewModal extends Modal {
|
|||
contentEl.empty();
|
||||
contentEl.addClass('image-share-modal');
|
||||
|
||||
// 根据当前模板宽度设置弹出框宽度,加上一些边距
|
||||
const modalPadding = 48; // 左右各24px的内边距
|
||||
const initialWidth = this.imageGenerator.getCurrentTemplate().width + modalPadding;
|
||||
contentEl.style.width = `${initialWidth}px`;
|
||||
// 获取屏幕大小
|
||||
const windowWidth = window.innerWidth;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
// 创建一个调整模态框大小的函数
|
||||
const adjustModalSize = (width: number, height: number, padding = 80) => {
|
||||
// 计算内容尺寸(加上内边距)
|
||||
const contentWidth = width + padding;
|
||||
const contentHeight = height + padding + 150; // 额外添加150px用于控件和标题
|
||||
|
||||
// 应用适当的限制
|
||||
const maxWidth = Math.min(windowWidth * 0.6, 2000); // 最大宽度为窗口的90%或2000px
|
||||
const maxHeight = Math.min(windowHeight * 0.9, 2000); // 最大高度为窗口的90%或2000px
|
||||
|
||||
// 确保尺寸在合理范围内
|
||||
const finalWidth = Math.min(Math.max(contentWidth, 500), maxWidth);
|
||||
const finalHeight = Math.min(Math.max(contentHeight, 400), maxHeight);
|
||||
|
||||
// 应用到模态框和父模态框
|
||||
const modalElement = contentEl.parentElement as HTMLElement;
|
||||
if (modalElement && modalElement.classList.contains('modal')) {
|
||||
modalElement.style.width = `${finalWidth}px`;
|
||||
modalElement.style.height = `${finalHeight}px`;
|
||||
}
|
||||
|
||||
// 也应用到当前元素以保持一致性
|
||||
contentEl.style.width = `${finalWidth}px`;
|
||||
};
|
||||
|
||||
// 计算合适的初始模态框大小
|
||||
const currentTemplate = this.imageGenerator.getCurrentTemplate();
|
||||
// 初始设置 - 将在渲染完成后更新
|
||||
adjustModalSize(currentTemplate.width, 600);
|
||||
|
||||
const resizableContainer = contentEl.createDiv({ cls: 'resizable-container' });
|
||||
|
||||
|
|
@ -399,12 +432,26 @@ class TextPreviewModal extends Modal {
|
|||
templateButton.addClass('active');
|
||||
await this.imageGenerator.setTemplate(template.id);
|
||||
canvasContainer.empty();
|
||||
canvasContainer.appendChild(this.imageGenerator.getCanvas());
|
||||
const newCanvas = this.imageGenerator.getCanvas();
|
||||
canvasContainer.appendChild(newCanvas);
|
||||
|
||||
// 当模板变更时更新弹出框宽度
|
||||
const modalPadding = 48; // 与初始化时相同的边距
|
||||
const newWidth = this.imageGenerator.getCurrentTemplate().width + modalPadding;
|
||||
contentEl.style.width = `${newWidth}px`;
|
||||
// 当模板变更时更新弹出框尺寸
|
||||
adjustModalSize(newCanvas.width, newCanvas.height);
|
||||
|
||||
// 重新计算并应用适当的缩放比例
|
||||
const newCanvasWidth = newCanvas.width;
|
||||
const newContainerWidth = canvasContainer.clientWidth - 16; // 减去内边距
|
||||
|
||||
if (newCanvasWidth > newContainerWidth) {
|
||||
// 计算新的缩放比例
|
||||
zoomLevel = Math.floor((newContainerWidth / newCanvasWidth * 100) / 10) * 10;
|
||||
zoomLevel = Math.max(50, zoomLevel);
|
||||
updateZoom(zoomLevel);
|
||||
} else {
|
||||
// 如果画布适合容器,重置为100%
|
||||
zoomLevel = 100;
|
||||
updateZoom(zoomLevel);
|
||||
}
|
||||
};
|
||||
if (template.id === 'default') {
|
||||
templateButton.addClass('active');
|
||||
|
|
@ -432,34 +479,53 @@ class TextPreviewModal extends Modal {
|
|||
zoomInBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>';
|
||||
|
||||
// 缩放逻辑
|
||||
// 创建一个缩放更新函数
|
||||
const updateZoom = (level: number) => {
|
||||
const canvas = canvasContainer.querySelector('canvas');
|
||||
if (canvas) {
|
||||
canvas.style.width = `${level}%`;
|
||||
zoomText.textContent = `${level}%`;
|
||||
}
|
||||
};
|
||||
|
||||
// 等待初始画布渲染完成
|
||||
await this.imageGenerator.updateCanvas();
|
||||
const canvas = this.imageGenerator.getCanvas();
|
||||
canvasContainer.appendChild(canvas);
|
||||
|
||||
// 更新模态框大小以适应画布
|
||||
adjustModalSize(canvas.width, canvas.height);
|
||||
|
||||
// 自动计算初始缩放比例
|
||||
let zoomLevel = 100;
|
||||
const canvasWidth = canvas.width;
|
||||
const containerWidth = canvasContainer.clientWidth - 16; // 减去内边距
|
||||
|
||||
// 如果画布宽度大于容器宽度,则自动适应
|
||||
if (canvasWidth > containerWidth) {
|
||||
// 计算适合的缩放比例,乘以100转为百分比,再向下取整到最接近的10
|
||||
zoomLevel = Math.floor((containerWidth / canvasWidth * 100) / 10) * 10;
|
||||
// 确保缩放比例不低于50%
|
||||
zoomLevel = Math.max(50, zoomLevel);
|
||||
|
||||
// 应用初始缩放
|
||||
updateZoom(zoomLevel);
|
||||
}
|
||||
|
||||
zoomOutBtn.addEventListener('click', () => {
|
||||
if (zoomLevel > 50) {
|
||||
zoomLevel -= 10;
|
||||
updateZoom();
|
||||
updateZoom(zoomLevel);
|
||||
}
|
||||
});
|
||||
|
||||
zoomInBtn.addEventListener('click', () => {
|
||||
if (zoomLevel < 200) {
|
||||
zoomLevel += 10;
|
||||
updateZoom();
|
||||
updateZoom(zoomLevel);
|
||||
}
|
||||
});
|
||||
|
||||
const updateZoom = () => {
|
||||
const canvas = canvasContainer.querySelector('canvas');
|
||||
if (canvas) {
|
||||
canvas.style.width = `${zoomLevel}%`;
|
||||
zoomText.textContent = `${zoomLevel}%`;
|
||||
}
|
||||
};
|
||||
|
||||
// 等待初始画布渲染完成
|
||||
await this.imageGenerator.updateCanvas();
|
||||
canvasContainer.appendChild(this.imageGenerator.getCanvas());
|
||||
|
||||
// 创建一个容器来包裹所有内容
|
||||
// const contentContainer = this.contentEl.createDiv({
|
||||
// cls: 'text-preview-container'
|
||||
|
|
@ -524,13 +590,13 @@ const SHARE_TEMPLATES: ShareTemplate[] = [
|
|||
{
|
||||
id: 'default',
|
||||
name: '默认模板',
|
||||
width: 400,
|
||||
width: 800,
|
||||
render: async () => {}
|
||||
},
|
||||
{
|
||||
id: 'dark',
|
||||
name: '深色模板',
|
||||
width: 400,
|
||||
width: 800,
|
||||
render: async () => {}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
32
styles.css
32
styles.css
|
|
@ -6,13 +6,25 @@ available in the app when your plugin is enabled.
|
|||
If your plugin does not need CSS, delete this file.
|
||||
|
||||
*/
|
||||
.modal {
|
||||
/* 移除固定宽高 */
|
||||
/* width: 1500px; */
|
||||
/* height: 300px; */
|
||||
max-width: 90vw; /* 限制最大宽度为视窗宽度的90% */
|
||||
max-height: 90vh; /* 限制最大高度为视窗高度的90% */
|
||||
display: flex; /* 使用flex布局使内容居中 */
|
||||
flex-direction: column;
|
||||
min-width: 400px; /* 设置最小宽度 */
|
||||
transition: width 0.3s ease, height 0.3s ease; /* 平滑过渡效果 */
|
||||
}
|
||||
|
||||
|
||||
.image-share-modal {
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
max-width: 2000px;
|
||||
max-height: 2000px;
|
||||
/* 移除固定宽度,以便通过JavaScript动态设置 */
|
||||
/* width: 1000px; */
|
||||
transition: width 0.3s ease;
|
||||
transition: width 0.3s ease, height 0.3s ease;
|
||||
}
|
||||
|
||||
.image-share-modal .resizable-container {
|
||||
|
|
@ -67,7 +79,7 @@ If your plugin does not need CSS, delete this file.
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 2px;
|
||||
padding: 8px;
|
||||
background: var(--background-secondary);
|
||||
border-radius: 8px;
|
||||
min-height: 200px;
|
||||
|
|
@ -75,6 +87,9 @@ If your plugin does not need CSS, delete this file.
|
|||
width: 100%;
|
||||
overflow: auto;
|
||||
max-height: 70vh;
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.image-share-modal h2 {
|
||||
|
|
@ -87,9 +102,9 @@ If your plugin does not need CSS, delete this file.
|
|||
}
|
||||
|
||||
.image-share-modal .download-button {
|
||||
position: fixed;
|
||||
right: 30%;
|
||||
bottom: 40%;
|
||||
position: absolute; /* 使用absolute而不是fixed */
|
||||
right: 20px; /* 距右边20px */
|
||||
top: 20px; /* 距上边20px */
|
||||
background: var(--interactive-accent);
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
|
|
@ -125,6 +140,9 @@ If your plugin does not need CSS, delete this file.
|
|||
image-rendering: crisp-edges;
|
||||
transform: translateZ(0);
|
||||
backface-visibility: hidden;
|
||||
min-width: auto;
|
||||
min-height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.image-share-modal .template-selector {
|
||||
|
|
|
|||
Loading…
Reference in a new issue