Pixi.js:基于鼠标位置的缩放功能实现技术问询
Pixi.js 实现围绕鼠标位置缩放的功能
核心原理
围绕鼠标位置缩放的关键在于:缩放时保持鼠标指向的场景坐标在屏幕上的位置不变。需要完成以下步骤:
- 将鼠标的屏幕坐标转换为场景容器(stage)的局部坐标(需考虑当前的缩放和位移)
- 应用缩放比例
- 调整容器的位置,确保鼠标对应的场景点在缩放后仍处于原屏幕位置
修正后的完整代码
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
相关产品推荐
相关产品推荐

