ホームページ > 記事 > WeChat アプレット > キャンバスを使用して小さなプログラムでポスターを描画する方法
2020年最初の記事です。年始はレビューと質問への回答に追われて、何も書く暇がありませんでした。本を読めば読むほど、他人と比べて劣等感を感じるようになります。私はずっと初心者でした。最近のプロジェクトにたまたまキャンバスがあり、そのビジネスが突然 UI フロントエンドの火に再び火をつけ、落とし穴と考えを書き留めました。
キャンバスに絵や文字を描くとき、キャンバスの幅と高さを 375*667 に設定します。描かれた絵は非常にぼやけていて、解像度の低い絵のように感じられます。も重なっているように見えます。
#注: 物理ピクセルは携帯電話の画面に表示される最小単位を指しますが、デバイスに依存しないピクセル (論理ピクセル) )コンピュータデバイスのA点、cssで設定したピクセルを指します。理由: フロントエンド開発では、
devicePixelRatio (デバイス ピクセル比) というプロパティがあることがわかっています。このプロパティは、使用されるピクセルの数 (通常は 2) を決定します。 ) デバイスに依存しないピクセルをレンダリングするための物理ピクセル。
ポスターを描く前に、私たちが受け取るデザイン案は通常、iPhone6 の 2 倍の画像に基づいています。そして、前の問題の解決策から、キャンバスのサイズも 2 倍であることがわかっているので、絵の 2 倍のデザイン案を直接測定してキャンバスを直接描画することができ、サイズは 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 }
質問 3 :canvasContext.measureText について純粋な数値を計算する場合、携帯電話では 0 になります。
はテキストの長さを計算するために提供されていますが、すべての
digitsが使用されている場合、API は常に 0 に計算することがわかります。そのため、シミュレートされたmeasureText メソッドが最終的に使用されます。テキストの長さを計算します。
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 }
フォントが長すぎるとキャンバスからはみ出してしまい、描画が汚くなってしまいますので、このときはみ出した部分は ...
幅と幅を設定することができます。ループで計算する テキストの幅を抽出し、幅を超える場合は部分文字列で切り取って ...
を追加します。
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) } } } }
キャンバスの中央揃えが使用可能 (キャンバスの幅 - テキストの幅)/2 x (x は x 軸の移動量)フォントの) <pre class="brush:php;toolbar:false">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))</pre>
質問 5: ミニ プログラムでネットワーク図を処理するにはどうすればよいですか? ミニ プログラムでのネットワーク イメージ (CDN 上のイメージなど) の使用については、ローカル LRU 管理のために WeChat にアクセスする必要があります。これにより、後で同じイメージを描画するときにダウンロード時間を節約できます。したがって、まず、WeChat アプレットのバックグラウンドで downloadFile の正当なドメイン名を設定する必要があります。次に、キャンバスに描画する前に、事前に画像をダウンロードし、画像がダウンロードされるのを待ってから開始することをお勧めします。描画失敗の問題を回避するために描画します。
質問6: Base64の画像データはIDEでは描画用に設定できますが、実機では使えないのでしょうか?
まず、base64 を
Uint8ClampedArrayを通じてキャンバスに描画し、キャンバスを画像としてエクスポートします。
質問 7: wx.canvasToTempFilePath についてCanvas を使用して描画に成功した後、このメソッドを直接呼び出して画像を生成します。IDE 上では問題ありませんが、生成された画像は IDE 上では不完全になります。この場合、setTimeout を使用してこの問題を解決できます。
<pre class="brush:php;toolbar:false">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)
})</pre>質問 8: CanvasContext.font<h3 class="heading" data-id="heading-7">フォントサイズについては小数を使用できません
フォント設定のフォントサイズ部分に小数が含まれる場合、フォント設定全体が無効になります。 </h3>
<h3 class="heading" data-id="heading-10"> 質問 9: Android ではフォントのレンダリングがずれていますか? </h3>
<figure><img class="lazyload" src="https://img.php.cn/upload/article/000/000/051/9b18b104b923aa9857d906b6cf7849c7-2.jpg" data- style="max-width:90%" data- style="max-width:90%" alt="キャンバスを使用して小さなプログラムでポスターを描画する方法" ><figcaption></figcaption></figure>#この問題は Android スマートフォンで発生しますが、iOS は正常に動作します。私がこの問題を初めて見たとき、なぜあるものは真ん中にあり、他のものはずっと前にあるのか理解できませんでした。後で調べたら、Android では <p>this.ctx.setTextAlign(textAlign) <code>default が
center になっていて混乱していましたが、左に変更したら正常になりました。
lineTo # を使用するだけです。 ## と moveTo
は、2 つの API
の点を接続するだけです。 createLinearGradient
を使用して影を描画します。 考え方
側でデザイン案を完成させ、json
を自動生成してミニプログラムのポスターに適用することもできます。 考え方 2: バックエンドで生成されたポスターの制限
考察 3: フロントエンドでのポスター生成の制限
イースター エッグ
以上がキャンバスを使用して小さなプログラムでポスターを描画する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。