Web组件如何加载HEIF、HEIC、SVGA、SVG文件
=============================

#### 问题现象

HEIF和HEIC、SVGA和SVG分别是什么，Web组件如何加载这些文件？

#### 背景知识

*   HEIF图片（High Efficiency Image File Format），是一个用于单张图像或图像序列的文件格式。目前主流的HEIF图片均使用HEVC(H.265)编码。
*   HEIC是符合HEIF标准、使用HEVC编码的具体图像文件。
*   SVGA是一种轻量级的动画格式，相比GIF和APNG格式，它支持更多的动画特性，如透明度、缩放和旋转等。
*   SVG（Scalable Vector Graphics）是可缩放矢量图形，它是一种基于XML（可扩展标记语言）的图形格式，用于描述二维图形和图像。具体可参考[SVG标签说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-svg)。

#### 解决方案

*   HEIF、HEIC和SVG图片支持在HTML里直接通过img标签展示，以加载本地图片为例（需要先将HTML文件放到rawfile目录下，图片资源文件放到rawfile/img目录下）。
    
    完整样例代码如下：
    
    _<!-- heif.html -->_
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>测试HEIF/HEIC/SVG图片</title>
        <style>
            p {
                font-size: 16px;
            }
            .flex-center {
                display: block;
                justify-content: center;
                align-items: center;
                min-height: 300px;
            }
            .responsive-img {
                width: 55%;
                height: auto;
                justify-content: center;
                align-items: center;
            }
        </style>
    </head>
    <body>
    <div class="flex-center">
        <div>
            <p>HEIF图片</p>
           _ <!--网络图片src直接换成对应的url地址即可\--\>_
            <img class="responsive-img" src="img/test.heif">
        </div>
        <div>
            <p>HEIC图片</p>
           _ <!--网络图片src直接换成对应的url地址即可\--\>_
            <img class="responsive-img" src="img/test.heic">
        </div>
        <div>
            <p>SVG图片</p>
         _   <!--网络图片src直接换成对应的url地址即可\--\>_
            <img class="responsive-img" src="img/test.svg">
        </div>
    </div>
    <script>
    </script>
    </body>
    </html>
    
    import { webview } from '@kit.ArkWeb';
    
    @Entry
    @Component
    struct HEIFDemo {
      controller: webview.WebviewController \= new webview.WebviewController();
      context: Context \= this.getUIContext().getHostContext() as Context;
    
      build() {
        Column() {
          Web({
            src: $rawfile('heif.html'),
            controller: this.controller
          })
            .fileAccess(true)
            .javaScriptAccess(true)
            .domStorageAccess(true)
            .geolocationAccess(false);
        };
      }
    }
    
*   SVGA动画不支持在HTML里直接通过img标签展示，可以通过使用SVGA-Web播放器([SVGAPlayer-Web](https://github.com/svga/SVGAPlayer-Web))在Web组件中加载SVGA动画，具体步骤如下：
    
    1.  在resources目录下新建一个resfile目录，并把HTML文件放到resfile目录下，图片资源文件放到resfile/img目录下，js文件放到resfile/js目录下。
    2.  引入播放器库：
        
        在HTML的head标签中，引入SVGA播放器库。
        
        <script src="js/svga.min.js"></script>
        
    3.  准备动画容器：
        
        在页面中创建一个div元素作为SVGA动画的舞台。
        
        <div id="svgaContainer"></div>
        
    4.  加载并播放动画：
        
        编写JavaScript代码，初始化播放器并加载远程或本地的.svga文件。
        
        document.addEventListener('DOMContentLoaded', function () {
          _// 1. 初始化播放器，绑定到容器_
          let player \= new SVGA.Player('#svgaContainer');
         _ // 2. 初始化解析器_
          let parser \= new SVGA.Parser();
        
          _// 3. 加载并解析SVGA文件，此处load的url使用的是本地文件的地址，也可以使用在线的svga文件，例如：xxx.com/xxx.svga_
          parser.load("file:///data/storage/el1/bundle/entry/resources/resfile/img/test.svga",
            function (videoItem) {
             _ // 4. 将解析好的视频项设置给播放器_
              player.setVideoItem(videoItem);
             _ // 5. 开始播放动画_
              player.startAnimation();
            }, function (error) {
              console.error('SVGA文件加载失败:', error);
            });
        });
        
    
    完整的样例代码如下：
    
    import { webview } from '@kit.ArkWeb';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    @Entry
    @Component
    struct SVGADemo {
      controller: webview.WebviewController \= new webview.WebviewController();
      context: Context \= this.getUIContext().getHostContext() as Context;
    
      build() {
        Column() {
          Web({
            src: '',
            controller: this.controller
          })
            .onControllerAttached(() \=\> {
              try {
                this.controller.setPathAllowingUniversalAccess(\[
                  this.getUIContext().getHostContext()!.resourceDir
                \]);
                this.controller.loadUrl('file://' \+ this.context!.resourceDir \+ '/svga.html');
              } catch (error) {
                console.error(\`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}\`);
              }
            })
            .fileAccess(true)
            .javaScriptAccess(true)
            .domStorageAccess(true)
            .geolocationAccess(false);
        };
      }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>加载SVGA</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            .img-container {
                padding: 20px;
                margin: 10px;
            }
            .flex-center {
                display: flex;
                justify-content: center;
                align-items: center;
            }
            #svgaContainer {
                width: 300px;
            }
        </style>
        <script src="js/svga.min.js"></script>
    </head>
    <body>
    <div class="img-container flex-center">
        <div id="svgaContainer"></div>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
           _ // 1. 初始化播放器，绑定到容器_
            let player = new SVGA.Player('#svgaContainer');
           _ // 2. 初始化解析器_
            let parser = new SVGA.Parser();
           _ // 3. 加载并解析SVGA文件，此处load的url使用的是本地文件的地址，也可以使用在线的svga文件，例如：xxx.com/xxx.svga_
            parser.load("file:///data/storage/el1/bundle/entry/resources/resfile/img/test.svga",
                function (videoItem) {
                  _  // 4. 将解析好的视频项设置给播放器_
                    player.setVideoItem(videoItem);
                 _   // 5. 开始播放动画_
                    player.startAnimation();
                }, function (error) {
                    console.error('SVGA文件加载失败:', error);
                });
        });
    </script>
    </body>
    </html>