Heim > WeChat-Applet > Mini-Programmentwicklung > Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

青灯夜游
Freigeben: 2022-03-08 20:02:55
nach vorne
8140 Leute haben es durchsucht

Wie zeichne ich ein Wetterliniendiagramm im WeChat-Applet? Im folgenden Artikel erfahren Sie, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen und eine Bezier-Kurve dritter Ordnung verwenden, um die Temperaturpunkte anzupassen, um sie glatt zu machen und am unteren Rand der Kurve eine Hintergrundfarbe zu erhalten . Ich hoffe, es ist für alle hilfreich!

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Polylinie

Rendering:

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Benutzerdefiniertes Komponentenliniendiagramm

<canvas type="2d" id="line" class="line-class" style="width:{{width}}px;height:{{height}}px" />
Nach dem Login kopieren
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();
    },
  },
});
Nach dem Login kopieren

Daten sind das Temperaturarray, z. B. [1, 2, ...]

weil nein Wir wissen, wie viele Temperaturwerte es gibt, daher wird die Breite hier dynamisch übergeben

Es gibt ein kleines Problem: Wenn die Breite zu groß ist, zeigt die reale Maschine sie nicht an ...

 // 获取 scroll-view 的总宽度
 wx.createSelectorQuery()
      .select(&#39;.hourly&#39;)
      .boundingClientRect(rect => {
        this.setData({
          scrollWidth: rect.right - rect.left,
        });
      })
      .exec();
Nach dem Login kopieren
<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>
Nach dem Login kopieren

Schreiben Sie hier scroll-x und scroll-y, sonst gibt es ein Problem mit dem absoluten Positionierungsversatz, und ich weiß nicht warum

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

.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;
}
Nach dem Login kopieren

Die hier verwendete absolute Positionierung dient eigentlich dazu, den Effekt eines Liniendiagramms wie Moji zu simulieren Wetter und jeden Tag in einem Block, also stündlich, muss mit Scroll-Ansicht usw. kombiniert werden. Hoch muss die Leinwand positioniert werden

Hauptsächlich, weil ich nicht weiß, wie ich Moji Weather erreichen kann, also kann ich das nur vorübergehend tun

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Bezier-Kurve dritter Ordnung

Rendering

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

emmm, es scheint, dass es nicht dasselbe ist. Nicht sehr glatt

Kontrollpunkte berechnen

Schreiben Sie zuerst a Punktklasse

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
Nach dem Login kopieren

Canvas Bezier-Kurven-Zeichenwerkzeug (karlew.com)

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

Über die obige Website können Sie die Bedeutung jedes Parameters dritter Ordnung erfahren Bezier-Kurve

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Das heißt, bei Verwendung von bezierCurveTo ist der letzte Punkt der nächste Punkt und die ersten beiden sind Kontrollpunkte

Berechnung von Kontrollpunkten Referenz: Methode zur Bestimmung von Bezier-Kurven-Kontrollpunkten – Baidu-Bibliothek

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

Kondensiert ist es

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

wobei a und b beliebige positive Zahlen sein können

Definieren Sie also eine Methode zur Berechnung der Kontrollpunkte A und B von ein bestimmter Punkt

/**
 * 计算当前点的贝塞尔曲线控制点
 * @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 };
}
Nach dem Login kopieren

Hier ist die Skala a und b, aber machen Sie ihre Werte gleich

Aber der erste Punkt hat keinen previousPoint und der vorletzte Punkt hat keinen nextPoint2

Wenn der Punkt also der erste ist, Verwenden Sie currentPoint anstelle von previousPoint

Wenn es der vorletzte Punkt ist, verwenden Sie nextPoint1 anstelle von nextPoint2

Bringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).

Was den letzten Punkt betrifft, müssen Sie nichts tun, da der dritte Parameter von bezierCurveTo der nächste Punkt ist. Sie müssen nur Koordinaten angeben, um eine Verbindung herzustellen. Es ist also nicht erforderlich, Kontrollpunkte zu berechnen:

/**
 * 绘制贝塞尔曲线
 * 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();
},
Nach dem Login kopieren

[Verwandte Lernempfehlungen:

Mini-Tutorial zur Programmentwicklung

]

Das obige ist der detaillierte Inhalt vonBringen Sie Schritt für Schritt bei, wie Sie mit Canvas ein Wetterliniendiagramm im WeChat-Applet zeichnen (mit Code).. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage