Pixi JS v.8中如何将带缩放的Graphics对象转为光栅Texture
在PixiJS v8中保留缩放比例将Graphics转换为Texture的方法
直接修改graphics.scale不会影响生成的Texture,因为renderer.generateTexture默认基于图形的本地坐标系(未应用任何变换)渲染,对象的缩放属性属于显示变换,不会被纳入纹理生成流程。下面是两种可行的解决方法:
方法一:把缩放直接应用到图形路径上
用Graphics.scaleShape()方法替代graphics.scale.set(),这个方法会直接修改Graphics内部的绘制路径数据,让图形本身的尺寸被缩放,生成的Texture自然就是放大/缩小后的效果。
修改代码中设置缩放的行:
// 原代码(无效果) graphics.scale.set(10);
替换成:
// 将缩放应用到图形路径 graphics.scaleShape(10, 10);
完整修改后的代码:
import { Application, Assets, Graphics, Sprite } from 'pixi.js'; (async () => { const app = new Application(); await app.init({ antialias: true, resizeTo: window }); document.body.appendChild(app.canvas); const tigerSvg = await Assets.load({ src: 'https://pixijs.com/assets/tiger.svg', data: { parseAsGraphicsContext: true, }, }); const graphics = new Graphics(tigerSvg); graphics.scaleShape(10, 10); // 应用缩放至图形路径 const texture = app.renderer.generateTexture(graphics); const sprite = new Sprite(texture); const bounds = sprite.getLocalBounds(); sprite.pivot.set((bounds.x + bounds.width) / 2, (bounds.y + bounds.height) / 2); sprite.position.set(app.screen.width / 2, app.screen.height / 2); app.stage.addChild(sprite); app.ticker.add((time) => { sprite.rotation += 0.01; sprite.scale.set(2 + Math.sin(sprite.rotation)); }); })();
方法二:通过生成纹理的参数控制渲染区域和清晰度
如果不想改动原始图形的路径数据,可以手动计算缩放后图形的边界,在生成Texture时指定渲染区域,同时调整分辨率保证纹理清晰:
import { Application, Assets, Graphics, Sprite, Bounds } from 'pixi.js'; (async () => { const app = new Application(); await app.init({ antialias: true, resizeTo: window }); document.body.appendChild(app.canvas); const tigerSvg = await Assets.load({ src: 'https://pixijs.com/assets/tiger.svg', data: { parseAsGraphicsContext: true, }, }); const graphics = new Graphics(tigerSvg); const scale = 10; graphics.scale.set(scale, scale); // 计算缩放后的全局边界 const globalBounds = new Bounds(); graphics.getBounds(globalBounds); // 生成纹理时指定渲染范围和分辨率 const texture = app.renderer.generateTexture(graphics, { frame: globalBounds.getRectangle(), resolution: app.renderer.resolution * scale, // 避免缩放后纹理模糊 }); const sprite = new Sprite(texture); const bounds = sprite.getLocalBounds(); sprite.pivot.set((bounds.x + bounds.width) / 2, (bounds.y + bounds.height) / 2); sprite.position.set(app.screen.width / 2, app.screen.height / 2); app.stage.addChild(sprite); app.ticker.add((time) => { sprite.rotation += 0.01; sprite.scale.set(2 + Math.sin(sprite.rotation)); }); })();
两种方法各有适用场景:方法一适合不需要再复用原始尺寸图形的情况;方法二保留了原始图形数据,方便后续调整原始图形的大小。
内容的提问来源于stack exchange,提问作者ENIAC
相关产品推荐
相关产品推荐

