【发布时间】:2018-08-13 14:47:24
【问题描述】:
我正在为一个简单的 2D 图形测试 PIXIjs,基本上我正在滑动带有一些背景颜色和边框动画的瓷砖,另外我正在掩盖布局的某些部分。 虽然它在桌面上运行良好,但它确实比在移动设备中使用纯 css 制作的幻灯片+动画慢(顺便说一下,我使用的是 crosswalk+cordova,所以浏览器总是一样的) 对于移动磁贴和动画颜色,我为每个磁贴调用 requestAnimationFrame 并且我禁用了 PIXI 的代码:
ticker.autoStart = false;
ticker.stop();
这种缓慢可能是由于移动设备上的 GPU 较弱?还是只是我使用 PIXI 的方式?
我没有展示完整的代码,因为它很长 ~ 800 行。
以下是我在捕获幻灯片后对每个图块使用的例程:
const animateTileBorderAndText = (tileObj, steps, _color, radius, textSize, strokeThickness, _config) => {
let pixiTile = tileObj.tile;
let s = 0;
let graphicsData = pixiTile.graphicsData[0];
let shape = graphicsData.shape;
let textStyle = pixiTile.children[0].style;
let textInc = (textSize - textStyle.fontSize) / steps;
let strokeInc = (strokeThickness - textStyle.strokeThickness) / steps;
let prevColor = graphicsData.fillColor;
let color = _color !== null ? _color : prevColor;
let alpha = pixiTile.alpha;
let h = shape.height;
let w = shape.width;
let rad = shape.radius;
let radiusInc = (radius - rad) / steps;
let r = (prevColor & 0xFF0000) >> 16;
let g = (prevColor & 0x00FF00) >> 8;
let b = prevColor & 0x0000FF;
let rc = (color & 0xFF0000) >> 16;
let rg = (color & 0x00FF00) >> 8;
let rb = color & 0x0000FF;
let redStep = (rc - r) / steps;
let greenStep = (rg - g) / steps;
let blueStep = (rb - b) / steps;
let paintColor = prevColor;
let goPaint = color !== prevColor;
let animate = (t) => {
if (s === steps) {
textStyle.fontSize = textSize;
textStyle.strokeThickness = strokeThickness;
//pixiTile.tint = color;
if (!_config.SEMAPHORES.slide) {
_config.SEMAPHORES.slide = true;
PUBSUB.publish(_config.SLIDE_CODE, _config.torusModel.getData());
}
return true;
}
if (goPaint) {
r += redStep;
g += greenStep;
b += blueStep;
paintColor = (r << 16) + (g << 8) + b;
}
textStyle.fontSize += textInc;
textStyle.strokeThickness += strokeInc;
pixiTile.clear()
pixiTile.beginFill(paintColor, alpha)
pixiTile.drawRoundedRect(0, 0, h, w, rad + radiusInc * (s + 1))
pixiTile.endFill();
s++;
return requestAnimationFrame(animate);
};
return animate();
};
上面的函数是在下面的函数之后调用的,每个tile都会调用这个函数来让它滑动。
const slideSingleTile = (tileObj, delta, axe, conf, SEM, tilesMap) => {
let tile = tileObj.tile;
let steps = conf.animationSteps;
SEM.slide = false;
let s = 0;
let stepDelta = delta / steps;
let endPos = tile[axe] + delta;
let slide = (time) => {
if (s === steps) {
tile[axe] = endPos;
tileObj.resetPosition();
tilesMap[tileObj.row][tileObj.col] = tileObj;
return tileObj.onSlideEnd(axe == 'x' ? 0 : 2);
}
tile[axe] += stepDelta;
s++;
return requestAnimationFrame(slide);
};
return slide();
};
对于每个手指手势,单个列/行(NxM 块矩阵)使用上述两个函数进行滑动和动画处理。
这是我第一次使用画布。 我认为画布比 DOM 动画快得多,而且我对 PIXIjs 的评价非常好,所以我相信我做错了什么。
有人可以帮忙吗?
【问题讨论】:
-
您是否尝试过调试它,以检查代码的哪一部分花费的时间最长?甚至只是计时零件并使用 console.log 显示它们。这至少是检查瓶颈所在的良好开端。
-
您好,感谢您的快速回答。我已经在桌面(chrome)上对其进行了分析,我可以看到它在更新层树中花费了 50% 的时间。现在我必须将它与 css 版本进行比较。不幸的是,在移动设备上,当分析开启时它会变慢,甚至不启动动画。 (这是因为我的三星硬件性能差)
-
我看了多一点,试着给点分数。如果你使用 canvas 而不是 wegl,则不使用 GPU。 Webgl 使用 GPU。如果您为很多瓷砖设置动画,它看起来像是一个繁重的操作。你应该尽量在每一帧中做尽可能少的事情。此外,如果可能的话,只需移动对象并更改它们的属性,而不是创建新的。就像创建新的圆角矩形
-
您好,Hachi,再次感谢您的帮助。似乎在pixijs中更改矩形布局(背景颜色边框......)的唯一方法是重绘......我希望我可以被证明是错误的,但我试图直接更改色调和其他变量,除了不需要影响将会发生。关于 WebGL,文档 (github.com/pixijs/pixi.js) 说:“如果可能,应用程序将使用 WebGL 创建渲染器”。如何检查 pixi 是使用 WebGL 还是仅使用 canvas?
-
顺便说一句,我做了更多的调试,我发现在“更新层树”中花费的所有计算都不是由于 pixjs,而是我在 dom 中做的其他事情。再次感谢您提醒我,我是一名开发人员,我应该拥有(并使用)调试技能。
标签: performance canvas pixi.js