You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pixi.js:基于鼠标位置的缩放功能实现技术问询

Pixi.js 实现围绕鼠标位置缩放的功能

核心原理

围绕鼠标位置缩放的关键在于:缩放时保持鼠标指向的场景坐标在屏幕上的位置不变。需要完成以下步骤:

  1. 将鼠标的屏幕坐标转换为场景容器(stage)的局部坐标(需考虑当前的缩放和位移)
  2. 应用缩放比例
  3. 调整容器的位置,确保鼠标对应的场景点在缩放后仍处于原屏幕位置

修正后的完整代码

const { Application, Container, Sprite, Texture, Point } = PIXI

let app, isKeyDown

app = new Application({
    backgroundAlpha: 1,
    width: innerWidth, height: innerHeight,
    antialias: true,
    resolution: window.devicePixelRatio || 1,
    resizeTo: window,
    autoDensity: true
})
document.body.appendChild(app.view)

const stage = new Container()
app.stage.addChild(stage)

// 创建网格Sprite
for (let x = 0; x < 100; x++)
    for (let y = 0; y < 100; y++) {
        const box = Sprite.from(Texture.WHITE)
        box.position.set(x * 16, y * 16)
        box.width = box.height = 16 // 设置Sprite大小,否则默认无尺寸无法显示
        if ((x + y) % 2 === 1) {
            box.tint = 0xcccccc // 修正无效的十六进制颜色值,实现棋盘格效果
        }
        stage.addChild(box)
    }

let startMousePos, startStagePos
addEventListener('pointerdown', onDown)
addEventListener('pointermove', onMove)
addEventListener('pointerup', onUP)
addEventListener('pointerleave', onUP) // 鼠标离开窗口时自动取消拖动
addEventListener('wheel', onWheel)

// 优化平移逻辑:记录初始状态,计算相对偏移
function onDown(e) {
    isKeyDown = true
    startMousePos = new Point(e.x, e.y)
    startStagePos = new Point(stage.x, stage.y)
}

function onMove(e) {
    if (!isKeyDown) return
    const deltaX = e.x - startMousePos.x
    const deltaY = e.y - startMousePos.y
    stage.x = startStagePos.x + deltaX
    stage.y = startStagePos.y + deltaY
}

function onUP(e) {
    isKeyDown = false
}

// 实现围绕鼠标缩放
function onWheel(e) {
    e.preventDefault() // 阻止页面默认滚动行为
    const mouseX = e.x
    const mouseY = e.y

    // 将屏幕坐标转换为stage的局部坐标(场景内的固定位置)
    const localPos = stage.toLocal(new Point(mouseX, mouseY))

    // 定义缩放因子(滚轮向上放大,向下缩小,比例更稳定)
    const scaleFactor = e.deltaY < 0 ? 1.1 : 0.9
    const newScaleX = stage.scale.x * scaleFactor
    const newScaleY = stage.scale.y * scaleFactor

    // 限制缩放范围,避免过度缩放导致异常
    const minScale = 0.1
    const maxScale = 5
    if (newScaleX < minScale || newScaleX > maxScale) return

    // 调整stage位置,确保鼠标指向的场景点位置不变
    stage.x = mouseX - localPos.x * newScaleX
    stage.y = mouseY - localPos.y * newScaleY

    // 应用新的缩放
    stage.scale.x = newScaleX
    stage.scale.y = newScaleY
}

关键修改点说明

  • 修复Sprite显示问题:原代码未设置Sprite宽高,添加box.width = box.height = 16让方块可见。
  • 修正颜色值:替换无效的十六进制颜色,改用0xcccccc实现棋盘格效果。
  • 优化平移逻辑:通过记录初始鼠标和stage位置,计算相对偏移,拖动行为更稳定。
  • 围绕鼠标缩放实现:
    • 用stage.toLocal()将屏幕坐标转换为场景内的固定坐标,确保缩放时锚点正确。
    • 采用乘法缩放因子替代加法,缩放速度均匀可控。
    • 调整stage的位置,保证缩放后鼠标指向的场景点仍在原屏幕位置。
    • 添加缩放范围限制,避免过度缩放。
  • 增强交互体验:新增pointerleave事件监听,鼠标离开窗口时自动取消拖动。

内容的提问来源于stack exchange,提问作者Meysam Ghorbani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:42:51