键盘打开后导致水印重绘问题
咨询场景描述:
代码如下:
import { WaterMark } from './WaterMark'
@Entry
@Component
struct Test4{
private controller: SearchController = new SearchController()
@State private searchValue: string = '';
build() {
RelativeContainer(){
Column() {
Search({ value: this.searchValue, placeholder: '请输入姓名', controller: this.controller })
.height(32)
.margin({ left: '16vp', right: '16vp'})
.borderRadius(4)
.borderColor('0xDADADA')
.backgroundColor('#F5F5F5')
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.textFont({ size: 14, weight: 400 })
.onSubmit((value: string) => {
})
.onChange((value: string) => {
})
}
.id('page')
.alignRules({
top: {anchor: "__container__", align: VerticalAlign.Top},
bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
left: {anchor: "__container__", align: HorizontalAlign.Start},
right: {anchor: "__container__", align: HorizontalAlign.End}
})
WaterMark({message: '水印'})
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center },
})
.id('mark')
.width('100%')
.height('100%')
.hitTestBehavior(HitTestMode.None)
}
}
}
import { display } from '@kit.ArkUI';
@Component
export struct WaterMark {
@Prop
public message: string = '';
private readonly settings: RenderingContextSettings = new RenderingContextSettings(true);
private readonly context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
private lastMessage = '';
build() {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
this.context.rotate(-45);
this.paint();
})
.opacity(0.1);
}
paint() {
this.lastMessage = this.message;
const side = Math.max(px2vp(display.getDefaultDisplaySync().width), px2vp(display.getDefaultDisplaySync().height));
const canvasCenterX = 1.4 * side;
const phoneScreenCenterX = px2vp(display.getDefaultDisplaySync().width) / 2;
if (canvasCenterX > phoneScreenCenterX) {
this.context.translate(phoneScreenCenterX - canvasCenterX, 0);
} else {
this.context.translate(phoneScreenCenterX - canvasCenterX, 0);
}
let x = 0;
let y = 0;
const timeStr = new Date().getTime() + '';
this.context.font = '50px sans-serif';
const textWidth = this.context.measureText(this.message).width;
const textHeight = this.context.measureText(this.message).height;
const timeWidth = this.context.measureText(timeStr).width;
const maxWidth = Math.max(textWidth, timeWidth);
const minWidth = Math.min(textWidth, timeWidth);
const xGap = (maxWidth - minWidth) / 4;
for (let i = 0; i < 15; i++) {
for (let j = 0; j < 15; j++) {
this.context.font = '50px sans-serif';
this.context.fillText(this.message, x, y);
this.context.font = '40px sans-serif';
this.context.fillText(timeStr, x - xGap, y + textHeight - 5);
x += maxWidth + 70;
}
if (i % 2 == 0) {
x = 0;
} else {
x = 80;
}
y += textHeight + 85;
}
}
}
当前水印会抖动根因是:设置了页面键盘避让模式为resize,所以会压缩页面,页面压缩会导致元素大小发生变化,这些都是当前规格,然后canvas的规格是只要发生了大小改变会重新onReady,导致水印重绘,而目前的逻辑是去屏幕的中心点来进行绘制,所以会出现上移下移的动作目前方案,Canvas画布设置固定大小,底部大小改变的时候不应先不管canvas画布大小设置,水印不会产生变化demo如下: