ホームページ  >  記事  >  WeChat アプレット  >  キャンバスを使用して小さなプログラムでポスターを描画する方法

キャンバスを使用して小さなプログラムでポスターを描画する方法

hzc
hzc転載
2020-06-17 09:18:314701ブラウズ

2020年最初の記事です。年始はレビューと質問への回答に追われて、何も書く暇がありませんでした。本を読めば読むほど、他人と比べて劣等感を感じるようになります。私はずっと初心者でした。最近のプロジェクトにたまたまキャンバスがあり、そのビジネスが突然 UI フロントエンドの火に再び火をつけ、落とし穴と考えを書き留めました。

ピットを踏む

質問 1: キャンバスに描かれた絵がぼやけてしまうのはなぜですか?

キャンバスに絵や文字を描くとき、​​キャンバスの幅と高さを 375*667 に設定します。描かれた絵は非常にぼやけていて、解像度の低い絵のように感じられます。も重なっているように見えます。

キャンバスを使用して小さなプログラムでポスターを描画する方法
#注: 物理ピクセルは携帯電話の画面に表示される最小単位を指しますが、デバイスに依存しないピクセル (論理ピクセル) )コンピュータデバイスのA点、cssで設定したピクセルを指します。

理由: フロントエンド開発では、

devicePixelRatio (デバイス ピクセル比) というプロパティがあることがわかっています。このプロパティは、使用されるピクセルの数 (通常は 2) を決定します。 ) デバイスに依存しないピクセルをレンダリングするための物理ピクセル。

たとえば、100*100 ピクセルの画像の場合、Retina スクリーン上では、画像の 1 ピクセルをレンダリングするために 2 ピクセルが使用されます。これは画像を 2 倍にすることに相当するため、画像はぼやけてしまいます。 、これが Retina スクリーン上で 1px が厚くなる理由です。 #####################解決する: Canvas-width と Canvas-height を 2 倍に拡大し、スタイルによって Canvas の表示幅と高さを 2 倍に縮小します。 Times.

例:
<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
キャンバスを使用して小さなプログラムでポスターを描画する方法 質問 2: px と rpx の変換をどのように処理しますか?
rpx はミニ プログラム内で固有のサイズ単位であり、画面の幅に応じて調整できます。iPhone6/iphonex では、1rpx はさまざまな px に相当します。したがって、異なる携帯電話ではキャンバスの表示に一貫性がなくなる可能性があります。

ポスターを描く前に、私たちが受け取るデザイン案は通常、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 になります。

ミニ プログラムでは、

this.ctx.measureText(text) になります。 width

はテキストの長さを計算するために提供されていますが、すべての

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
  }

質問 4: フォントの行が中央に表示されるようにするにはどうすればよいですか?何行ですか?

フォントが長すぎるとキャンバスからはみ出してしまい、描画が汚くなってしまいますので、このときはみ出した部分は ...幅と幅を設定することができます。ループで計算する テキストの幅を抽出し、幅を超える場合は部分文字列で切り取って ... を追加します。

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)
            }
          }
        }
      }

テキストプレイで示される計算式:

キャンバスの中央揃えが使用可能 (キャンバスの幅 - テキストの幅)/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

形式に変換します。次に、

wx.canvasPutImageData(OBJECT, this)

を通じてキャンバスに描画し、キャンバスを画像としてエクスポートします。

質問 6: 角の丸い絵を描くにはどうすればよいですか?

質問 7: wx.canvasToTempFilePath についてCanvas を使用して描画に成功した後、このメソッドを直接呼び出して画像を生成します。IDE 上では問題ありませんが、生成された画像は IDE 上では不完全になります。この場合、setTimeout を使用してこの問題を解決できます。 <pre class="brush:php;toolbar:false">this.ctx.draw(false, () =&gt; {         setTimeout(() =&gt; {             Taro.canvasToTempFilePath({               canvasId: 'canvasid',               success: async(res) =&gt; {                 this.props.onSavePoster(res.tempFilePath)//回调事件                 // 清空画布                 this.ctx.clearRect(0, 0, canvas_width, canvas_height)               },               fail: (err) =&gt; {                 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 になっていて混乱していましたが、左に変更したら正常になりました。

質問 10: 折れ線グラフを描画します

キャンバスを使用して小さなプログラムでポスターを描画する方法
キャンバスを使用して単純な折れ線グラフを描画します。

lineTo # を使用するだけです。 ## と moveTo は、2 つの API の点を接続するだけです。 createLinearGradient を使用して影を描画します。 考え方

考え方 1: json 構成テーブルを使用してポスターを生成する場合の制限

現在のポスター生成では、デザイン ドラフトに従ってサイズを測定するだけで済みますが、測定はこのプロセスは依然として非常に煩雑であり、設計ドラフトが不十分な領域では手動による微調整が必​​要です。 後からドラッグ&ドロップで

web

側でデザイン案を完成させ、jsonを自動生成してミニプログラムのポスターに適用することもできます。 考え方 2: バックエンドで生成されたポスターの制限

ポスターは、最初はバックエンドのクラスメートによって生成されました。利点は、フロントエンドの描画時間を必要としないことです。 WeChat APIとインターフェースの落とし穴を踏む必要はありません、戻ってURLを取得して表示しますが、バックエンドで生成される効果は良くありません、結局のところ、この種の作業はフロントエンドです。

考察 3: フロントエンドでのポスター生成の制限

フロントエンドでポスターを生成する場合、画像をローカルにダウンロードするなど、時間がかかり、また、 Android 用の特別な setTimeout は、正常な描画を保証します。さまざまな互換性の問題、モバイル DPR、Android と iOS、その他のノンストップ イースター エッグで頭がハゲてきますよ~はははは~

イースター エッグ

最新の Canvas-2D 背景を使用することは不可能です画像 全部描きますか?

Canvas の開発プロセス中、ミニ プログラムにはいつも思い出させてくれるかすかな光がありました。

キャンバスを使用して小さなプログラムでポスターを描画する方法
最新の Canvas2d API も試してみましたが、確かに Web 側と同期していて書き込みもスムーズになっています。開発者ツール。すべて正常に動作します。携帯電話で実行すると、幅の半分しか表示されません。さまざまなモデルでテストする場合も同様です。

キャンバスを使用して小さなプログラムでポスターを描画する方法
#後から元のキャンバスに変更すれば大丈夫です。 。 。具体的な理由は WeChat コミュニティではまだ見つかっていないため、今後の反復とアップグレードで調査していきます。

キャンバスを使用して小さなプログラムでポスターを描画する方法
推奨チュートリアル: 「
JS チュートリアル

以上がキャンバスを使用して小さなプログラムでポスターを描画する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。