You've already forked SmartisanNote.Remake
优化了编辑器中的图片显示尺寸
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="code-fun-flex-row code-fun-justify-between mt-17-5">
|
<div class="code-fun-flex-row code-fun-justify-between mt-17-5">
|
||||||
<!-- 便签正文第一行 -->
|
<!-- 便签正文第一行 -->
|
||||||
<span class="font_3 text_19">{{ content }}</span>
|
<span class="font_3 text_19">{{ displayContent }}</span>
|
||||||
<!-- 便签中是否存在图片 -->
|
<!-- 便签中是否存在图片 -->
|
||||||
<img v-if="hasImage" class="image_28" src="/assets/icons/drawable-xxhdpi/list_item_image_icon.png" />
|
<img v-if="hasImage" class="image_28" src="/assets/icons/drawable-xxhdpi/list_item_image_icon.png" />
|
||||||
</div>
|
</div>
|
||||||
@@ -81,6 +81,23 @@ const formattedDate = computed(() => {
|
|||||||
return props.date
|
return props.date
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 处理显示内容,过滤HTML标签并只显示第一行
|
||||||
|
const displayContent = computed(() => {
|
||||||
|
console.log('NoteItem content:', props.content)
|
||||||
|
// 过滤HTML标签
|
||||||
|
let text = props.content.replace(/<[^>]*>/g, '')
|
||||||
|
console.log('NoteItem text without HTML:', text)
|
||||||
|
|
||||||
|
// 处理换行符,统一为\n
|
||||||
|
text = text.replace(/\\n/g, '\n')
|
||||||
|
|
||||||
|
// 按换行符分割并获取第一行
|
||||||
|
const lines = text.split('\n')
|
||||||
|
|
||||||
|
// 返回第一行内容,如果为空则显示默认文本
|
||||||
|
return lines[0]?.trim() || '无内容'
|
||||||
|
})
|
||||||
|
|
||||||
// 滑动阈值(删除按钮宽度)
|
// 滑动阈值(删除按钮宽度)
|
||||||
const SLIDE_THRESHOLD = 64 // 4rem 转换为 px
|
const SLIDE_THRESHOLD = 64 // 4rem 转换为 px
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ onMounted(() => {
|
|||||||
editorRef.value.innerHTML = props.modelValue
|
editorRef.value.innerHTML = props.modelValue
|
||||||
content.value = props.modelValue
|
content.value = props.modelValue
|
||||||
console.log('Initial content set successfully')
|
console.log('Initial content set successfully')
|
||||||
|
// 调整已有图片的高度
|
||||||
|
adjustExistingImages()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to set initial content:', error)
|
console.error('Failed to set initial content:', error)
|
||||||
}
|
}
|
||||||
@@ -91,8 +93,20 @@ const tools = ref([
|
|||||||
// 处理输入事件
|
// 处理输入事件
|
||||||
const handleInput = () => {
|
const handleInput = () => {
|
||||||
if (editorRef.value) {
|
if (editorRef.value) {
|
||||||
content.value = editorRef.value.innerHTML
|
// 获取编辑器内容
|
||||||
console.log('Input event handled, content:', content.value)
|
let innerHTML = editorRef.value.innerHTML
|
||||||
|
|
||||||
|
// 处理换行符,确保在段落之间有明确的分隔
|
||||||
|
innerHTML = innerHTML.replace(/<\/p><p>/g, '</p>\n<p>')
|
||||||
|
// 处理div标签换行
|
||||||
|
innerHTML = innerHTML.replace(/<\/div><div>/g, '</div>\n<div>')
|
||||||
|
// 处理br标签换行
|
||||||
|
innerHTML = innerHTML.replace(/<br>/g, '\n')
|
||||||
|
innerHTML = innerHTML.replace(/<br\/>/g, '\n')
|
||||||
|
// 处理div标签内的换行
|
||||||
|
innerHTML = innerHTML.replace(/<div>/g, '\n<div>')
|
||||||
|
|
||||||
|
content.value = innerHTML
|
||||||
emit('update:modelValue', content.value)
|
emit('update:modelValue', content.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,10 +561,42 @@ const insertImage = () => {
|
|||||||
const img = document.createElement('img')
|
const img = document.createElement('img')
|
||||||
img.src = imageDataUrl
|
img.src = imageDataUrl
|
||||||
img.className = 'editor-image'
|
img.className = 'editor-image'
|
||||||
img.style.maxWidth = '100%'
|
|
||||||
img.style.height = 'auto'
|
// 创建一个临时图片来获取原始尺寸
|
||||||
img.style.display = 'block'
|
const tempImg = new Image()
|
||||||
img.style.margin = '0 auto'
|
tempImg.onload = function () {
|
||||||
|
// 获取CSS变量
|
||||||
|
const editorFontSize = getComputedStyle(document.documentElement).getPropertyValue('--editor-font-size').trim() || '16px'
|
||||||
|
const editorLineHeight = getComputedStyle(document.documentElement).getPropertyValue('--editor-line-height').trim() || '1.6'
|
||||||
|
const fontSize = parseInt(editorFontSize)
|
||||||
|
const lineHeight = parseFloat(editorLineHeight)
|
||||||
|
|
||||||
|
// 计算行高
|
||||||
|
const computedLineHeight = fontSize * lineHeight
|
||||||
|
|
||||||
|
// 获取编辑器的宽度(减去一些内边距)
|
||||||
|
const editorWidth = editorRef.value.offsetWidth - 20 // 20px为左右内边距
|
||||||
|
|
||||||
|
// 按宽度撑满计算调整后的尺寸
|
||||||
|
const originalHeight = tempImg.height
|
||||||
|
const originalWidth = tempImg.width
|
||||||
|
const scaleRatio = editorWidth / originalWidth
|
||||||
|
const scaledHeight = originalHeight * scaleRatio
|
||||||
|
|
||||||
|
// 计算调整后的高度,使其为行高的整数倍
|
||||||
|
const scaleFactor = Math.max(1, Math.round(scaledHeight / computedLineHeight))
|
||||||
|
const adjustedHeight = scaleFactor * computedLineHeight
|
||||||
|
|
||||||
|
// 按比例调整宽度
|
||||||
|
const adjustedWidth = (originalWidth * adjustedHeight) / originalHeight
|
||||||
|
|
||||||
|
img.style.height = `${adjustedHeight}px`
|
||||||
|
img.style.width = `${adjustedWidth}px`
|
||||||
|
|
||||||
|
// 确保图片与基准线对齐
|
||||||
|
img.style.verticalAlign = 'top'
|
||||||
|
}
|
||||||
|
tempImg.src = imageDataUrl
|
||||||
|
|
||||||
// 插入图片到当前光标位置
|
// 插入图片到当前光标位置
|
||||||
range.insertNode(img)
|
range.insertNode(img)
|
||||||
@@ -731,6 +777,59 @@ const handleToolbarFocusOut = () => {
|
|||||||
}, 200) // 增加延迟时间,确保有足够时间处理点击事件
|
}, 200) // 增加延迟时间,确保有足够时间处理点击事件
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 调整已有图片的高度
|
||||||
|
const adjustExistingImages = () => {
|
||||||
|
// 等待DOM更新完成
|
||||||
|
setTimeout(() => {
|
||||||
|
if (editorRef.value) {
|
||||||
|
const images = editorRef.value.querySelectorAll('img.editor-image')
|
||||||
|
images.forEach(img => {
|
||||||
|
// 只处理还没有调整过高度的图片
|
||||||
|
if (!img.dataset.heightAdjusted) {
|
||||||
|
// 创建一个临时图片来获取原始尺寸
|
||||||
|
const tempImg = new Image()
|
||||||
|
tempImg.onload = function () {
|
||||||
|
// 获取CSS变量
|
||||||
|
const editorFontSize = getComputedStyle(document.documentElement).getPropertyValue('--editor-font-size').trim() || '16px'
|
||||||
|
const editorLineHeight = getComputedStyle(document.documentElement).getPropertyValue('--editor-line-height').trim() || '1.6'
|
||||||
|
const fontSize = parseInt(editorFontSize)
|
||||||
|
const lineHeight = parseFloat(editorLineHeight)
|
||||||
|
|
||||||
|
// 计算行高
|
||||||
|
const computedLineHeight = fontSize * lineHeight
|
||||||
|
|
||||||
|
// 获取编辑器的宽度(减去一些内边距)
|
||||||
|
const editorWidth = editorRef.value.offsetWidth - 20 // 20px为左右内边距
|
||||||
|
|
||||||
|
// 按宽度撑满计算调整后的尺寸
|
||||||
|
const originalHeight = tempImg.height
|
||||||
|
const originalWidth = tempImg.width
|
||||||
|
const scaleRatio = editorWidth / originalWidth
|
||||||
|
const scaledHeight = originalHeight * scaleRatio
|
||||||
|
|
||||||
|
// 计算调整后的高度,使其为行高的整数倍
|
||||||
|
const scaleFactor = Math.max(1, Math.round(scaledHeight / computedLineHeight))
|
||||||
|
const adjustedHeight = scaleFactor * computedLineHeight
|
||||||
|
|
||||||
|
// 按比例调整宽度
|
||||||
|
const adjustedWidth = (originalWidth * adjustedHeight) / originalHeight
|
||||||
|
|
||||||
|
img.style.height = `${adjustedHeight}px`
|
||||||
|
img.style.width = `${adjustedWidth}px`
|
||||||
|
|
||||||
|
// 确保图片与基准线对齐
|
||||||
|
img.style.verticalAlign = 'top'
|
||||||
|
|
||||||
|
// 标记图片已调整过高度
|
||||||
|
img.dataset.heightAdjusted = 'true'
|
||||||
|
}
|
||||||
|
tempImg.src = img.src
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getContent: () => content.value,
|
getContent: () => content.value,
|
||||||
@@ -741,6 +840,8 @@ defineExpose({
|
|||||||
try {
|
try {
|
||||||
editorRef.value.innerHTML = content.value
|
editorRef.value.innerHTML = content.value
|
||||||
console.log('Content set successfully in editorRef')
|
console.log('Content set successfully in editorRef')
|
||||||
|
// 调整已有图片的高度
|
||||||
|
adjustExistingImages()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to set innerHTML:', error)
|
console.error('Failed to set innerHTML:', error)
|
||||||
// 备选方案:使用textContent
|
// 备选方案:使用textContent
|
||||||
@@ -759,6 +860,8 @@ defineExpose({
|
|||||||
try {
|
try {
|
||||||
editorRef.value.innerHTML = content.value
|
editorRef.value.innerHTML = content.value
|
||||||
console.log('Content set successfully after delay')
|
console.log('Content set successfully after delay')
|
||||||
|
// 调整已有图片的高度
|
||||||
|
adjustExistingImages()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to set innerHTML after delay:', error)
|
console.error('Failed to set innerHTML after delay:', error)
|
||||||
}
|
}
|
||||||
@@ -774,7 +877,7 @@ defineExpose({
|
|||||||
.editor-container {
|
.editor-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
min-height: 100%;
|
||||||
background-color: var(--background-card);
|
background-color: var(--background-card);
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
}
|
}
|
||||||
@@ -962,30 +1065,37 @@ defineExpose({
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.editor-content .editor-image) {
|
||||||
|
|
||||||
.editor-content img {
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: calc((var(--editor-line-height, 1.6) * 10) * 1px) auto;
|
||||||
|
object-fit: cover;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 10px solid white;
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.18);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 待办事项样式 */
|
/* 待办事项样式 */
|
||||||
:deep(.todo-container) {
|
:deep(.todo-container) {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: var(--editor-line-height, 1.6);
|
line-height: var(--editor-line-height, 1.6);
|
||||||
|
position: relative;
|
||||||
|
padding-left: calc(var(--editor-font-size, 16px) * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.todo-icon) {
|
:deep(.todo-icon) {
|
||||||
width: calc(var(--editor-font-size, 16px) * 2);
|
width: calc(var(--editor-font-size, 16px) * 1.5);
|
||||||
height: calc(var(--editor-font-size, 16px) * 2);
|
height: calc(var(--editor-font-size, 16px) * 1.5);
|
||||||
margin-right: 3px;
|
|
||||||
margin-top: 0;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.todo-content) {
|
:deep(.todo-content) {
|
||||||
|
|||||||
@@ -277,14 +277,14 @@ const setShowAlert = value => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rich-text-editor {
|
.rich-text-editor {
|
||||||
height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-info {
|
.header-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 1.5rem 16px 0.7rem 16px;
|
padding: 1rem 16px 0.7rem 16px;
|
||||||
background-color: var(--background-card);
|
background-color: var(--background-card);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user