本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

Web组件支持三种缩放方式

  • 手势缩放:双指捏合缩放

  • 鼠标滚轮缩放:Ctrl+滚轮

  • 键盘缩放:Ctrl+加号/减号

同时提供完整的监听和控制API,使应用能实现个性化的缩放交互体验。

二、启用与禁用网页缩放

2.1 手势缩放控制

2.1.1 通过zoomAccess属性控制
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomAccess(false)  // false: 禁用手势缩放
    }
  }
}
2.1.2 通过HTML viewport标签控制

在HTML文件中添加:

<meta name="viewport" content="user-scalable=no">
2.1.3 缩放启用条件(逻辑与关系)
允许手势缩放 = zoomAccess(true) AND viewport允许缩放(user-scalable≠no)
2.1.4 说明
  1. PC/2in1设备特殊性viewport标签不生效,只能通过zoomAccess控制

  2. 缩放范围限制:即使允许缩放,也可能受以下限制:

    • minimum-scalemaximum-scale属性(在viewport标签中)

    • 网页内容宽度(限制最小缩放比例)

  3. 特殊情况:当minimum-scale等于maximum-scale时,网页不能缩放

2.2 强制缩放控制

通过forceEnableZoom属性可以绕过HTML限制

Web({ src: 'www.example.com', controller: this.controller })
  .forceEnableZoom(true)  // 不受minimum-scale/maximum-scale/user-scalable限制

2.3 键盘鼠标缩放控制

2.3.1 默认支持方式
  • 键盘:Ctrl + '+' 或 Ctrl + '-'

  • 鼠标:Ctrl + 滚轮

  • 触摸板:Ctrl + 双指滑动

2.3.2 方法一:拦截键盘事件(精细控制)
import { webview } from '@kit.ArkWeb';
import { KeyCode, KeyType } from '@kit.InputKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomAccess(true)
        .onKeyPreIme((event) => {
          // 检查是否是Ctrl+缩放按键
          if (event.type === KeyType.Down &&
              event.getModifierKeyState &&
              event.getModifierKeyState(['Ctrl']) &&
              (event.keyCode === KeyCode.KEYCODE_MINUS || 
               event.keyCode === KeyCode.KEYCODE_EQUALS ||
               event.keyCode === KeyCode.KEYCODE_NUMPAD_SUBTRACT || 
               event.keyCode === KeyCode.KEYCODE_NUMPAD_ADD)) {
            return true;  // 拦截事件,阻止缩放
          }
          return false;
        })
    }
  }
}
2.3.3 方法二:使用zoomControlAccess属性(简单控制)
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomControlAccess(false)  // 禁用所有Ctrl+组合键缩放
    }
  }
}

三、监听缩放比例变化

3.1 onScaleChange事件监听

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Web({ src: 'www.example.com', controller: this.controller })
        .onScaleChange((event) => {
          console.info('缩放比例从 ' + event.oldScale + ' 变为 ' + event.newScale);
          // event.newScale 对应网页的 visualViewport.scale 属性
        })
    }
  }
}

3.2 事件参数

参数 类型 描述
oldScale number 变化前的缩放比例
newScale number 变化后的缩放比例

注意:该事件对应手势缩放事件,与visualViewport.scale同步。

四、控制网页缩放比例

4.1 初始化缩放比例

Web({ src: 'www.example.com', controller: this.controller })
  .initialScale(1.5)  // 设置初始缩放比例为150%

4.2 缩放控制API

接口 功能 备注
zoom(factor: number) 按指定系数缩放 基于当前比例,factor>1放大,<1缩小
zoomIn() 固定放大25% 每次调用放大25%
zoomOut() 固定缩小20% 每次调用缩小20%

前提:使用这些API前必须设置zoomAccess(true),否则会抛出错误代码17100004

4.3 固定比例缩放示例

4.3.1 使用zoomIn/zoomOut
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  build() {
    Column() {
      Button('zoomIn')
        .onClick(() => {
          try {
            this.controller.zoomIn();  // 放大25%
          } catch (error) {
            console.error(`错误代码: ${(error as BusinessError).code}, 
                          信息: ${(error as BusinessError).message}`);
          }
        })
      
      Button('zoomOut')
        .onClick(() => {
          try {
            this.controller.zoomOut();  // 缩小20%
          } catch (error) {
            console.error(`错误代码: ${(error as BusinessError).code}, 
                          信息: ${(error as BusinessError).message}`);
          }
        })
      
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomAccess(true)  // 必须启用缩放
    }
  }
}
4.3.2 使用zoom按输入值缩放
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  @State factor: number = 1;  // 缩放系数,1为原始大小
  
  build() {
    Column() {
      // 输入缩放系数
      TextInput()
        .type(InputType.NUMBER_DECIMAL)
        .onChange((value) => {
          this.factor = Number(value);
        })
      
      Button('zoom')
        .onClick(() => {
          try {
            // factor>1: 放大,factor<1: 缩小,factor=1: 恢复原始大小
            this.controller.zoom(this.factor);
          } catch (error) {
            console.error(`错误代码: ${(error as BusinessError).code}, 
                          信息: ${(error as BusinessError).message}`);
          }
        })
      
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomAccess(true)
    }
  }
}

4.4 精确缩放至目标比例

4.4.1 实现原理

通过onScaleChange获取当前比例,结合zoom接口实现精确缩放。

计算公式

缩放系数 = 100 × 目标比例 ÷ 当前比例
4.4.2 完整实现
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  
  // 目标缩放比例
  @State targetFactor: number = 1;
  
  // 当前页面缩放比例(从onScaleChange获取)
  @State pageFactor: number = 100;  // 100表示1.0(100%)
  
  // 常数100,用于计算
  intNumber: number = 100;
  
  build() {
    Column() {
      // 输入目标比例(如输入1.5表示150%)
      TextInput()
        .type(InputType.NUMBER_DECIMAL)
        .onChange((value) => {
          this.targetFactor = Number(value);
        })
      
      Button('缩放至目标比例')
        .onClick(() => {
          try {
            // 计算缩放系数
            let factor = this.targetFactor * this.intNumber / this.pageFactor;
            
            // 执行缩放
            this.controller.zoom(factor);
            
          } catch (error) {
            console.error(`错误代码: ${(error as BusinessError).code}, 
                          信息: ${(error as BusinessError).message}`);
          }
        })
      
      Web({ src: 'www.example.com', controller: this.controller })
        .zoomAccess(true)
        .onScaleChange((event) => {
          console.log('缩放比例从 ' + event.oldScale + ' 变为 ' + event.newScale);
          
          // 更新当前缩放比例(转换为百分比形式)
          // 例如:event.newScale为1.2,则pageFactor为120
          this.pageFactor = event.newScale;
        })
    }
  }
}

五、缩放比例计算

5.1 比例表示方式

表示法 示例 说明
百分比 150% 用户直观理解
小数 1.5 系统内部使用
整数 150 计算时使用(100=1.0)

5.2 zoom函数参数

参数值 效果 说明
1.0 原始大小 不缩放
>1.0 放大 如1.5放大50%
<1.0 缩小 如0.8缩小20%
0或负数 错误 无效参数

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