fix(YourPuzzleComponent): 修复背景图未显示完全的问题
- 为 img 标签添加 object-fit: contain 样式,确保图片按比例显示 - 添加图片预加载功能,提高组件加载性能 - 增加图片加载失败的错误处理机制 - 优化滑块样式,设置背景图片不重复并居中显示 - 调整滑块位置,解决显示不完整的问题
This commit is contained in:
parent
85523e8321
commit
bfd60167fa
@ -2,13 +2,13 @@
|
|||||||
<div class="puzzle-container">
|
<div class="puzzle-container">
|
||||||
<div class="puzzle-box" :style="{ height: boxHeight + 'px' }">
|
<div class="puzzle-box" :style="{ height: boxHeight + 'px' }">
|
||||||
<!-- 背景图 -->
|
<!-- 背景图 -->
|
||||||
<img :src="bgImageUrl" class="bg-image" ref="bgImage" @load="onImageLoad">
|
<img :src="bgImageUrl" class="bg-image" ref="bgImage" @load="onImageLoad" @error="handleImageError">
|
||||||
<!-- 滑块 -->
|
<!-- 滑块 -->
|
||||||
<div
|
<div
|
||||||
class="slider-block"
|
class="slider-block"
|
||||||
:style="{
|
:style="{
|
||||||
backgroundImage: `url(${sliderImageUrl})`,
|
backgroundImage: `url(${sliderImageUrl})`,
|
||||||
top: `${blockY}px`,
|
top: `${blockY-2}px`,
|
||||||
left: `${moveX}px`,
|
left: `${moveX}px`,
|
||||||
visibility: loaded ? 'visible' : 'hidden'
|
visibility: loaded ? 'visible' : 'hidden'
|
||||||
}"
|
}"
|
||||||
@ -81,7 +81,13 @@ const bgImage = ref(null)
|
|||||||
// 方法
|
// 方法
|
||||||
const onImageLoad = () => {
|
const onImageLoad = () => {
|
||||||
if (bgImage.value) {
|
if (bgImage.value) {
|
||||||
|
try {
|
||||||
const img = bgImage.value
|
const img = bgImage.value
|
||||||
|
// 确保图片已经完全加载
|
||||||
|
if (!img.complete) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const scale = img.width / img.naturalWidth // 计算图片缩放比例
|
const scale = img.width / img.naturalWidth // 计算图片缩放比例
|
||||||
boxHeight.value = img.height
|
boxHeight.value = img.height
|
||||||
|
|
||||||
@ -91,7 +97,25 @@ const onImageLoad = () => {
|
|||||||
|
|
||||||
maxMoveX.value = img.width - blockSize // 使用实际显示的滑块大小计算最大移动距离
|
maxMoveX.value = img.width - blockSize // 使用实际显示的滑块大小计算最大移动距离
|
||||||
loaded.value = true
|
loaded.value = true
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Image load error:', error)
|
||||||
|
// 设置默认值以确保组件仍然可用
|
||||||
|
const defaultBlockSize = 50
|
||||||
|
document.documentElement.style.setProperty('--block-size', defaultBlockSize + 'px')
|
||||||
|
maxMoveX.value = 320 - defaultBlockSize // 使用默认容器宽度
|
||||||
|
loaded.value = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加图片错误处理
|
||||||
|
const handleImageError = () => {
|
||||||
|
console.error('Image failed to load')
|
||||||
|
// 设置默认值以确保组件仍然可用
|
||||||
|
const defaultBlockSize = 50
|
||||||
|
document.documentElement.style.setProperty('--block-size', defaultBlockSize + 'px')
|
||||||
|
maxMoveX.value = 320 - defaultBlockSize
|
||||||
|
loaded.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMouseDown = (event) => {
|
const handleMouseDown = (event) => {
|
||||||
@ -160,8 +184,24 @@ const handleTouchEnd = () => {
|
|||||||
handleMouseUp()
|
handleMouseUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预加载图片
|
||||||
|
const preloadImages = () => {
|
||||||
|
const bgImg = new Image()
|
||||||
|
const sliderImg = new Image()
|
||||||
|
|
||||||
|
bgImg.onload = () => {
|
||||||
|
if (bgImage.value) {
|
||||||
|
onImageLoad()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bgImg.src = props.bgImageUrl
|
||||||
|
sliderImg.src = props.sliderImageUrl
|
||||||
|
}
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
preloadImages()
|
||||||
window.addEventListener('mousemove', handleMouseMove)
|
window.addEventListener('mousemove', handleMouseMove)
|
||||||
window.addEventListener('mouseup', handleMouseUp)
|
window.addEventListener('mouseup', handleMouseUp)
|
||||||
window.addEventListener('touchmove', handleTouchMove)
|
window.addEventListener('touchmove', handleTouchMove)
|
||||||
@ -210,6 +250,10 @@ onBeforeUnmount(() => {
|
|||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
object-fit: contain;
|
||||||
|
max-width: 100%;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-block {
|
.slider-block {
|
||||||
@ -217,6 +261,8 @@ onBeforeUnmount(() => {
|
|||||||
width: var(--block-size);
|
width: var(--block-size);
|
||||||
height: var(--block-size);
|
height: var(--block-size);
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -224,6 +270,8 @@ onBeforeUnmount(() => {
|
|||||||
will-change: transform;
|
will-change: transform;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-container {
|
.slider-container {
|
||||||
|
Loading…
Reference in New Issue
Block a user