Comment utiliser Canvas pour dessiner des affiches dans un petit programme

hzc
Libérer: 2020-06-17 09:29:16
avant
4704 Les gens l'ont consulté

Le premier article en 2020. J'étais occupé à réviser et à répondre aux questions au début de l'année et je n'ai jamais eu le temps d'écrire quoi que ce soit. Plus je lis de livres, plus je me sens inférieur aux autres. Il se trouve que j'avais une toile dans mon récent projet. L'entreprise a soudainement rallumé le feu de mon interface utilisateur, et j'ai noté les pièges et les réflexions.

Fruits

Question 1 : Pourquoi les images dessinées sur toile sont-elles floues ?

Lorsque nous dessinons des images/textes sur toile, nous définissons la largeur et la hauteur de la toile : 375*667, et vous constaterez que l'image dessinée est très floue, et elle ressemble à une image avec une mauvaise résolution, et le texte Il semblera également se superposer.

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Remarque : les pixels physiques font référence à la plus petite unité affichée sur l'écran d'un téléphone mobile, tandis que les pixels indépendants de l'appareil (pixels logiques) dans un ordinateur devices Un point, le pixel défini en CSS fait référence au pixel.

Raison : Dans le développement front-end, nous connaissons un attribut appelé devicePixelRatio(设备像素比), qui détermine combien (généralement 2) de pixels physiques seront utilisés pour restituer un pixel indépendant du périphérique lors du rendu de l'interface. .

Par exemple, une image de 100*100 pixels, sur un écran Retina, utilisera 2 pixels pour restituer un pixel de l'image, ce qui équivaut à doubler l'image, donc l'image deviendra floue, ce qui c'est pourquoi 1px devient plus épais sur les écrans Retina.

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Solution : Agrandissez la largeur et la hauteur de la toile de 2 fois, et réduisez la largeur et la hauteur d'affichage de la toile de 2 fois grâce au style. Times.

Par exemple :

<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
Copier après la connexion

Question 2 : Comment gérer la conversion des px et rpx ?

rpx est une unité de taille unique dans les mini programmes, qui peut être adaptée en fonction de la largeur de l'écran. Sur iPhone6/iphonex, 1rpx est égal à différents px. Par conséquent, il est probable que l’affichage de votre toile soit incohérent sous différents téléphones mobiles.

Avant de dessiner l'affiche, les ébauches de conception que nous obtenons sont généralement basées sur l'image 2x de l'iPhone6. Et d'après la solution au problème précédent, nous savons que la taille de la toile est également 2 fois, nous pouvons donc mesurer directement le brouillon de conception de 2 fois l'image et dessiner directement la toile, et la taille doit être prise en compte par rpxtoPx .

