برنامه نویسی

پرونده توسعه بعدی Harmonyos: برنامه حاکم

شرح تصویر

کد زیر نحوه ایجاد یک برنامه خط کش تعاملی را با استفاده از Harmonyos بعدی نشان می دهد. این اجرای دارای نسل مقیاس پویا ، تعامل مبتنی بر ژست و سازگاری UI در زمان واقعی است.

رمز اجرا

import { window } from '@kit.ArkUI'; // Import window management APIs
import { deviceInfo } from '@kit.BasicServicesKit'; // Import device information APIs

// Ruler scale line definition
class RulerLine {
  index: number; // Index of the scale line
  height: number; // Height of the scale line

  constructor(index: number, height: number) {
    this.index = index; // Initialize index
    this.height = height; // Initialize height
  }

  // Display scale numbering
  showNumber(): string {
    return this.index % 10 === 0 ? `${Math.floor(this.index / 10)}` : ''; // Show number every 10 units
  }
}

// Custom text styling extension
@Extend(Text)
function fancy() {
  .fontColor("#019dfe") // Set font color
  .fontSize(20); // Set font size
}

// Main ruler component
@Entry
@Component
struct RulerComponent {
  @State maxRulerHeight: number = 0; // Maximum ruler height
  @State @Watch('onCellWidthChanged') cellWidthInPixels: number = 17.28; // Pixels per millimeter
  @State textWidth: number = 80; // Text label width
  @State rulerLines: RulerLine[] = []; // Array of scale lines
  @State leftOffsetX: number = -300; // Left offset position
  @State currentPositionX: number = -300; // Current X position
  @State @Watch('onContainerHeightChanged') containerHeight: number = 53; // Container height
  @State originalContainerHeight: number = 53; // Original container height
  @State @Watch('onCellWidthChanged') containerWidth: number = 0; // Container width

  // Handle cell width changes
  onCellWidthChanged() {
    this.maxRulerHeight = vp2px(this.containerWidth) / this.cellWidthInPixels / 10;
  }

  // Handle container height changes
  onContainerHeightChanged() {
    this.containerHeight = Math.max(this.containerHeight, 53); // Ensure minimum height
  }

  // Lifecycle: Component initialization
  aboutToAppear(): void {
    // Set landscape orientation
    window.getLastWindow(getContext()).then((windowClass) => {
      windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE);
    });

