WebAssembly实战:Badge 生成器

发布于 2019-11-16 15:27:25 阅读 278

首先,使用WebAssembly可以隐藏你的代码逻辑,但是隐藏的背后就是别人拿到你的wasm文件后,直接可以用了,可以在wasm中做一个身份验证处理,验证成功后才进行下面的操作。

首先先给大家看下结果

WX20191116-151603@2x.png

上图有4个输入框,上下两个分别为前后badge徽章的文字以及背景图,至于字体的颜色,我是根据背景图的颜色做计算的,如果背景是深色,那么字体就是白色,如果背景是浅色,那么字体就是黑色。

WX20191116-152045@2x.png

这个html文件除了引用了wasm_exec.js还有我们使用go转换成的WebAssembly文件:main.wasm,非常精简,因为所有的处理逻辑都在wasm文件中。

那我们来看下wasm编译前的main.go源码。

var paddingLength = 10
    c := make(chan struct{}, 0)
    document := js.Global().Get("document")
    badgeSuffix := document.Call("getElementById", "badge-suffix")
    suffixBGColor := document.Call("getElementById", "suffix-bg-color")

    badgePrefix := document.Call("getElementById", "badge-prefix")
    prefixBGColor := document.Call("getElementById", "prefix-bg-color")

    createBtn := document.Call("getElementById", "create-btn")

    btnCallback := js.FuncOf(func(this js.Value, i []js.Value) interface{} {
        var width = 225
        var height = 20
        var fSize = 11
        var rx float64 = 3

        lBGColor := prefixBGColor.Get("value").String()
        var lText = badgePrefix.Get("value").String()
        var lColor = lBGColor
        var lFColor = setFontColor(lBGColor)
        var lLength float64 = 124
        var lX float64 = 62

        rBGColor := suffixBGColor.Get("value").String()
        var rText = badgeSuffix.Get("value").String()
        var rColor = rBGColor
        var rFColor = setFontColor(rBGColor)
        var rLength float64 = 101
        var rX float64 = 175
        badge := SetBadge(width, height, fSize, rx, lText, lColor, lFColor, lLength, lX, rText, rColor, rFColor, rLength, rX)
        res, err := badge.Template()
        if err != nil {
            fmt.Println("save badge error !!!")
            fmt.Println(err)
        }
        //为了获取当前svg的box,需要将当前的svg显示在页面上,然后通过js获取
        svgResultDivContainer := document.Call("createElement", "div")
        svgResultDivContainer.Call("setAttribute", "id", "svg-result")
        svgResultDivContainer.Set("innerHTML", res)
        document.Get("body").Call("appendChild", svgResultDivContainer)

        lBBoxWidth:= document.Call("getElementById", "left_text").Call("getBBox", nil).Get("width").Int()
        lLength = (float64)(lBBoxWidth + paddingLength)
        lX = lLength / 2


        rBBoxWidth:= document.Call("getElementById", "right_text").Call("getBBox", nil).Get("width").Int()
        rLength = (float64)(rBBoxWidth + paddingLength)
        rX = rLength / 2 + lLength
        width = (int)(rLength + lLength)

        //再次生成svg源码
        badge = SetBadge(width, height, fSize, rx, lText, lColor, lFColor, lLength, lX, rText, rColor, rFColor, rLength, rX)
        res, err = badge.Template()
        if err != nil {
            fmt.Println("save badge error !!!")
            fmt.Println(err)
        }
        svgResultDivContainer = document.Call("getElementById", "svg-result")
        svgResultDivContainer.Set("innerHTML", res)
        fmt.Println("svg source code")
        fmt.Println(res)
        createBtn.Call("remove", nil )
        return nil
    })

    createBtn.Call("addEventListener", "click", btnCallback)
    fmt.Println("WebAssembly start...")
    <-c

代码很简单,和上一篇文章的结构相似,只不过多了n行生成svg的代码。因为我需要获取svg中的字体的长宽信息,所以代码中出现了两次生成svg的函数SetBadge,其中第一次是需要我在页面获取文字的宽度,然后计算显示适合的长度信息。

有兴趣的可以点击看看