WeChat-Applet --- Leinwand

Offizielle Canvas-Website: CanvasRenderingContext2D.canvas – Web-APIs | MDN

Mini-Programm-Canvas-Komponente: canvas | WeChat Open Documentation

1. Zwei Arten von Cavnas, um Kontext zu erhalten

Alte Version der createCanvasContext-Methode

createCanvasContextEs ist eine alte Schnittstelle, die von WeChat bereitgestellt wird, um canvaseine Instanz , und ihre Verwendung ist wie folgt.

wxml

<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>

Ein guter Tag hello,worldbeginnt damit, einen zu schreiben.

schreibe in js so

onReady(){
    /*  使用 wx.createContext 获取绘图上下文 context , firstCanvas 与 canvas 属性中的canvas-id一一对应  */
    const context = wx.createCanvasContext('firstCanvas')
    /* 设置字体大小 */
    context.setFontSize(20) 
    /* 设置字体颜色 */
    context.setFillStyle('pink')
    /* 设置文本内容,位置 */
    context.fillText('hello,world', 0, 0)
    context.draw()
}

Die alte Version verwendet das Attribut im createCanvasContexteingehenden canvasTag , canvas-idum die Instanz zu erhalten canvas. Um ehrlich zu sein, ist die alte Version nicht flexibel genug. Viele canvasEinstellungen für Linien und Farben sind in Methoden gekapselt, und Methoden müssen jedes Mal aufgerufen werden, wenn sie geändert werden.

Neue Version getContext Kontextmodus (2.9.0)

Der neue Weg besteht darin createSelectorQuery, canvaszuerst den Elementknoten durchzubekommen und dann getContextden Kontext durchzubekommen .

wxml

 <canvas type="2d" id="myCanvas"></canvas>

js

const query = wx.createSelectorQuery()
query.select('#myCanvas')
.fields({
    node: true,
    size: true
})
.exec((res)=>{
    const { node } = res[0]
    if (!node) return
    /* 获取 canvas 实例 */
    const context = node.getContext('2d')
    context.fillStyle = 'pink'
    /* 设置字体样式 大小 字体类别 */
    context.font = 'normal 400 12px PingFangSC-Regular',
    context.fillText('hello,world', 0, 0)
})

Diese Methode und die erste createSelectorQueryMethode haben subtile Unterschiede in der Art der Verwendung der API. Diese Art des Schreibens ähnelt eher der ursprünglichen Art des DOMSchreibens, das Festlegen von Farben, Stilen contextund das direkte Ändern von Attributen, ohne die entsprechenden aufzurufen api.

1. In Bezug auf Breite, Höhe und Zoomverhältnis der Leinwand sind die gezeichneten Elemente deformiert. Entspricht die Höhe der Leinwand wirklich der Breite und Höhe, die durch das Cavans-Label festgelegt werden?

Containerbreite und -höhe : Die Breite und Höhe, die wir canvasfür das Etikett festlegen, wie im obigen Code  canvasStyle, ist canvasdie Breite und Höhe des Containers. 

Breite und Höhe der Leinwandapi : In der neuen Version werden die Breite  und  Höhe unserer Leinwand nodedynamisch festgelegt, indem Knoten abgerufen werden .node.widthnode.height

Containerbreite und -höheLeinwandbreite

 Die Leinwand des Applets canvashat eine ursprüngliche Leinwandbreite und -höhe sowie ein Zoomverhältnis und basiert auf dem doppelten Pixel.Nachdem wir die Containerbreite und -höhecanvas für den Container festgelegt haben , ist die Leinwandbreite und -höhe die Leinwand nicht entsprechend eingestellt sind , wird die gezeichnete Leinwand stark verformt. Wenn wir davon ausgehen, den gesamten Bildschirm als Leinwand zu verwenden, variiert die Bildschirmgröße für verschiedene Mobiltelefone, sodass wir die Breite und Höhe des Geräts dynamisch abrufen müssen.canvasscale

2. Leinwand zeichnet Bilder

 api-drawImage : CanvasContext.drawImage(string imageResource, Zahl sx, Zahl sy, Zahl sWidth, Zahl sHeight, Zahl dx, Zahl dy, Zahl dWidth, Zahl dHeight) | WeChat Open Documentation