    // Initialize scale lines
    for (let i = 0; i <= 15 * 10; i++) {
      const lineHeight: number = (i % 10 === 0) ? 90 : (i % 5 === 0) ? 60 : 45;
      this.rulerLines.push(new RulerLine(i, lineHeight));
    }
  }

  // UI construction
  build() {
    Column() {
      Stack() {
        // Scale lines rendering
        Stack() {
          ForEach(this.rulerLines, (line: RulerLine, index: number) => {
            Line()
              .width(1)
              .height(`${line.height}px`)
              .backgroundColor(Color.White)
              .margin({ left: `${this.cellWidthInPixels * index}px` });
            Text(line.showNumber())
              .fontColor(Color.White)
              .fontSize(18)
              .width(`${this.textWidth}px`)
              .height(`${this.textWidth}px`)
              .textAlign(TextAlign.Center)
              .margin({
                left: `${this.cellWidthInPixels * index - this.textWidth / 2}px`,
                top: `${line.height}px`
              });
          });
        }.width('100%').height('100%').align(Alignment.TopStart);

        // Control panel
        Column({ space: 15 }) {
          Text(`Current Device: ${deviceInfo.marketName}`).fancy();
          Counter() {
            Text(`Measurement: ${this.maxRulerHeight.toFixed(2)} cm`).fancy();
          }
          .foregroundColor(Color.White)
          .width(300)
          .onInc(() => {
            this.containerHeight = px2vp(vp2px(this.containerHeight) + this.cellWidthInPixels / 10;
          })
          .onDec(() => {
            this.containerHeight = px2vp(vp2px(this.containerHeight) - this.cellWidthInPixels / 10;
          });

          Counter() {
            Text(`mm Scale: ${this.cellWidthInPixels.toFixed(2)}px`).fancy();
          }
          .foregroundColor(Color.White)
          .width(300)
          .onInc(() => {
            this.cellWidthInPixels += 0.01;
          })
          .onDec(() => {
            this.cellWidthInPixels = Math.max(0.01, this.cellWidthInPixels - 0.01);
          });
        }

        // Interactive measurement area
        RelativeContainer() {
          Rect()
            .fill("#80019dfe")
            .borderColor("#019dfe")
            .borderWidth({ left: 1, right: 1 })
            .clip(true)
            .width("100%")
            .height("100%")
            .onAreaChange((oldArea: Area, newArea: Area) => {
              this.containerWidth = newArea.width as number;
            });

          // Left draggable handle
          Stack() {
            Circle({ height: 30, width: 30 })
              .fill("#019dfe")
              .stroke(Color.Transparent)
              .strokeWidth(3);
            Circle({ height: 40, width: 40 })
              .fill(Color.Transparent)
              .stroke("#019dfe")
              .strokeWidth(3);
          }
          .hitTestBehavior(HitTestMode.Block)
          .padding(20)
          .alignRules({
            center: { anchor: "__container__", align: VerticalAlign.Center },
            middle: { anchor: "__container__", align: HorizontalAlign.Start }
          })
          .gesture(PanGesture({
            fingers: 1,
            direction: PanDirection.Horizontal,
            distance: 1
          }).onActionUpdate((event: GestureEvent) => {
            this.leftOffsetX = this.currentPositionX + event.offsetX / 2;
            this.containerHeight = this.originalContainerHeight - event.offsetX;
          }).onActionEnd(() => {
            this.currentPositionX = this.leftOffsetX;
            this.originalContainerHeight = this.containerHeight;
          }));

          // Right draggable handle
          Stack() {
            Circle({ height: 30, width: 30 })
              .fill("#019dfe")
              .stroke(Color.Transparent)
              .strokeWidth(3);
            Circle({ height: 40, width: 40 })
              .fill(Color.Transparent)
              .stroke("#019dfe")
              .strokeWidth(3);
          }
          .hitTestBehavior(HitTestMode.Block)
          .padding(20)
          .alignRules({
            center: { anchor: "__container__", align: VerticalAlign.Center },
            middle: { anchor: "__container__", align: HorizontalAlign.End }
          })
          .gesture(PanGesture({
            fingers: 1,
            direction: PanDirection.Horizontal,
            distance: 1
          }).onActionUpdate((event: GestureEvent) => {
            this.leftOffsetX = this.currentPositionX + event.offsetX / 2;
            this.containerHeight = this.originalContainerHeight + event.offsetX;
          }).onActionEnd(() => {
            this.currentPositionX = this.leftOffsetX;
            this.originalContainerHeight = this.containerHeight;
          }));
        }
        .width(this.containerHeight)
        .height("100%")
        .translate({ x: this.leftOffsetX })
        .gesture(PanGesture({
          fingers: 1,
          direction: PanDirection.Horizontal,
          distance: 1
        }).onActionUpdate((event: GestureEvent) => {
          if (event) {
            this.leftOffsetX = this.currentPositionX + event.offsetX;
          }
        }).onActionEnd(() => {
          this.currentPositionX = this.leftOffsetX;
        }));
      }
    }.height('100%').width('100%')
    .padding({ left: 30, right: 10 })
    .backgroundColor("#181b22");
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ویژگی های کلیدی

  1. تولید مقیاس پویا

    مقیاس های خط کش را به صورت برنامه ای با ارتفاع های مختلف برای علائم مقیاس مختلف (بخش های اصلی ، متوسط ​​و کوچک) ایجاد می کند.

  2. طرح تطبیقی

    برای حفظ مقیاس مناسب در اندازه های مختلف صفحه نمایش از سیستم طرح پاسخگو Harmonyos استفاده می کند.

  3. اندازه گیری تعاملی

    برای عملیات اندازه گیری دقیق ، دسته های کشنده دوگانه را با انیمیشن صاف پیاده سازی می کند.

  4. تبدیل واحد در زمان واقعی

    تبدیل پیکسل به سانتیمتر را با چگالی مقیاس قابل تنظیم فراهم می کند.

  5. حمایت از ژست

    حرکات PAN چند جهته را برای هر دو عملیات تنظیم حاکم و اندازه گیری پیاده سازی می کند.

استفاده

  1. دستگیره های آبی را برای انجام اندازه گیری ها بکشید
  2. برای تنظیم تراکم مقیاس از دکمه های “+” https://dev.to/ “-” استفاده کنید
  3. خط کش به طور خودکار با جهت گیری دستگاه سازگار است
  4. نتایج اندازه گیری در زمان واقعی را در سانتی متر نشان می دهد

این اجرای نشان دهنده قابلیت های بعدی Harmonyos از جمله UI اعلان ، مدیریت واکنش پذیر و کنترل پیشرفته ژست است.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا