ArkTs编写虚拟摇杆

@Entry
@Component
struct All{
  @State offsetX: number = 0
  @State offsetY: number = 0
  @State positionX: number = 0
  @State positionY: number = 0
  @State offsetX1: number = 0
  @State offsetY1: number = 0
  @State positionX1: number = 0
  @State positionY1: number = 0
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All })
  private panOption1: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Horizontal })
  build(){
    Stack({}) {
      Row() {
        Stack() {
          Column() {
            Arc1({ radius: 60, x: 80, y: 600, globalAlpha:0.3 })
          }
          Column() {
            Arc1({ radius: 25, x: 80, y: 600, globalAlpha:0.7 })
          }
          .translate({ x: this.offsetX, y: this.offsetY, z: 0 }) // 以组件左上角为坐标原点进行移动
          // 左右拖动触发该手势事件
          // 添加 PanGesture 手势,实现左右拖动触发事件
          .gesture(
            PanGesture(this.panOption)
              .onActionStart((event?: GestureEvent) => {
                console.info('Pan start')
              })
              .onActionUpdate((event?: GestureEvent) => {
                if (event) {
                  // 计算拖动的相对坐标
                  let x = event.offsetX;
                  let y = event.offsetY;

                  // 计算相对圆心的距离
                  let distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));

                  // 如果超过半径,将位置限制在圆的边缘
                  if (distance > 60) {
                    let angle = Math.atan2(y, x);
                    x = Math.cos(angle) * 60;
                    y = Math.sin(angle) * 60;
                  }

                  // 更新偏移量
                  this.offsetX = this.positionX + x;
                  this.offsetY = this.positionY + y;
                }
              })
              .onActionEnd(() => {
                this.offsetX = 0;
                this.offsetY = 0;
                // this.positionX = this.offsetX;
                // this.positionY = this.offsetY;
                console.info('Pan end');
              })
          )
        }
        .width('50%')
        .height('100%')
        // Column() {
        Stack() {
          square()

          // }
          // Column() {
          // Arc1({ radius: 30, x: 276, y: 615 })
          Arc1({ radius: 30, x: 85, y: 615,  globalAlpha:0.7})
            // }
            .translate({ x: this.offsetX1, y: this.offsetY1, z: 0 }) // 以组件左上角为坐标原点进行移动
              // 左右拖动触发该手势事件
              // 添加 PanGesture 手势,实现左右拖动触发事件
            .gesture(
              PanGesture(this.panOption1)
                .onActionStart((event?: GestureEvent) => {
                  console.info('Pan start')
                })
                .onActionUpdate((event?: GestureEvent) => {
                  if (event) {
                    // 计算拖动的相对坐标
                    let x1 = event.offsetX;
                    let y1 = event.offsetY;

                    // 限制水平拖动范围在长方形内
                    if (x1 > 60) {
                      x1 = 60;
                    } else if (x1 < -60) {
                      x1 = -60;
                    }

                    // 更新偏移量
                    this.offsetX1 = this.positionX1 + x1;
                    this.offsetY1 = this.positionY1 + y1;
                  }
                })
                .onActionEnd(() => {
                  this.offsetX1 = 0;
                  this.offsetY1 = 0;
                  // this.positionX = this.offsetX;
                  // this.positionY = this.offsetY;
                  console.info('Pan end');
                })
            )
        }
        .width('50%')
        .height('100%')
      }
    }
    .width('100%')
    .height('100%')
  }
}
@Component
struct Arc1{
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private radius: number
  private x: number
  private y:number
  private globalAlpha: number
  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
          // .backgroundColor('#ffff00')
        .onReady(() => {
          this.context.beginPath()
          this.context.arc(this.x, this.y, this.radius, 0, 6.28)
          this.context.globalAlpha = this.globalAlpha
          this.context.fillStyle = '#ffa6a6ea'
          this.context.fill()
        })
    }
    .width('100%')
    .height('100%')
  }
}

@Component
struct square{
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  build(){
    Column() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
        Canvas(this.context)
          .width('100%')
          .height('100%')
            // .backgroundColor('#ffff00')
          .onReady(() => {
            let ctx = new Path2D();
            let x = 0
            let y = 600
            let arcRadius = 15
            let height = 30
            let width = 170
            // 左上角
            ctx.moveTo(x + arcRadius, y);
            ctx.arcTo(x, y, x, y + arcRadius, arcRadius);
            // 左下角
            ctx.lineTo(x, y + height - arcRadius);
            ctx.arcTo(x, y + height, x + arcRadius, y + height, arcRadius);
            // 右下角
            ctx.lineTo(x + width - arcRadius, y + height);
            ctx.arcTo(x + width, y + height, x + width, y + height - arcRadius, arcRadius);
            // 右上角
            ctx.lineTo(x + width, y + arcRadius);
            ctx.arcTo(x + width, y, x + width - arcRadius, y, arcRadius);
            ctx.closePath();
            this.context.fillStyle = '#0097D4';
            // 填充
            this.context.fill(ctx);
          })
      }
    }
  }
}

效果图

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值