Heim >WeChat-Applet >Mini-Programmentwicklung >Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

hzc
hzcnach vorne
2020-06-17 09:18:314741Durchsuche

Der erste Artikel im Jahr 2020. Ich war zu Beginn des Jahres damit beschäftigt, Fragen zu rezensieren und zu beantworten, und hatte nie Zeit, etwas zu schreiben. Je mehr Bücher ich lese, desto minderwertiger fühle ich mich gegenüber anderen . Ich hatte zufällig eine Leinwand in meinem letzten Projekt, die plötzlich mein UI-Front-End-Feuer entfachte, und ich schrieb die Fallstricke und Gedanken auf.

Obst

Frage 1: Warum sind auf Leinwand gezeichnete Bilder unscharf?

Beim Zeichnen von Bildern/Text auf Leinwand legen wir die Breite und Höhe der Leinwand fest: 375*667, und Sie werden feststellen, dass das gezeichnete Bild sehr verschwommen ist und sich wie ein Bild mit schlechter Auflösung anfühlt Der Text „Es“ scheint ebenfalls überlagert zu sein.

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Hinweis: Physische Pixel beziehen sich auf die kleinste Einheit, die auf dem Bildschirm eines Mobiltelefons angezeigt wird, während geräteunabhängige Pixel (logische Pixel) auf dem Computer verwendet werden Geräte Ein Punkt, der in CSS festgelegte Pixel bezieht sich auf das Pixel.

Grund: In der Frontend-Entwicklung kennen wir ein Attribut namens devicePixelRatio(设备像素比), das bestimmt, wie viele (normalerweise 2) physische Pixel beim Rendern der Schnittstelle zum Rendern eines geräteunabhängigen Pixels verwendet werden . .

Zum Beispiel werden bei einem Bild mit 100*100 Pixeln auf einem Retina-Bildschirm 2 Pixel verwendet, um ein Pixel des Bildes zu rendern, was einer Verdoppelung des Bildes entspricht, sodass das Bild entsteht verschwommen, weshalb 1 Pixel auf dem Retina-Bildschirm dicker wird.

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Lösung: Vergrößern Sie „canvas-width“ und „canvas-height“ um das Zweifache und reduzieren Sie die Breite und Höhe der Leinwandanzeige durch den Stil um das Zweifache. Mal.

Zum Beispiel:

<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>

Frage 2: Wie gehe ich mit der Konvertierung von px und rpx um?

rpx ist eine eindeutige Größeneinheit in Miniprogrammen, die je nach Bildschirmbreite angepasst werden kann. Auf dem iPhone6/iphonex entspricht 1rpx verschiedenen px. Daher ist es wahrscheinlich, dass Ihre Leinwandanzeige auf verschiedenen Mobiltelefonen inkonsistent ist.

Bevor wir das Poster zeichnen, basieren die Designentwürfe, die wir erhalten, normalerweise auf dem 2x-Bild des iPhone6. Und aus der Lösung des vorherigen Problems wissen wir, dass die Größe der Leinwand auch das Zweifache beträgt, sodass wir den Entwurfsentwurf des zweifachen Bildes direkt messen und die Leinwand direkt zeichnen können, und die Größe muss auf rpxtoPx geachtet werden .

/**
   * 
   * @param {*} rpx 
   * @param {*} int  //是否变成整数
   factor => 0.5 //iphone6
   pixelRatio => 2 像素比
   */
toPx(rpx, int) {
    if (int) {
      return parseInt(rpx * this.factor * this.pixelRatio)
    }
    return rpx * this.factor * this.pixelRatio
  }

Frage 3: Bei der Berechnung reiner Zahlen ist es 0 auf dem Mobiltelefon

bietet this.ctx.measureText(text).width im Miniprogramm zur Berechnung der Textlänge Wenn Sie jedoch alle 数字 verwenden, werden Sie feststellen, dass die API dies immer tut Es wird als 0 berechnet. Daher wird schließlich die simulierte MeasureText-Methode zur Berechnung der Textlänge verwendet.

