zoukankan      html  css  js  c++  java
  • pixi.js持续渲染页面

    Pixi是一个超快的2D渲染引擎,通过Javascript和Html技术创建动画或管理交互式图像,从而制作游戏或应用。

    项目地址:https://github.com/pixijs/pixi.js
    API 地址:https://pixijs.download/dev/docs/index.html
    中文教程地址:https://github.com/Zainking/learningPixi

    问题

    一个简单的demo,主要是通过pixi.js绘制一张图片并展示在页面中。通过观察任务管理器->性能->GPU模块可以发现,页面一直在渲染,导致GPU持续被占用。本来的目的只是想展示一张静态图片即可,并不要求实时刷新。换句话说,就是如何实现pixi.js只在需要的时候进行渲染。

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
    <script type="text/javascript">
        let Application = PIXI.Application,
            loader = PIXI.loader,
            resources = PIXI.loader.resources,
            Sprite = PIXI.Sprite;
    
        //Create a Pixi Application
        let app = new Application({
             1000,
            height: 800,
        });
    
        document.body.appendChild(app.view);
        loader.add("img/wall5.jpg").load(setup);
        function setup() {
            let img = new Sprite(resources["img/wall5.jpg"].texture);
            app.stage.addChild(img);
        }
    
    </script>
    

    解决方案

    在查看了pixi.js的源码后发现,它的持续渲染还是通过requestAnimationFrame实现的。下面简单分析下实现过程。

    1. Application的构造函数中,循环调用所有plugininit函数,并将构造参数
      传递下去(https://pixijs.download/dev/docs/packages_app_src_Application.ts.html#line95)

    2. TickerPlugin中执行init函数(默认autoStart参数为true),构建定时器Ticker。(https://pixijs.download/dev/docs/packages_ticker_src_TickerPlugin.ts.html#line101)

    if (options.autoStart)
    {
       this._ticker.start();
    }
    
    1. Ticker中初始化_tick方法,调用requestAnimationFrame(MDN),实现持续渲染。(https://pixijs.download/dev/docs/packages_ticker_src_Ticker.ts.html#line171)
    this._tick = (time: number): void =>
    {
        this._requestId = null;
        if (this.started)
        {
             // Invoke listeners now
            this.update(time);
            if (this.started && this._requestId === null && this._head.next)
            {
                this._requestId = requestAnimationFrame(this._tick);
            }
        }
    };
    

    综上所述,要实现只渲染一次的目标,只要不去启动_ticker,再在需要渲染的时候执行render即可。


    1. 关闭app的自动启动

    new PIXI.Application (options)
    options.autoStart: Automatically starts the rendering after the construction
    (在构造结束后就自动开始渲染)

    ps:该属性的设置只能在构造时传入,后续修改无效

    1. 在需要的时候主动调用渲染app.render();

    修改后代码:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
    <script type="text/javascript">
        let Application = PIXI.Application,
            loader = PIXI.loader,
            resources = PIXI.loader.resources,
            Sprite = PIXI.Sprite;
    
        //Create a Pixi Application
        let app = new Application({
             1000,
            height: 800,
            autoStart: false
        });
    
        document.body.appendChild(app.view);
        loader.add("img/wall5.jpg").load(setup);
        function setup() {
            let img = new Sprite(resources["img/wall5.jpg"].texture);
            app.stage.addChild(img);
            app.render();
        }
    </script>
    

    现在再观察GPU可以发现只有一个小小的起伏后就归0了。为了效果明显一点,我先执行一些耗性能的操作后再绘制图片。可以看到GPU利用率在一个高峰后就迅速回落了。

    总结

    请注意不同版本pixi.js API之间的区别,以官方API文档为主。

  • 相关阅读:
    [LeetCode] Best Time to Buy and Sell Stock III
    [LeetCode] Implement strStr()
    [LeetCode] Wildcard Matching
    [LeetCode] Gray Code
    [LeetCode] Divide Two Integers
    [LeetCode] Flatten Binary Tree to Linked List
    [LeetCode] Binary Tree Maximum Path Sum
    [TopCoder][SRM] SRM 562 DIV 2
    推荐博客文章
    检测两点所确定直线上的像素坐标
  • 原文地址:https://www.cnblogs.com/cplemom/p/14062602.html
Copyright © 2011-2022 走看看