鸿蒙 uni-app ctx.measureText方法报错
鸿蒙 uni-app ctx.measureText方法报错
| 项目信息 | 描述 |
|---|---|
| 产品分类 | uniapp/App |
| PC开发环境操作系统 | Mac |
| PC开发环境操作系统版本号 | macOS Ventura 13.0 |
| HBuilderX类型 | Alpha |
| HBuilderX版本号 | 4.86 |
| 手机系统 | HarmonyOS NEXT |
| 手机系统版本号 | HarmonyOS 5.1.0 |
| 手机厂商 | 华为 |
| 手机机型 | nova 13 |
| 页面类型 | vue |
| vue版本 | vue3 |
| 打包方式 | 云端 |
| 项目创建方式 | HBuilderX |
# 示例代码:
```html
<template>
<view>
<view>
<canvas style="width: 355px; height: 350px;" canvas-id="myCanvas" id="myCanvas"></canvas>
</view>
<view>
<button @click="test"> 生成</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
app: undefined
}
},
onLoad(options) {
// this.test()
},
onUnload() {},
methods: {
test(){
try{
const ctx = uni.createCanvasContext('myCanvas')
let word = 'Hello World'
// ctx.font = 'italic bold 20px cursive'
ctx.setFontSize(30)
const metrics = ctx.measureText(word,(metricsWidth => {
console.log(metricsWidth)
}))
console.log(metrics.width)
ctx.fillText(word,10, 50)
// ctx.fill()
ctx.draw()
}catch(e){
console.log(e);
}
}
}
}
</script>
<style>
.book-name {
text-align: center;
}
</style>
操作步骤:
- 根据示例点击生成按钮
预期结果:
- 输出宽度
实际结果:
- 抛错误:
TypeErrorwebview.evalJSAsync(…).then is not a function
bug描述:
- 根据文档里 ctx.measureText在HarmonyOS Next要用异步的方式获取文本宽度,但是会抛错:
TypeErrorwebview.evalJSAsync(…).then is not a function

更多关于鸿蒙 uni-app ctx.measureText方法报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
在HarmonyOS NEXT环境下,ctx.measureText的异步调用方式存在问题。根据uni-app官方文档,在HarmonyOS平台需要使用回调函数获取文本度量信息,但当前实现存在兼容性问题。
建议改用以下两种方案:
方案一:使用同步polyfill
// 在调用measureText前添加兼容代码
if (!ctx.measureText.__original) {
ctx.measureText.__original = ctx.measureText;
ctx.measureText = function(text) {
return { width: text.length * this.fontSize * 0.5 }; // 估算宽度
}
}
const metrics = ctx.measureText(word);
console.log(metrics.width);
方案二:延迟绘制
ctx.setFontSize(30);
ctx.fillText(word, 10, 50);
ctx.draw(true, () => {
// 在draw完成后通过其他方式获取文本尺寸
uni.createSelectorQuery().select('#myCanvas').boundingClientRect(res => {
console.log('Canvas尺寸:', res);
}).exec();
});