/**
   * 
   * @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
  }
Copier après la connexion

Question 3 : Concernant canvasContext.measureText, lors du calcul de nombres purs, c'est 0 sur le téléphone portable

fournit this.ctx.measureText(text).width dans le mini programme pour calculer la longueur du texte. , mais si vous utilisez all 数字, vous constaterez que l'API sera toujours calculée comme 0. Par conséquent, la méthode simulée MeasureText est finalement utilisée pour calculer la longueur du texte.

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
  }
Copier après la connexion

Question 4 : Comment s'assurer qu'une ligne de polices s'affiche au centre ? Combien de lignes ?

Si la police est trop longue, elle dépassera la toile, rendant le dessin moche. À ce stade, nous devrions faire en sorte que la partie excédentaire devienne ...Vous pouvez définir une largeur et des calculs de boucle pour calculer la valeur. largeur du texte. Si s'il dépasse, utilisez la sous-chaîne pour intercepter et ajouter ....

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)
            }
          }
        }
      }
Copier après la connexion

La formule de calcul affichée dans la lecture du texte :

Le centrage peut être utilisé dans le canevas (largeur du canevas - largeur du texte)/2 + x (x est le mouvement du x- axe de la police)

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))
Copier après la connexion

Question 5 : Comment traiter les schémas de réseau dans les mini programmes ?

Concernant l'utilisation d'images réseau dans des mini programmes, tels que les images sur CDN, vous devez descendre sur WeChat pour la gestion LRU locale, afin de pouvoir gagner du temps de téléchargement lorsque vous dessinerez la même image plus tard. Donc tout d'abord, vous devez configurer le nom de domaine légal de downloadFile en arrière-plan de l'applet WeChat. Deuxièmement, avant de dessiner sur le canevas, il est préférable de télécharger l'image à l'avance et d'attendre que l'image soit téléchargée avant de commencer. dessiner pour éviter certains problèmes d'échec de dessin.

Question 6 : Les données d'image Base64 peuvent être définies dans l'EDI pour le dessin, mais sont-elles inutiles sur la vraie machine ?

Convertissez d'abord base64 au format Uint8ClampedArray. Dessinez-le ensuite sur la toile via wx.canvasPutImageData(OBJECT, this), puis exportez la toile sous forme d'image.

Question 6 : Comment dessiner une image aux coins arrondis ?

Question 7 : À propos de wx.canvasToTempFilePath

Après avoir utilisé avec succès Canvas pour dessiner, appelez directement cette méthode pour générer des images. Il n'y a pas de problème sur l'EDI, mais les images générées seront incomplètes. la vraie machine Dans ce cas, vous pouvez utiliser un setTimeout pour résoudre ce problème.

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)
    })
Copier après la connexion

Question 8 : À propos de canvasContext.font

fontsize ne peut pas utiliser de décimales Si la partie taille de police du paramètre de police contient des décimales, l’ensemble du paramètre de police sera invalide.

Question 9 : Le rendu des polices est mal aligné sur Android ?

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Ce problème se produit sur les téléphones Android, iOS se comporte normalement. Quand j'ai vu ce problème pour la première fois, je n'arrivais pas à comprendre pourquoi certains étaient au milieu alors que d'autres étaient beaucoup plus en avant. Plus tard, j'ai découvert que la valeur par défaut de this.ctx.setTextAlign(textAlign) sous Android était center, ce qui a semé la confusion. Après l'avoir changé à gauche, c'est devenu normal.

Question 10 : Dessinez un graphique linéaire

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Utilisez Canvas pour dessiner un graphique linéaire simple, utilisez simplement lineTo et moveToConnectez simplement les deux API points. Utilisez createLinearGradient pour dessiner des ombres.

Réflexion

Réflexion 1 : Limites de l'utilisation de la table de configuration json pour générer des affiches

La génération d'affiches d'aujourd'hui n'a besoin que de mesurer la taille en fonction du brouillon de conception, mais la mesure Le processus reste très lourd et un réglage manuel est nécessaire dans les domaines où le projet de conception est insuffisant. Plus tard, vous pouvez également utiliser le glisser-déposer pour terminer le brouillon de conception du côté web, générer automatiquement json et l'appliquer à l'affiche du mini programme.

Pensée 2 : Limites des affiches générées par le back-end

Les affiches ont été initialement générées par des camarades de classe du back-end. L'avantage est que cela ne nécessite pas de temps de dessin au préalable, et il n'y en a pas. Il faut marcher sur les pièges de l'API et de l'interface WeChat. Revenez pour obtenir l'URL et l'afficher, mais l'effet généré sur le back-end n'est pas bon après tout, ce genre de travail est plus front-end.

Pensée 3 : Limites de la génération frontale d'affiches

Lorsque le front-end génère des affiches, j'ai trouvé que cela prend plus de temps, y compris le téléchargement de l'image localement, et qu'il faut également écrire un setTimeout spécifiquement pour Android pour garantir un dessin normal. Divers problèmes de compatibilité, DPR des téléphones mobiles, Android et iOS et autres œufs de Pâques non-stop vous rendront chauve ~ Hahahaha ~

Oeufs de Pâques

Il est impossible d'utiliser la dernière toile-2d image de fond Les dessiner tous ?

Pendant le processus de développement de Canvas, il y avait toujours une lueur de lumière dans le mini programme pour me le rappeler.

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

J'ai également essayé la dernière API canvas2d Elle est en effet synchronisée avec le côté web et la méthode d'écriture est plus fluide. outils de développement. Tout fonctionne bien lors de l'exécution sur un téléphone mobile, seule la moitié de la largeur est affichée. La même chose est vraie lors des tests sur différents modèles.

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Ce sera bien si vous le remplacez par la toile d'origine plus tard. . . La raison spécifique n'a pas encore été trouvée dans la communauté WeChat. Nous l'étudierons dans les itérations et mises à niveau ultérieures.

Comment utiliser Canvas pour dessiner des affiches dans un petit programme

Tutoriel recommandé : "Tutoriel JS"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal