<!-- Generated by SpecStory -->

# 纹理大小与长宽比问题讨论 (2025-05-27 13:22:15)

_**User**_

1.double click 没有重新计算纹理大小
2. 纹理的长宽比不应该是 1:1 的，应该根据原图尺寸比例

---

_**Assistant**_

我来分析并修复这两个问题：

1. **双击时没有重新计算纹理大小** - 需要在双击动画完成后触发纹理更新
2. **纹理长宽比应该保持原图比例** - 当前的纹理尺寸计算没有保持原图的宽高比

让我先查看纹理计算的相关代码：

---

Read file: src/components/ui/WebGLImageViewer.tsx

---

现在让我查看动画完成的处理代码：

---

Read file: src/components/ui/WebGLImageViewer.tsx

---

现在我明确了问题所在。让我修复这两个问题：

1. **双击动画完成后需要触发纹理更新**
2. **纹理尺寸计算需要保持原图宽高比**

---



---

现在修复纹理尺寸计算，让它保持原图的宽高比：

---



---

现在我已经修复了两个问题：

## 修复内容

### 1. 双击动画完成后触发纹理更新
在 `animate()` 方法的动画完成分支中添加了 `this.debouncedTextureUpdate()` 调用，确保双击缩放动画完成后会重新计算和更新纹理，以获得最佳的图像质量。

### 2. 纹理尺寸保持原图宽高比
完全重写了 `calculateOptimalTextureSize()` 方法：

- **计算原图宽高比**：`const aspectRatio = this.originalImage.width / this.originalImage.height`
- **根据宽高比确定最小尺寸**：分别处理宽图、高图和正方形的情况
- **保持宽高比的约束**：在应用最小尺寸约束时，通过缩放因子同时调整宽度和高度
- **2的幂次方优化**：基于较大的维度计算2的幂次方，然后根据宽高比计算另一个维度
- **最终尺寸验证**：确保最终尺寸既不超过原图尺寸，也不小于最小要求

## 主要改进

1. **纹理质量**：双击缩放后纹理会自动更新，确保在不同缩放级别下都有最佳的图像清晰度
2. **宽高比保持**：纹理尺寸现在严格按照原图的宽高比计算，避免了之前可能出现的图像变形
3. **性能优化**：仍然使用2的幂次方尺寸以获得最佳的WebGL性能，但在保持宽高比的前提下进行优化

这些修复确保了WebGL图像查看器在各种缩放操作下都能提供高质量、无变形的图像显示效果。

---

_**User**_

图片首次渲染时候，材质的分辨率大小不正确，应该根据 fit-window 的缩放来调整

---

_**Assistant**_

我来分析这个问题。图片首次渲染时，纹理分辨率应该根据 fit-to-window 的缩放来调整，而不是使用默认的 scale = 1。

让我先查看图片加载和初始化的相关代码：

---

Read file: src/components/ui/WebGLImageViewer.tsx

---

现在让我查看 `fitImageToScreen` 方法：

---

Read file: src/components/ui/WebGLImageViewer.tsx

---

现在我明白问题了。在图片首次加载时，执行顺序是：

1. `loadImage()` 中调用 `createTexture(image)` 
2. `createTexture()` 立即调用 `createOptimizedTexture()`
3. 此时 `this.scale` 还是初始值 1，而不是 fit-to-window 的缩放值
4. 然后才调用 `fitImageToScreen()` 来设置正确的缩放值

所以纹理是基于错误的缩放值（scale = 1）计算的。我需要调整执行顺序，让纹理创建在缩放设置之后进行。

---



---

现在我还需要处理一个边界情况：如果 `centerOnInit` 为 false，我们仍然需要确保初始缩放值是合理的。让我检查构造函数中的初始缩放设置：

---

Read file: src/components/ui/WebGLImageViewer.tsx

---

我看到在构造函数中设置了 `this.scale = config.initialScale`，但这个值是相对于 fit-to-window 的比例，而不是绝对缩放值。我需要进一步优化，确保即使 `centerOnInit` 为 false 时，也能正确计算初始纹理。

让我修改 `loadImage` 方法，确保在任何情况下都能正确设置初始缩放：

---



---

现在我还需要修改构造函数，避免在没有图片尺寸信息时设置错误的初始缩放：

---



---

现在让我们总结一下修复的内容：

## 修复内容

### 问题分析
图片首次渲染时，纹理分辨率计算不正确的原因是：
1. 在构造函数中设置了 `this.scale = config.initialScale`，但这是相对缩放值
2. 在 `loadImage()` 中，纹理创建在缩放设置之前执行
3. 导致纹理基于错误的缩放值（通常是 1）进行计算

### 修复方案

1. **调整执行顺序**：在 `loadImage()` 中，先设置正确的缩放值，再创建纹理
2. **正确处理初始缩放**：
   - 如果 `centerOnInit` 为 true，调用 `fitImageToScreen()` 设置适应窗口的缩放
   - 如果 `centerOnInit` 为 false，手动计算绝对缩放值：`fitToScreenScale * initialScale`
3. **移除构造函数中的错误初始化**：注释掉构造函数中的 `this.scale = config.initialScale`，让缩放值在图片加载时正确设置

### 修复效果

现在图片首次渲染时：
- 纹理分辨率会根据正确的 fit-to-window 缩放值计算
- 无论 `centerOnInit` 设置如何，都能获得正确的初始纹理质量
- 纹理尺寸会根据实际显示尺寸和设备像素比进行优化
- 保持了原图的宽高比，避免变形

这个修复确保了图片在首次加载时就能以最佳的纹理质量显示，特别是对于需要适应窗口大小的场景。

---

