You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PixiJS中如何为路径描边动态设置重复纹理?

PixiJS中如何为路径描边动态设置重复纹理?

嘿,我刚好碰到过类似的2D墙结构需求,你的思路其实已经走对了大半!要实现动态重复纹理的路径描边,核心是在基础纹理设置重复模式的前提下,根据路径的变化实时调整纹理的重复参数,我来给你拆解一下具体步骤:

一、先搞定基础的纹理重复设置

你代码里设置baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT这一步是关键,这是让纹理能重复显示的基础。不过要注意:

  • 修改完wrapMode后必须调用baseTexture.update(),才能让GPU同步这个设置;
  • 如果遇到纹理重复不生效的情况,检查下纹理尺寸是否是2的幂次(比如256x256)——虽然WebGL 2.0支持非2幂次纹理重复,但旧环境可能有兼容问题,必要时可以开启PixiJS的WebGL 2.0模式。

二、动态调整纹理重复的核心技巧

要让纹理跟着路径长度/形状动态重复,关键是根据路径的实际长度计算纹理的重复次数,而不是固定死重复值。

1. 先获取路径的总长度

PixiJS的Graphics可以通过geometry.totalLength获取路径的总长度,我们可以封装一个工具函数:

function getPathTotalLength(path) {
  const tempGraphics = new PIXI.Graphics();
  tempGraphics.path(path);
  const totalLength = tempGraphics.geometry.totalLength;
  tempGraphics.destroy(); // 用完及时销毁临时对象,避免内存泄漏
  return totalLength;
}

2. 动态计算并更新纹理重复值

假设我们的纹理原始宽度是baseTexture.width,路径总长度是pathLength,那么让纹理刚好铺满路径的重复次数就是pathLength / baseTexture.width。修改texture.repeat后同样要调用texture.update()生效:

// 加载纹理(替换成你的本地纹理路径)
const baseTexture = await PIXI.Assets.load('./your-wall-texture.png');
baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
baseTexture.update();

const texture = new PIXI.Texture(baseTexture);
const g = new PIXI.Graphics();
app.stage.addChild(g);

// 初始路径绘制
const path = new PIXI.GraphicsPath();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.arcTo(250, 100, 250, 150, 30);
path.lineTo(250, 200);

// 初始计算重复值
const initialPathLength = getPathTotalLength(path);
const textureWidth = baseTexture.width;
texture.repeat.set(initialPathLength / textureWidth, 1); // x方向按路径长度重复,y方向保持1
texture.update();

// 绘制描边
g.path(path);
g.stroke({ width: 12, texture: texture });

3. 路径变化时的动态更新

如果你的墙结构需要动态修改(比如拖拽调整墙的长度、修改圆角半径),只需要重新计算路径长度、更新纹理重复值,然后重新绘制即可:

// 举个例子:点击按钮修改路径
document.querySelector('#adjustWallBtn').addEventListener('click', () => {
  // 重置并创建新路径
  path.reset();
  path.moveTo(100, 100);
  path.lineTo(350, 100); // 更长的直线段
  path.arcTo(400, 100, 400, 220, 40); // 更大的圆角
  path.lineTo(400, 280);

  // 重新计算路径长度和纹理重复
  const newPathLength = getPathTotalLength(path);
  texture.repeat.set(newPathLength / textureWidth, 1);
  texture.update();

  // 重新绘制图形
  g.clear();
  g.path(path);
  g.stroke({ width: 12, texture: texture });
});

三、额外优化小技巧

  • 如果想让纹理在描边的垂直方向(也就是墙的厚度方向)也不被拉伸,可以计算描边宽度和纹理高度的比例,设置texture.repeat.y = strokeWidth / baseTexture.height
  • 如果纹理边缘衔接有缝隙,检查纹理的边缘是否有多余的透明像素,或者微调一下重复值(比如加个很小的偏移)。

这样就能实现完全动态的纹理重复路径描边啦,我之前做类似的室内墙结构就是这么处理的,亲测好用~

内容来源于stack exchange

火山引擎 最新活动