measureText(text, fontSize = 10) {
    text = String(text)
    text = text.split('')
    let width = 0
    text.forEach(function(item) {
      if (/[a-zA-Z]/.test(item)) {
        width += 7
      } else if (/[0-9]/.test(item)) {
        width += 5.5
      } else if (/\./.test(item)) {
        width += 2.7
      } else if (/-/.test(item)) {
        width += 3.25
      } else if (/[\u4e00-\u9fa5]/.test(item)) { // 中文匹配
        width += 10
      } else if (/\(|\)/.test(item)) {
        width += 3.73
      } else if (/\s/.test(item)) {
        width += 2.5
      } else if (/%/.test(item)) {
        width += 8
      } else {
        width += 10
      }
    })
    return width * fontSize / 10
  }

Frage 4: Wie kann sichergestellt werden, dass eine Reihe von Schriftarten in der Mitte angezeigt wird? Wie viele Zeilen?

Wenn die Schriftart zu lang ist, überschreitet sie die Leinwandfläche, wodurch die Zeichnung hässlich wird. Zu diesem Zeitpunkt sollten wir den überschüssigen Teil so gestalten, dass er ...Sie können eine Breite und eine Schleife festlegen, um die Breite zu berechnen Wenn der Wert überschritten wird, verwenden Sie eine Teilzeichenfolge, um ... abzufangen und hinzuzufügen.

let fillText=''
let width = 350
for (let i = 0; i <= text.length - 1; i++) { // 将文字转为数组,一行文字一个元素
        fillText = fillText + text[i]
        // 判断截断的位置
        if (this.measureText(fillText, this.toPx(fontSize, true)) >= width) {
          if (line === lineNum) {
            if (i !== text.length - 1) {
              fillText = fillText.substring(0, fillText.length - 1) + '...'
            }
          }
          if (line <= lineNum) {
            textArr.push(fillText)
          }
          fillText = &#39;&#39;
          line++
        } else {
          if (line <= lineNum) {
            if (i === text.length - 1) {
              textArr.push(fillText)
            }
          }
        }
      }

Die im Textspiel gezeigte Berechnungsformel:

Zentrierung kann in der Leinwand verwendet werden (Breite der Leinwand - Breite des Textes)/2 + x (x ist die Bewegung des x- Achse der Schrift)

let w = this.measureText(text, this.toPx(fontSize, true))
this.ctx.fillText(text, this.toPx((this.canvas.width - w) / 2 + x), this.toPx(y + (lineHeight || fontSize) * index))

Frage 5: Wie verarbeite ich Netzwerkdiagramme in Miniprogrammen?

Was die Verwendung von Netzwerkbildern in Miniprogrammen, wie z. B. Bildern auf CDN, betrifft, müssen Sie für die lokale LRU-Verwaltung zu WeChat gehen, damit Sie beim späteren Zeichnen desselben Bildes Downloadzeit sparen können. Daher müssen Sie zunächst den legalen Domänennamen von downloadFile im Hintergrund des WeChat-Applets konfigurieren. Zweitens ist es am besten, das Bild im Voraus herunterzuladen und zu warten, bis das Bild heruntergeladen ist zu zeichnen, um Probleme mit Zeichnungsfehlern zu vermeiden.

Frage 6: Base64-Bilddaten können in der IDE zum Zeichnen festgelegt werden, aber sind sie auf der realen Maschine nutzlos?

Konvertieren Sie zuerst base64 in das Uint8ClampedArray-Format. Zeichnen Sie es dann über wx.canvasPutImageData(OBJECT, this) auf die Leinwand und exportieren Sie die Leinwand dann als Bild.

Frage 6: Wie zeichne ich ein Bild mit abgerundeten Ecken?

Frage 7: Über wx.canvasToTempFilePath

Nachdem Sie Canvas erfolgreich zum Zeichnen verwendet haben, rufen Sie diese Methode direkt auf, um Bilder zu generieren. Es gibt kein Problem in der IDE, aber die generierten Bilder sind unvollständig In diesem Fall können Sie ein setTimeout verwenden, um dieses Problem zu lösen.

