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.
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.
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.
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>
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 }
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 }
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 = '' 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))
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.
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.
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) })
fontsize kann keine Dezimalzahlen verwenden Wenn der Schriftgrößenteil der Schriftarteinstellung Dezimalstellen enthält, ist die gesamte Schriftarteinstellung ungültig.
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.
Verwenden Sie Canvas, um ein einfaches Liniendiagramm zu zeichnen, verwenden Sie einfach lineTo
und moveTo
Verbinden Sie einfach die beiden API
Punkte. Verwenden Sie createLinearGradient
, um Schatten zu zeichnen.
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.
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.
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~
Während des Entwicklungsprozesses von Canvas gab es immer einen Lichtblick im Miniprogramm, der mich daran erinnerte.
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.
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.
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!