cari
Rumahapplet WeChatPembangunan program miniAjar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Bagaimana untuk melukis carta garis cuaca dalam applet WeChat? Artikel berikut akan memperkenalkan kepada anda cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat, dan menggunakan lengkung Bezier tertib ketiga agar sesuai dengan titik suhu untuk menjadikannya licin dan mempunyai warna latar belakang di bahagian bawah lengkung Saya harap Bermanfaat untuk semua orang!

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Polyline

Rendering:

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Carta garis komponen tersuai

<canvas type="2d" id="line" class="line-class" style="width:{{width}}px;height:{{height}}px" />
Component({
  externalClasses: [&#39;line-class&#39;],
  properties: {
    width: String,
    height: String,
    data: Array,
  },
  observers: {
    width() {
      // 这里监听 width 变化重绘 canvas
      // 动态传入 width 好像只能这样了..
      const query = this.createSelectorQuery();
      query
        .select(&#39;#line&#39;)
        .fields({ node: true, size: true })
        .exec(res => {
          const canvas = res[0].node;
          const ctx = canvas.getContext(&#39;2d&#39;);
          const width = res[0].width; // 画布宽度
          const height = res[0].height; // 画布高度

          console.log(`宽度: ${width}, 高度: ${height}`);

          const dpr = wx.getSystemInfoSync().pixelRatio;
          canvas.width = width * dpr;
          canvas.height = height * dpr;
          ctx.scale(dpr, dpr);

          // 开始绘图
          this.drawLine(ctx, width, height, this.data.data);
        });
    },
  },
  methods: {
    drawLine(ctx, width, height, data) {
      const Max = Math.max(...data);
      const Min = Math.min(...data);

      // 把 canvas 的宽度, 高度按一定规则平分
      const startX = width / (data.length * 2), // 起始点的横坐标 X
        baseY = height * 0.9, // 基线纵坐标 Y
        diffX = width / data.length,
        diffY = (height * 0.7) / (Max - Min); // 高度预留 0.2 写温度

      ctx.beginPath();
      ctx.textAlign = &#39;center&#39;;
      ctx.font = &#39;13px Microsoft YaHei&#39;;
      ctx.lineWidth = 2;
      ctx.strokeStyle = &#39;#ABDCFF&#39;;

      // 画折线图的线
      data.forEach((item, index) => {
        const x = startX + diffX * index,
          y = baseY - (item - Min) * diffY;

        ctx.fillText(`${item}°`, x, y - 10);
        ctx.lineTo(x, y);
      });
      ctx.stroke();

      // 画折线图背景
      ctx.lineTo(startX + (data.length - 1) * diffX, baseY); // 基线终点
      ctx.lineTo(startX, baseY); // 基线起点
      const lingrad = ctx.createLinearGradient(0, 0, 0, height * 0.7);
      lingrad.addColorStop(0, &#39;rgba(255,255,255,0.9)&#39;);
      lingrad.addColorStop(1, &#39;rgba(171,220,255,0)&#39;);
      ctx.fillStyle = lingrad;
      ctx.fill();

      // 画折线图上的小圆点
      ctx.beginPath();
      data.forEach((item, index) => {
        const x = startX + diffX * index,
          y = baseY - (item - Min) * diffY;

        ctx.moveTo(x, y);
        ctx.arc(x, y, 3, 0, 2 * Math.PI);
      });
      ctx.fillStyle = &#39;#0396FF&#39;;
      ctx.fill();
    },
  },
});

data ialah tatasusunan suhu, seperti [1, 2, ...]

Kerana saya tidak 'Tidak tahu Berapa banyak nilai suhu yang ada, jadi lebar di sini dihantar secara dinamik

Ada masalah kecil, iaitu, jika lebar terlalu besar, mesin sebenar tidak akan memaparkannya. ..

 // 获取 scroll-view 的总宽度
 wx.createSelectorQuery()
      .select(&#39;.hourly&#39;)
      .boundingClientRect(rect => {
        this.setData({
          scrollWidth: rect.right - rect.left,
        });
      })
      .exec();
<view class="title">小时概述</view>
<scroll-view scroll-x scroll-y class="scroll" show-scrollbar="{{false}}" enhanced="{{true}}">
    <view class="hourly">
      <view wx:for="{{time}}" wx:key="index">{{item}}</view>
    </view>
    <line-chart line-class="line" width="{{scrollWidth}}" height="100" data="{{temp}}" />
</scroll-view>

Di sini Tulis tatal-x dan tatal-y, tidak akan ada masalah mengimbangi kedudukan mutlak, dan saya tidak tahu mengapa

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

.scroll {
  position: relative;
  height: 150px;
  width: 100%;
}

.hourly {
  display: flex;
  height: 150px;
  position: absolute;
  top: 0;
}

.hourly > view {
  min-width: 3.5em;
  text-align: center;
}

.line { // 折线图绝对定位到底部
  position: absolute;
  bottom: 0;
}

Kedudukan mutlak yang digunakan di sini sebenarnya adalah untuk mensimulasikan Kesan carta garisan seperti Cuaca Moji dan setiap hari dalam blok, jadi ketinggian setiap jam hendaklah sama dengan paparan skrol, dan kanvas perlu diletakkan

Terutamanya kerana saya tidak tahu cara melaksanakan Cuaca Moji, jadi saya hanya boleh melakukan ini buat sementara waktu

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Ketiga -order Bezier Curve

Rendering

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

emmm, nampak tak lancar sangat

Kira titik kawalan

Mula-mula tulis kelas mata

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

Alat lukisan lengkung Kanvas Bezier (karlew.com)

http: //wx.karlew.com/canvas/bezier/

Anda boleh mengetahui susunan ketiga melalui laman web di atas Maksud setiap parameter keluk Bezier

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Iaitu, apabila menggunakan bezierCurveTo, titik terakhir ialah titik seterusnya, dan dua yang pertama ialah titik kawalan

Rujukan pengiraan titik kawalan: Kaedah menentukan titik kawalan lengkung Bezier - Perpustakaan Baidu

https://wenku.baidu.com/view/c790f8d46bec0975f565e211.html

Untuk meringkaskannya, ia adalah

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

di mana a dan b boleh menjadi sebarang nombor positif

Jadi tentukan kaedah untuk mengira titik kawalan A dan B bagi titik tertentu

/**
 * 计算当前点的贝塞尔曲线控制点
 * @param {Point} previousPoint: 前一个点
 * @param {Point} currentPoint: 当前点
 * @param {Point} nextPoint1: 下一个点
 * @param {Point} nextPoint2: 下下个点
 * @param {Number} scale: 系数
 */
calcBezierControlPoints(
  previousPoint,
  currentPoint,
  nextPoint1,
  nextPoint2,
  scale = 0.25
) {
  let x = currentPoint.x + scale * (nextPoint1.x - previousPoint.x);
  let y = currentPoint.y + scale * (nextPoint1.y - previousPoint.y);

  const controlPointA = new Point(x, y); // 控制点 A

  x = nextPoint1.x - scale * (nextPoint2.x - currentPoint.x);
  y = nextPoint1.y - scale * (nextPoint2.y - currentPoint.y);

  const controlPointB = new Point(x, y); // 控制点 B

  return { controlPointA, controlPointB };
}

Di sini skala ialah a dan b, tetapi nilainya adalah sama

Tetapi titik pertama tidak mempunyai Titik sebelumnya, dan titik kedua terakhir tidak mempunyai NextPoint2

Jadi apabila titik itu adalah yang pertama, gunakan CurrentPoint dan bukannya previousPoint

Apabila ia adalah titik kedua terakhir, gunakan nextPoint1 dan bukannya nextPoint2

Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod)

Bagi titik terakhir, anda tidak perlu melakukan apa-apa, kerana parameter ketiga bezierCurveTo ialah titik seterusnya Anda hanya perlu menyediakan koordinat untuk menyambung, dan tidak perlu mengira titik kawalan

Oleh itu, kaedah melukis lengkung Bezier tertib ketiga:

/**
 * 绘制贝塞尔曲线
 * ctx.bezierCurveTo(控制点1, 控制点2, 当前点);
 */
drawBezierLine(ctx, data, options) {
  const { startX, diffX, baseY, diffY, Min } = options;

  ctx.beginPath();
  // 先移动到第一个点
  ctx.moveTo(startX, baseY - (data[0] - Min) * diffY);

  data.forEach((e, i) => {
    let curPoint, prePoint, nextPoint1, nextPoint2, x, y;

    // 当前点
    x = startX + diffX * i;
    y = baseY - (e - Min) * diffY;
    curPoint = new Point(x, y);

    // 前一个点
    x = startX + diffX * (i - 1);
    y = baseY - (data[i - 1] - Min) * diffY;
    prePoint = new Point(x, y);

    // 下一个点
    x = startX + diffX * (i + 1);
    y = baseY - (data[i + 1] - Min) * diffY;
    nextPoint1 = new Point(x, y);

    // 下下个点
    x = startX + diffX * (i + 2);
    y = baseY - (data[i + 2] - Min) * diffY;
    nextPoint2 = new Point(x, y);

    if (i === 0) {
      // 如果是第一个点, 则前一个点用当前点代替
      prePoint = curPoint;
    } else if (i === data.length - 2) {
      // 如果是倒数第二个点, 则下下个点用下一个点代替
      nextPoint2 = nextPoint1;
    } else if (i === data.length - 1) {
      // 最后一个点直接退出
      return;
    }

    const { controlPointA, controlPointB } = this.calcBezierControlPoints(
      prePoint,
      curPoint,
      nextPoint1,
      nextPoint2
    );

    ctx.bezierCurveTo(
      controlPointA.x,
      controlPointA.y,
      controlPointB.x,
      controlPointB.y,
      nextPoint1.x,
      nextPoint1.y
    );
  });

  ctx.stroke();
},

[Cadangan pembelajaran berkaitan: Tutorial Pembangunan Program Mini]

Atas ialah kandungan terperinci Ajar anda langkah demi langkah cara menggunakan kanvas untuk melukis carta garis cuaca dalam applet WeChat (dengan kod). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:掘金社区. Jika ada pelanggaran, sila hubungi admin@php.cn Padam

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular

EditPlus versi Cina retak

EditPlus versi Cina retak

Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna