fix(YourPuzzleComponent): 修复背景图未显示完全的问题

- 为 img 标签添加 object-fit: contain 样式,确保图片按比例显示
- 添加图片预加载功能,提高组件加载性能
- 增加图片加载失败的错误处理机制
- 优化滑块样式,设置背景图片不重复并居中显示
- 调整滑块位置,解决显示不完整的问题
This commit is contained in:
xingyy 2025-03-11 19:42:50 +08:00
parent 85523e8321
commit bfd60167fa

View File

@ -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 {