<template>
  <view class="container">
    <canvas
      ref="canvasRef"
      class="drawing-canvas"
      :style="{
        width: `${canvasWidth}px`,
        height: `${canvasHeight}px`
      }"
      :width="canvasWidth * devicePixelRatio"
      :height="canvasHeight * devicePixelRatio"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    />
    
    <!-- 控制面板 -->
    <view class="control-panel">
      <button @click="addImage">添加图片</button>
      <button @click="clearAll">清除所有</button>
      <button @click="toggleDebug">{{ showDebug ? '隐藏调试' : '显示调试' }}</button>
      <text>图片数量: {{ images.length }}</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      canvasWidth: 0,
      canvasHeight: 0,
      devicePixelRatio: 1,
      ctx: null,
      offscreenCanvas: null, // 离屏 Canvas
      offscreenCtx: null,
      
      images: [], // 所有图片
      imageCache: new Map(), // 图片缓存
      draggingIndex: -1, // 当前拖动的图片索引
      
      // 性能优化
      renderQueue: [], // 渲染队列
      lastRenderTime: 0,
      batchRender: true, // 批量渲染
      showDebug: false
    }
  },
  
  mounted() {
    this.initCanvas()
    
    // 初始化图片
    for (let i = 0; i < 5; i++) {
      this.addImage()
    }
  },
  
  methods: {
    /**
     * 初始化 Canvas
     */
    initCanvas() {
      const systemInfo = uni.getSystemInfoSync()
      this.devicePixelRatio = systemInfo.pixelRatio || 1
      this.canvasWidth = systemInfo.windowWidth
      this.canvasHeight = systemInfo.windowHeight
      
      // 初始化主 Canvas
      const query = uni.createSelectorQuery().in(this)
      query.select('.drawing-canvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (res[0]) {
            const canvas = res[0].node
            this.ctx = canvas.getContext('2d')
            
            // 设置高分辨率
            canvas.width = this.canvasWidth * this.devicePixelRatio
            canvas.height = this.canvasHeight * this.devicePixelRatio
            this.ctx.scale(this.devicePixelRatio, this.devicePixelRatio)
            
            // 初始化离屏 Canvas
            this.initOffscreenCanvas()
            
            // 开始渲染循环
            this.startRenderLoop()
          }
        })
    },
    
    /**
     * 初始化离屏 Canvas
     */
    initOffscreenCanvas() {
      this.offscreenCanvas = document.createElement('canvas')
      this.offscreenCanvas.width = this.canvasWidth
      this.offscreenCanvas.height = this.canvasHeight
      this.offscreenCtx = this.offscreenCanvas.getContext('2d')
    },
    
    /**
     * 添加图片
     */
    addImage() {
      const image = {
        id: Date.now() + Math.random(),
        x: Math.random() * (this.canvasWidth - 100),
        y: Math.random() * (this.canvasHeight - 100),
        width: 80 + Math.random() * 40,
        height: 80 + Math.random() * 40,
        rotation: Math.random() * Math.PI * 2,
        scale: 0.8 + Math.random() * 0.4,
        color: this.getRandomColor(),
        isDragging: false
      }
      
      this.images.push(image)
      
      // 预渲染到离屏 Canvas
      this.prerenderImage(image)
      
      // 标记需要重新渲染
      this.scheduleRender()
    },
    
    /**
     * 预渲染图片
     */
    prerenderImage(image) {
      if (this.imageCache.has(image.id)) return
      
      const cacheCanvas = document.createElement('canvas')
      cacheCanvas.width = image.width
      cacheCanvas.height = image.height
      const cacheCtx = cacheCanvas.getContext('2d')
      
      // 绘制到缓存 Canvas
      cacheCtx.fillStyle = image.color
      cacheCtx.fillRect(0, 0, image.width, image.height)
      
      // 添加边框
      cacheCtx.strokeStyle = 'rgba(255, 255, 255, 0.8)'
      cacheCtx.lineWidth = 2
      cacheCtx.strokeRect(1, 1, image.width - 2, image.height - 2)
      
      // 添加编号
      cacheCtx.fillStyle = 'white'
      cacheCtx.font = '20px Arial'
      cacheCtx.textAlign = 'center'
      cacheCtx.textBaseline = 'middle'
      cacheCtx.fillText(
        String(this.images.indexOf(image) + 1),
        image.width / 2,
        image.height / 2
      )
      
      this.imageCache.set(image.id, cacheCanvas)
    },
    
    /**
     * 处理触摸开始
     */
    handleTouchStart(e) {
      const touch = e.touches[0]
      const rect = e.currentTarget.getBoundingClientRect()
      const x = touch.clientX - rect.left
      const y = touch.clientY - rect.top
      
      // 从后往前检查，点击在最后面的图片上
      for (let i = this.images.length - 1; i >= 0; i--) {
        const image = this.images[i]
        if (this.isPointInImage(x, y, image)) {
          this.draggingIndex = i
          image.isDragging = true
          image.dragOffset = {
            x: x - image.x,
            y: y - image.y
          }
          
          // 将图片移到最前面
          this.bringToFront(i)
          this.scheduleRender()
          break
        }
      }
    },
    
    /**
     * 处理触摸移动
     */
    handleTouchMove(e) {
      e.preventDefault()
      
      if (this.draggingIndex === -1) return
      
      const touch = e.touches[0]
      const rect = e.currentTarget.getBoundingClientRect()
      const x = touch.clientX - rect.left
      const y = touch.clientY - rect.top
      
      const image = this.images[this.draggingIndex]
      image.x = x - image.dragOffset.x
      image.y = y - image.dragOffset.y
      
      // 边界检查
      image.x = Math.max(0, Math.min(this.canvasWidth - image.width, image.x))
      image.y = Math.max(0, Math.min(this.canvasHeight - image.height, image.y))
      
      this.scheduleRender()
    },
    
    /**
     * 处理触摸结束
     */
    handleTouchEnd() {
      if (this.draggingIndex !== -1) {
        this.images[this.draggingIndex].isDragging = false
        this.draggingIndex = -1
        this.scheduleRender()
      }
    },
    
    /**
     * 检查点是否在图片内
     */
    isPointInImage(x, y, image) {
      // 简化的矩形检测
      return (
        x >= image.x &&
        x <= image.x + image.width &&
        y >= image.y &&
        y <= image.y + image.height
      )
    },
    
    /**
     * 将图片移到最前面
     */
    bringToFront(index) {
      if (index === this.images.length - 1) return
      
      const image = this.images[index]
      this.images.splice(index, 1)
      this.images.push(image)
      this.draggingIndex = this.images.length - 1
    },
    
    /**
     * 调度渲染
     */
    scheduleRender() {
      if (!this.renderScheduled) {
        this.renderScheduled = true
        requestAnimationFrame(() => {
          this.render()
          this.renderScheduled = false
        })
      }
    },
    
    /**
     * 开始渲染循环
     */
    startRenderLoop() {
      const renderLoop = () => {
        this.renderFrameId = requestAnimationFrame(renderLoop)
        
        // 如果正在拖动，强制渲染
        if (this.draggingIndex !== -1) {
          this.render()
        } else {
          // 非拖动状态，可以降低渲染频率
          const now = Date.now()
          if (now - this.lastRenderTime > 16) { // 约 60fps
            this.render()
          }
        }
      }
      
      renderLoop()
    },
    
    /**
     * 渲染
     */
    render() {
      if (!this.ctx || !this.offscreenCtx) return
      
      const now = Date.now()
      
      if (this.batchRender) {
        // 批量渲染到离屏 Canvas
        this.renderToOffscreen()
        
        // 从离屏 Canvas 复制到主 Canvas
        this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
        this.ctx.drawImage(this.offscreenCanvas, 0, 0)
      } else {
        // 直接渲染
        this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
        this.renderImages()
      }
      
      this.lastRenderTime = now
    },
    
    /**
     * 渲染到离屏 Canvas
     */
    renderToOffscreen() {
      this.offscreenCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
      
      // 绘制背景
      this.offscreenCtx.fillStyle = '#f5f5f5'
      this.offscreenCtx.fillRect(0, 0, this.canvasWidth, this.canvasHeight)
      
      // 绘制所有图片
      this.images.forEach(image => {
        this.renderImage(this.offscreenCtx, image)
      })
    },
    
    /**
     * 渲染图片
     */
    renderImages() {
      this.images.forEach(image => {
        this.renderImage(this.ctx, image)
      })
    },
    
    /**
     * 渲染单个图片
     */
    renderImage(ctx, image) {
      const cache = this.imageCache.get(image.id)
      if (!cache) return
      
      ctx.save()
      
      // 设置变换
      ctx.translate(image.x + image.width / 2, image.y + image.height / 2)
      ctx.rotate(image.rotation)
      ctx.scale(image.scale, image.scale)
      
      // 绘制阴影
      if (image.isDragging) {
        ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
        ctx.shadowBlur = 15
        ctx.shadowOffsetY = 5
      } else {
        ctx.shadowColor = 'rgba(0, 0, 0, 0.2)'
        ctx.shadowBlur = 5
        ctx.shadowOffsetY = 2
      }
      
      // 绘制图片
      ctx.drawImage(cache, -image.width / 2, -image.height / 2)
      
      // 绘制拖动状态指示器
      if (image.isDragging) {
        ctx.strokeStyle = '#4A90E2'
        ctx.lineWidth = 3
        ctx.strokeRect(
          -image.width / 2 - 2,
          -image.height / 2 - 2,
          image.width + 4,
          image.height + 4
        )
      }
      
      ctx.restore()
    },
    
    /**
     * 清除所有
     */
    clearAll() {
      this.images = []
      this.imageCache.clear()
      this.scheduleRender()
    },
    
    /**
     * 切换调试模式
     */
    toggleDebug() {
      this.showDebug = !this.showDebug
      this.scheduleRender()
    },
    
    /**
     * 获取随机颜色
     */
    getRandomColor() {
      const colors = [
        '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7',
        '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9'
      ]
      return colors[Math.floor(Math.random() * colors.length)]
    }
  }
}
</script>

<style>
.container {
  width: 100vw;
  height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  overflow: hidden;
}

.drawing-canvas {
  width: 100vw;
  height: 100vh;
  display: block;
  touch-action: none;
  user-select: none;
  cursor: move;
}

.control-panel {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.9);
  padding: 10px 20px;
  border-radius: 20px;
  display: flex;
  gap: 10px;
  align-items: center;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}

.control-panel button {
  padding: 8px 16px;
  border: none;
  border-radius: 8px;
  background: #4A90E2;
  color: white;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.3s;
}

.control-panel button:active {
  background: #357AE8;
  transform: translateY(1px);
}

.control-panel text {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}
</style>