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.
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.
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.
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>
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 }
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 }
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 = '' line++ } else { if (line <= lineNum) { if (i === text.length - 1) { textArr.push(fillText) } } } }
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))
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.
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.
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) })
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.
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.
Utilisez Canvas pour dessiner un graphique linéaire simple, utilisez simplement lineTo
et moveTo
Connectez simplement les deux API
points. Utilisez createLinearGradient
pour dessiner des ombres.
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.
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.
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 ~
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.
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.
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.
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!