<!-- Generated by SpecStory -->

# Adjust Mask to Thumbnail Position (2025-05-27 00:16:31)

_**User**_

把这个遮罩大小和位置限定在和thumbnailRef image 的位置重合

---

_**Assistant**_

我需要先查看完整的 `ProgressiveImage.tsx` 文件来了解 `thumbnailRef` 的定义和使用情况，然后修改遮罩的位置和大小。

---

Read file: src/components/ui/photo-viewer/ProgressiveImage.tsx

---

Read file: src/components/ui/photo-viewer/ProgressiveImage.tsx

---

现在我了解了完整的代码结构。我需要修改加载指示器遮罩的位置和大小，使其与 `thumbnailRef` 图片的位置重合。为了实现这个功能，我需要：

1. 添加一个状态来跟踪缩略图的位置和大小
2. 使用 `ResizeObserver` 或类似方法来获取缩略图的实际渲染尺寸
3. 修改遮罩的样式，使其定位到缩略图的位置

---



---

现在我需要添加一个函数来计算缩略图的实际渲染位置和大小，并在加载指示器中使用这些信息：

---



---

现在我需要修改加载指示器遮罩，使其使用 `thumbnailBounds` 来定位到缩略图的位置：

---



---

现在我还需要添加一个 resize observer 来监听容器大小变化，以便在窗口大小改变时重新计算缩略图边界：

---



---

我需要将 `calculateThumbnailBounds` 函数移到 useEffect 之前，或者重新组织代码结构。让我修复这个问题：

---



---

让我重新读取文件来查看当前的状态：

---

Read file: src/components/ui/photo-viewer/ProgressiveImage.tsx

---

我看到 `calculateThumbnailBounds` 函数已经在正确的位置了，但是在 useEffect 中被调用时还没有定义。我需要将这个 useEffect 移到 `calculateThumbnailBounds` 函数定义之后：

---



---

现在我需要在 `calculateThumbnailBounds` 函数定义之后添加这个 useEffect：

---



---

现在让我检查一下修改后的代码是否正确工作。让我查看完整的加载指示器部分：

---

Read file: src/components/ui/photo-viewer/ProgressiveImage.tsx

---

完美！现在让我检查一下是否还有任何 linter 错误：

---

```bash
cd /Users/innei/git/vibe-coding/photo-gallery-site && npm run lint -- src/components/ui/photo-viewer/ProgressiveImage.tsx
```

```
cd /Users/innei/git/vibe-coding/photo-gallery-site && npm run lint -- src/components/ui/photo-viewer/ProgressiveImag
src/components/ui/photo-viewer/ProgressiveImage.tsx   npm

> photo-gallery-site@0.0.1 lint /Users/innei/git/vibe-coding/photo-gallery-site
> eslint --fix -- src/components/ui/photo-viewer/ProgressiveImage.tsx


innei in photo-gallery-site on  main [$!] via 🎁 v0.0.1 via  v22.15.0 on ☁️  innei@rss3.io at     9fa1646 "Enhan
ce WebGLImageViewer with debug information and scaling constraints"  by tukon479@gmail.com 
at 00:19:30 ❯
```

---

很好！没有 linter 错误。现在让我总结一下我所做的修改：

## 修改总结

我已经成功修改了 `ProgressiveImage.tsx` 组件，使加载指示器遮罩的大小和位置与 `thumbnailRef` 图片的位置重合。主要修改包括：

### 1. 添加状态管理
```typescript
const [thumbnailBounds, setThumbnailBounds] = useState<{
  left: number
  top: number
  width: number
  height: number
} | null>(null)
```

### 2. 创建计算缩略图边界的函数
```typescript
const calculateThumbnailBounds = useCallback(() => {
  // 计算图片在容器中的实际显示位置和大小（考虑 object-contain）
  // 处理图片宽高比与容器宽高比的差异
}, [])
```

### 3. 添加 ResizeObserver 监听
```typescript
useEffect(() => {
  // 监听容器大小变化，重新计算缩略图边界
  const resizeObserver = new ResizeObserver(() => {
    const bounds = calculateThumbnailBounds()
    setThumbnailBounds(bounds)
  })
  // ...
}, [calculateThumbnailBounds, thumbnailSrc])
```

### 4. 修改加载指示器的样式
```typescript
<m.div
  className="absolute flex items-center justify-center bg-black/20 z-10 pointer-events-none"
  style={
    thumbnailBounds
      ? {
          left: thumbnailBounds.left,
          top: thumbnailBounds.top,
          width: thumbnailBounds.width,
          height: thumbnailBounds.height,
        }
      : {
          inset: 0,
        }
  }
  // ...
>
```

### 5. 在缩略图加载时计算边界
```typescript
const handleThumbnailLoad = useCallback(() => {
  thumbnailAnimateController.start({ opacity: 1 })
  
  // 计算缩略图边界
  const bounds = calculateThumbnailBounds()
  setThumbnailBounds(bounds)
}, [thumbnailAnimateController, calculateThumbnailBounds])
```

## 功能特点

1. **精确定位**：遮罩会精确覆盖缩略图的实际显示区域，考虑了 `object-contain` 的影响
2. **响应式**：当窗口大小改变时，会自动重新计算遮罩位置
3. **兼容性**：如果无法计算缩略图边界，会回退到覆盖整个容器
4. **性能优化**：使用 `useCallback` 和 `ResizeObserver` 确保高效的重新计算

现在加载指示器遮罩将只显示在缩略图的实际位置上，而不是覆盖整个容器区域。

---