Netzwerkbild : Zuerst müssen Sie übergeben, getImageInfoum den temporären Pfad des Bildes zu erhalten. Bitte achten Sie beim getImageInfoZiehen von Netzwerkressourcen darauf, einen legalen Download-Domainnamen zu konfigurieren, da wir sonst keine Bildinformationen erfolgreich erhalten können. Wir müssen zuerst den legalen Domänennamen im Hintergrund des Applets konfigurieren downloadFile.

api-getImageInfp : wx.getImageInfo(Object object) | WeChat Open Documentation

/* backGroundImageUrl 是我们要画的网络图片的地址  */
 this.getImageInfo(backGroundImageUrl).then(res=>{
      const {
        width,   /* 宽度 */
        height,  
        path     /* 临时路径 */
      } = res1
      /* 第二步: 绘图 */
    this.drawImage(context, node, path, 0, 0, width, height, 0, 0, 0, 0)

 })


Lokales Bild : Ziehen Sie direkt aus canvasdem bereitgestellten Bild .drawImage

const image = node.createImage();
image.src = url image.onload = () => {         
  context.drawImage(image,x,y,width,height,dx,dy,dwidth,dheight)
}

Wie zeichnet die Leinwand zwei gestapelte Bilder und steuert die Ebene?

Als erstes fällt mir das Ebenenproblem ein: Wir erwarten, dass das Hintergrundbild darunter platziert wird, aber es gibt keine Eigenschaft, um die Ebene im Canvas zu steuern zIndex. In der Praxis entspricht die Zeichnungsreihenfolgecanvas der Reihenfolge der Canvas-Hierarchie, und die obere Ebene wird zuerst gezeichnet, sodass wir für diese Art von hierarchischem Problem nur sicherstellen müssen, dass die Elemente der höheren Ebene später gezeichnet werden und die unteren Levelelemente werden zuerst gezeichnet und können perfekt gelöst werden.

3. Wie verwende ich die Leinwand, um mehrzeiligen Text zu zeichnen?

Zeichnen Sie Zeichen nacheinander in die Leinwand und addieren Sie dann die Breite jedes Zeichens. Wenn die Gesamtbreite größer als die Containerbreite ist, nehmen Sie eine weitere Linie und zeichnen Sie erneut

       /** 画多行文本
         * @param ctx          canvas 上下文
         * @param str          多行文本
         * @param initHeight   容器初始 top值
         * @param initWidth    容器初始 left值
         * @param canvasWidth  容器宽度
         */
        drawRanksTexts(ctx, str, initHeight, initWidth, canvasWidth) {
            let lineWidth = 0;
            let lastSubStrIndex = 0;
            /* 设置文字样式 */
            ctx.fillStyle = "#303133"
            ctx.font = 'normal 400 15px  PingFangSC-Regular'
            for (let i = 0; i < str.length; i++) {
                lineWidth += ctx.measureText(str[i]).width
                if (lineWidth > canvasWidth) { /* 换行 */
                    ctx.fillText(str.substring(lastSubStrIndex, i), initWidth, initHeight)
                    initHeight += 20
                    lineWidth = 0
                    lastSubStrIndex = i
                }
                if (i == str.length - 1) {  /* 无需换行 */
                    ctx.fillText(str.substring(lastSubStrIndex, i + 1), initWidth, initHeight)
                }
            }

        },

überweisen

/* TODO: 复制多行文本 */
const rowsText = await this.geDomPostion('#context', true)
this.drawRanksTexts(context, this.skuName, rowsText.top, rowsText.left, rowsText.width)

4. Speichern Sie das Poster

Exportieren Sie den Inhalt des angegebenen Bereichs der aktuellen Leinwand, um ein Bild der angegebenen Größe zu erzeugen

api-canvasToTempFilePath : wx.canvasToTempFilePath(Object object, Object this) | WeChat Open Documentation

Speichern Sie Bilder im Systemalbum

 api-saveImageToPhotosAlbum : wx.saveImageToPhotosAlbum(Object object) | WeChat Open Documentation


Autor: Ich bin kein Außerirdischer
Link: https://juejin.cn/post/6930404573043490830
Quelle: Rare Earth Nuggets
Das Urheberrecht liegt beim Autor. Für den kommerziellen Nachdruck wenden Sie sich bitte zwecks Genehmigung an den Autor, für den nicht kommerziellen Nachdruck geben Sie bitte die Quelle an.

おすすめ

転載: blog.csdn.net/weixin_38961329/article/details/122856077