kiccer / wx-canvas-2d

微信小程序 canvas-2d 绘图工具🖌️🧑‍🎨 | 支持按需加载🍃,支持内容配置🧩,支持功能扩展🔥 | 适配各种机型📱,超轻量☁️,超易用⚪,无需学习📚️,直接上手🚀
https://kiccer.github.io/wx-canvas-2d/
MIT License
86 stars 10 forks source link

获取字体宽度 #30

Closed xuannfx closed 4 months ago

xuannfx commented 4 months ago

我的目标是测量名称的宽度,从而相应地设置名称标签背景的宽度,以使得标签能容纳对应名称,但是发现测出来的结果不符合预期,文本进行了换行,标签背景的宽度也不正确。另外,在不同dpr机型的上效果也不一致。请教一下是哪里出了问题。

const {
    WxCanvas2d,
    Debugger,
    SaveToAlbum,
    Image,
    Text,
    Rect,
    Line,
    Qrcode
} = requirePlugin('wx-canvas-2d')

WxCanvas2d.use(Debugger)
WxCanvas2d.use(SaveToAlbum)

const canvas = new WxCanvas2d()
console.log({ canvas })

Component({
    /**
     * 组件的属性列表
     */
    properties: {
        show: {
            type: Boolean,
            default: false
        },
        item: {
            type: Object,
            default: {}
        }
    },

    /**
     * 组件的初始数据
     */
    data: {

    },

    lifetimes: {
        attached () {
            setTimeout(() => {
                // 创建
                canvas.create({
                    query: '.poster-canvas', // 必传,canvas元素的查询条件
                    rootWidth: 750, // 参考设备宽度 (即开发时UI设计稿的宽度,默认375,可改为750)
                    bgColor: '#fff', // 背景色,默认透明
                    component: this, // 自定义组件内需要传 this
                    radius: 16 // 海报图圆角,如果不需要可不填
                }).then(() => {
                    console.log('画布创建成功')
                }).catch(err => {
                    console.log('画布创建失败: ', err)
                })
            }, 500)
        },
        detached () {
            // 在组件实例被从页面节点树移除时执行
        }
    },

    /**
     * 组件的方法列表
     */
    methods: {
        onClose () {
            // canvas.clear()
            this.triggerEvent('close')
        },

        onAfterEnter () {
            if (!this.properties.item) return

            const { item } = this.properties
            const name = 22;    // 名称字体大小
            const type = 12;    // 类别字体大小
            const padding = 6;  // 文字左右边距

            // 文字宽度
            const nameWidth = canvas.xDpr(canvas.ctx.measureText(item.name).width);
            const typeWidth = canvas.xDpr(canvas.ctx.measureText(item.type).width);

            // 绘制
            canvas.draw({
                series: [
                    {
                        type: Rect,
                        x: 30,
                        y: 620,
                        bgColor: '#f22',
                        width: nameWidth + padding,
                        height: name + 20,
                        radius: 24
                    },{
                        type: Text,
                        text: item.name,
                        x: 30,
                        y: 620,
                        color: '#222',
                        fontSize: name,
                        lineHeight: name + 20,
                        width: nameWidth + padding,
                        align: 'center',
                    },
                    {
                        type: Rect,
                        x: 150,
                        y: 672,
                        bgColor: '#222',
                        width: typeWidth + padding,
                        height: type + 20,
                        radius: 24
                    },{
                        type: Text,
                        text: item.type,
                        x: 150,
                        y: 672,
                        color: '#fff',
                        fontSize: type,
                        lineHeight: type + 20,
                        width: nameWidth + padding,
                        align: 'center',
                    },

                    // 其他绘制元素
                ]
            }).then(() => {
                console.log('绘制成功!')
            }).catch(err => {
                console.log('绘制失败!', err)
            })
        }
    }
})
xuannfx commented 4 months ago
// 测量文本宽度
measureTextWidth(text, fontSize, fontWeight = '', fontFamily = canvas.fontFamily) {
    const originalFont = canvas.ctx.font; // 保存原始字体样式
    canvas.ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`; // 设置新的字体样式

    const width = canvas.ctx.measureText(text).width; // 测量文本宽度
    canvas.ctx.font = originalFont; // 恢复原始字体样式

    return width;
},

// 画图
onAfterEnter () {
……
// 文字宽度
const nameWidth = this.measureTextWidth(item.name, name);
const typeWidth = this.measureTextWidth(item.type, type);
……
}