this.ctx.draw(false, () => {
        setTimeout(() => {
            Taro.canvasToTempFilePath({
              canvasId: 'canvasid',
              success: async(res) => {
                this.props.onSavePoster(res.tempFilePath)//回调事件
                // 清空画布
                this.ctx.clearRect(0, 0, canvas_width, canvas_height)
              },
              fail: (err) => {
                console.log(err)
              }
            }, this.$scope)
          }, time)
    })

Frage 8: Über canvasContext.font

fontsize kann keine Dezimalzahlen verwenden Wenn der Schriftgrößenteil der Schriftarteinstellung Dezimalstellen enthält, ist die gesamte Schriftarteinstellung ungültig.

Frage 9: Die Schriftartwiedergabe ist auf Android falsch ausgerichtet?

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Dieses Problem tritt auf Android-Telefonen auf und iOS verhält sich normal. Als ich dieses Problem zum ersten Mal sah, konnte ich nicht herausfinden, warum einige in der Mitte waren, während andere viel weiter vorne waren. Später stellte ich fest, dass der Standardwert von this.ctx.setTextAlign(textAlign) unter Android center war, was zu Verwirrung führte. Nachdem er auf links geändert wurde, wurde er normal.

Frage 10: Zeichnen Sie ein Liniendiagramm

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Verwenden Sie Canvas, um ein einfaches Liniendiagramm zu zeichnen, verwenden Sie einfach lineTo und moveToVerbinden Sie einfach die beiden API Punkte. Verwenden Sie createLinearGradient, um Schatten zu zeichnen.

Denken

Denken 1: Einschränkungen bei der Verwendung der JSON-Konfigurationstabelle zum Generieren von Postern

Die heutige Postergeneration muss nur die Größe gemäß dem Designentwurf messen, aber die Messung Der Prozess ist immer noch sehr umständlich und in Bereichen, in denen der Entwurfsentwurf unzureichend ist, ist eine manuelle Feinabstimmung erforderlich. Später können Sie den Designentwurf auch per Drag & Drop auf der web-Seite fertigstellen und automatisch json generieren und auf das Poster des Miniprogramms anwenden.

Gedanke 2: Einschränkungen von Back-End-Postern

Poster wurden ursprünglich von Back-End-Klassenkameraden erstellt. Der Vorteil besteht darin, dass keine Front-End-Zeichnungszeit erforderlich ist Sie müssen die Fallstricke der WeChat-API und -Schnittstelle überwinden, um die URL abzurufen und anzuzeigen, aber der im Backend erzeugte Effekt ist schließlich nicht gut.

Gedanke 3: Einschränkungen der Front-End-Generierung von Postern

Wenn das Front-End Poster generiert, habe ich festgestellt, dass es länger dauert, einschließlich des lokalen Herunterladens des Bildes, und auch das Schreiben eines setTimeout speziell für Android, um ein normales Zeichnen sicherzustellen. Verschiedene Kompatibilitätsprobleme, DPR von Mobiltelefonen, Android und iOS und andere ununterbrochene Ostereier werden Sie kahl machen~ Hahahaha~

Ostereier

Es ist unmöglich, das neueste Canvas-2d zu verwenden Hintergrundbild Alle zeichnen?

Während des Entwicklungsprozesses von Canvas gab es immer einen Lichtblick im Miniprogramm, der mich daran erinnerte.

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Ich habe auch die neueste Canvas2d-API ausprobiert. Sie ist tatsächlich mit der Webseite synchronisiert und die Schreibmethode ist flüssiger Bei der Ausführung auf einem Mobiltelefon wird nur die Hälfte der Breite angezeigt. Dasselbe gilt auch beim Testen auf verschiedenen Modellen.

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Es ist in Ordnung, wenn Sie es später auf die Original-Leinwand ändern. . . Der konkrete Grund wurde in der WeChat-Community noch nicht gefunden. Wir werden ihn in nachfolgenden Iterationen und Upgrades untersuchen.

Wie man mit Canvas Poster in einem kleinen Programm zeichnet

Empfohlenes Tutorial: „JS-Tutorial

Das obige ist der detaillierte Inhalt vonWie man mit Canvas Poster in einem kleinen Programm zeichnet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen