• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16let __decorate =
17    (this && this.__decorate) ||
18    function (decorators, target, key, desc) {
19        let c = arguments.length;
20        let r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc;
21        let d;
22        if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') {
23            r = Reflect.decorate(decorators, target, key, desc);
24        } else {
25            for (let i = decorators.length - 1; i >= 0; i--) {
26            d = decorators[i];
27            if (d) {
28                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
29            }
30        }
31    }
32    return c > 3 && r && Object.defineProperty(target, key, r), r;
33};
34if (!('finalizeConstruction' in ViewPU.prototype)) {
35    Reflect.set(ViewPU.prototype, 'finalizeConstruction', () => {});
36}
37
38const measure = requireNapi('measure');
39const Curves = globalThis.requireNativeModule('ohos.curves');
40const LengthMetrics = requireNapi('arkui.node').LengthMetrics;
41const ColorMetrics = requireNapi('arkui.node').ColorMetrics;
42const LengthUnit = requireNapi('arkui.node').LengthUnit;
43const PathShape = requireNapi('arkui.shape').PathShape;
44
45export let ArcButtonPosition;
46(function (ArcButtonPosition) {
47    ArcButtonPosition[(ArcButtonPosition['TOP_EDGE'] = 0)] = 'TOP_EDGE';
48    ArcButtonPosition[(ArcButtonPosition['BOTTOM_EDGE'] = 1)] = 'BOTTOM_EDGE';
49})(ArcButtonPosition || (ArcButtonPosition = {}));
50
51export let ArcButtonStyleMode;
52(function (ArcButtonStyleMode) {
53    ArcButtonStyleMode[(ArcButtonStyleMode['EMPHASIZED_LIGHT'] = 0)] =
54      'EMPHASIZED_LIGHT';
55    ArcButtonStyleMode[(ArcButtonStyleMode['EMPHASIZED_DARK'] = 1)] =
56      'EMPHASIZED_DARK';
57    ArcButtonStyleMode[(ArcButtonStyleMode['NORMAL_LIGHT'] = 2)] = 'NORMAL_LIGHT';
58    ArcButtonStyleMode[(ArcButtonStyleMode['NORMAL_DARK'] = 3)] = 'NORMAL_DARK';
59    ArcButtonStyleMode[(ArcButtonStyleMode['CUSTOM'] = 4)] = 'CUSTOM';
60})(ArcButtonStyleMode || (ArcButtonStyleMode = {}));
61
62export let ArcButtonStatus;
63(function (ArcButtonStatus) {
64    ArcButtonStatus[(ArcButtonStatus['NORMAL'] = 0)] = 'NORMAL';
65    ArcButtonStatus[(ArcButtonStatus['PRESSED'] = 1)] = 'PRESSED';
66    ArcButtonStatus[(ArcButtonStatus['DISABLED'] = 2)] = 'DISABLED';
67})(ArcButtonStatus || (ArcButtonStatus = {}));
68
69class Constants {}
70
71/**
72 * 最大文字大小
73 */
74Constants.MAX_FONT_SIZE = 19;
75/**
76 * 最小文字大小
77 */
78Constants.MIN_FONT_SIZE = 13;
79/**
80 * 阴影半径
81 */
82Constants.SHADOW_BLUR = 4;
83/**
84 * Y偏移
85 */
86Constants.SHADOW_OFFSET_Y = 3;
87/**
88 * 按钮与边框距离
89 */
90Constants.DISTANCE_FROM_BORDER = 1;
91/**
92 * 文本间距
93 */
94Constants.TEXT_HORIZONTAL_MARGIN = 24;
95Constants.TEXT_MARGIN_TOP = 10;
96Constants.TEXT_MARGIN_BOTTOM = 16;
97Constants.EMPHASIZED_TEXT_COLOR = '#FFFFFF';
98Constants.EMPHASIZED_PRESSED_BTN_COLOR = '#357FFF';
99Constants.EMPHASIZED_DISABLE_BTN_COLOR = '#1F71FF';
100Constants.EMPHASIZED_DISABLE_TEXT_COLOR = '#FFFFFF';
101Constants.NORMAL_LIGHT_NORMAL_BTN_COLOR = '#17273F';
102Constants.NORMAL_LIGHT_TEXT_COLOR = '#5EA1FF';
103Constants.NORMAL_LIGHT_PRESSED_BTN_COLOR = '#2E3D52';
104Constants.NORMAL_LIGHT_DISABLE_BTN_COLOR = '#17273F';
105Constants.NORMAL_LIGHT_DISABLE_TEXT_COLOR = '#995ea1ff';
106Constants.NORMAL_DARK_NORMAL_BTN_COLOR = '#252525';
107Constants.NORMAL_DARK_TEXT_COLOR = '#5EA1FF';
108Constants.NORMAL_DARK_PRESSED_BTN_COLOR = '#3B3B3B';
109Constants.NORMAL_DARK_DISABLE_BTN_COLOR = '#262626';
110Constants.NORMAL_DARK_DISABLE_TEXT_COLOR = '#995ea1ff';
111Constants.EMPHASIZEWARN_NORMAL_BTN_COLOR = '#BF2629';
112Constants.EMPHASIZEWARN_TEXT_COLOR = '#FFFFFF';
113Constants.EMPHASIZEWARN_PRESSED_BTN_COLOR = '#C53C3E';
114Constants.EMPHASIZEWARN_DISABLE_BTN_COLOR = '#4C0f10';
115Constants.EMPHASIZEWARN_DISABLE_TEXT_COLOR = '#99FFFFFF';
116Constants.DEFAULT_TRANSPARENCY = 0.4;
117Constants.EMPHASIZED_NORMAL_BTN_COLOR = {
118    id: -1,
119    type: 10001,
120    params: ['sys.color.comp_background_emphasize'],
121    bundleName: '__harDefaultBundleName__',
122    moduleName: '__harDefaultModuleName__',
123}
124
125let ArcButtonOptions = class ArcButtonOptions {
126    constructor(options) {
127        this.position = options.position ?? ArcButtonPosition.BOTTOM_EDGE;
128        this.styleMode = options.styleMode ?? ArcButtonStyleMode.EMPHASIZED_LIGHT;
129        this.status = options.status ?? ArcButtonStatus.NORMAL;
130        this.label = options.label ?? '';
131        this.backgroundBlurStyle = options.backgroundBlurStyle ?? BlurStyle.NONE;
132        this.backgroundColor =
133            options.backgroundColor ?? ColorMetrics.resourceColor(Color.Black);
134        this.shadowColor =
135            options.shadowColor ?? ColorMetrics.resourceColor('#000000');
136        this.shadowEnabled = options.shadowEnabled ?? false;
137        this.fontSize =
138            options.fontSize ?? new LengthMetrics(Constants.MAX_FONT_SIZE);
139        this.fontColor =
140            options.fontColor ?? ColorMetrics.resourceColor(Color.White);
141        this.pressedFontColor =
142            options.pressedFontColor ?? ColorMetrics.resourceColor(Color.White);
143        this.fontStyle = options.fontStyle ?? FontStyle.Normal;
144        this.fontFamily = options.fontFamily ?? '';
145        this.fontMargin = options.fontMargin ?? {
146            start: LengthMetrics.vp(Constants.TEXT_HORIZONTAL_MARGIN),
147            top: LengthMetrics.vp(Constants.TEXT_MARGIN_TOP),
148            end: LengthMetrics.vp(Constants.TEXT_HORIZONTAL_MARGIN),
149            bottom: LengthMetrics.vp(Constants.TEXT_MARGIN_BOTTOM),
150        };
151        this.onTouch = options.onTouch ?? (() => {});
152        this.onClick = options.onClick ?? (() => {});
153    }
154};
155__decorate([Trace], ArcButtonOptions.prototype, 'position', void 0);
156__decorate([Trace], ArcButtonOptions.prototype, 'styleMode', void 0);
157__decorate([Trace], ArcButtonOptions.prototype, 'status', void 0);
158__decorate([Trace], ArcButtonOptions.prototype, 'label', void 0);
159__decorate([Trace], ArcButtonOptions.prototype, 'backgroundBlurStyle', void 0);
160__decorate([Trace], ArcButtonOptions.prototype, 'backgroundColor', void 0);
161__decorate([Trace], ArcButtonOptions.prototype, 'shadowColor', void 0);
162__decorate([Trace], ArcButtonOptions.prototype, 'shadowEnabled', void 0);
163__decorate([Trace], ArcButtonOptions.prototype, 'fontSize', void 0);
164__decorate([Trace], ArcButtonOptions.prototype, 'fontColor', void 0);
165__decorate([Trace], ArcButtonOptions.prototype, 'pressedFontColor', void 0);
166__decorate([Trace], ArcButtonOptions.prototype, 'fontStyle', void 0);
167__decorate([Trace], ArcButtonOptions.prototype, 'fontFamily', void 0);
168__decorate([Trace], ArcButtonOptions.prototype, 'fontMargin', void 0);
169__decorate([Trace], ArcButtonOptions.prototype, 'onTouch', void 0);
170__decorate([Trace], ArcButtonOptions.prototype, 'onClick', void 0);
171ArcButtonOptions = __decorate([ObservedV2], ArcButtonOptions);
172
173export { ArcButtonOptions };
174
175export class ArcButton extends ViewV2 {
176    constructor(
177        parent,
178        params,
179        __localStorage,
180        elmtId = -1,
181        paramsLambda,
182        extraInfo
183    ) {
184        super(parent, elmtId, extraInfo);
185        this.initParam(
186            'options',
187            params && 'options' in params ? params.options : undefined
188        );
189        this.canvasWidth = 0;
190        this.canvasHeight = 0;
191        this.scaleX = 1;
192        this.scaleY = 1;
193        this.btnColor = ColorMetrics.resourceColor(Color.Black);
194        this.textWidth = 0;
195        this.textHeight = 0;
196        this.fontColor = ColorMetrics.resourceColor(Color.White);
197        this.isExceed = false;
198        this.pathString = '';
199        this.fontSize = '';
200        this.btnNormalColor = ColorMetrics.resourceColor(Color.Black);
201        this.btnPressColor = ColorMetrics.resourceColor(Color.Black);
202        this.btnDisableColor = ColorMetrics.resourceColor(Color.Black);
203        this.textNormalColor = ColorMetrics.resourceColor(Color.White);
204        this.textDisableColor = ColorMetrics.resourceColor(Color.White);
205        this.isUp = false;
206        this.curves = Curves.interpolatingSpring(10, 1, 350, 35);
207        this.scaleValue = 1;
208        this.textPressColor = ColorMetrics.resourceColor(Color.White);
209        this.arcButtonTheme = {
210            BUTTON_HEIGHT: this.getArcButtonThemeVpValue({
211                id: -1,
212                type: 10002,
213                params: ['sys.float.arc_button_height'],
214                bundleName: '__harDefaultBundleName__',
215                moduleName: '__harDefaultModuleName__',
216            }),
217            ARC_CIRCLE_DIAMETER: this.getArcButtonThemeVpValue({
218                id: -1,
219                type: 10002,
220                params: ['sys.float.arc_button_auxiliary_circle_diameter'],
221                bundleName: '__harDefaultBundleName__',
222                moduleName: '__harDefaultModuleName__',
223            }),
224            DIAL_CIRCLE_DIAMETER: this.getArcButtonThemeVpValue({
225                id: -1,
226                type: 10002,
227                params: ['sys.float.arc_button_dial_circle_diameter'],
228                bundleName: '__harDefaultBundleName__',
229                moduleName: '__harDefaultModuleName__',
230            }),
231            CHAMFER_CIRCLE_RADIUS: this.getArcButtonThemeVpValue({
232                id: -1,
233                type: 10002,
234                params: ['sys.float.arc_button_chamfer_radius'],
235                bundleName: '__harDefaultBundleName__',
236                moduleName: '__harDefaultModuleName__',
237            }),
238        };
239        this.dataProcessUtil = new DataProcessUtil(this.arcButtonTheme);
240        this.finalizeConstruction();
241    }
242
243    optionsChange() {
244        this.fontSize = this.cover(this.options.fontSize);
245        this.judgeTextWidth();
246        this.changeStatus();
247    }
248
249    changeStatus() {
250        switch (this.options.styleMode) {
251            case ArcButtonStyleMode.EMPHASIZED_LIGHT:
252                this.btnNormalColor = ColorMetrics.resourceColor(
253                    Constants.EMPHASIZED_NORMAL_BTN_COLOR
254                );
255                this.textNormalColor = ColorMetrics.resourceColor(
256                    Constants.EMPHASIZED_TEXT_COLOR
257                );
258                this.btnPressColor = ColorMetrics.resourceColor(
259                    Constants.EMPHASIZED_PRESSED_BTN_COLOR
260                );
261                this.btnDisableColor = ColorMetrics.resourceColor(
262                    Constants.EMPHASIZED_DISABLE_BTN_COLOR
263                );
264                this.textDisableColor = ColorMetrics.resourceColor(
265                    Constants.EMPHASIZED_DISABLE_TEXT_COLOR
266                );
267                this.textPressColor = ColorMetrics.resourceColor(
268                    Constants.EMPHASIZED_TEXT_COLOR
269                );
270                break;
271            case ArcButtonStyleMode.NORMAL_LIGHT:
272                this.btnNormalColor = ColorMetrics.resourceColor(
273                    Constants.NORMAL_LIGHT_NORMAL_BTN_COLOR
274                );
275                this.textNormalColor = ColorMetrics.resourceColor(
276                    Constants.NORMAL_LIGHT_TEXT_COLOR
277                );
278                this.btnPressColor = ColorMetrics.resourceColor(
279                    Constants.NORMAL_LIGHT_PRESSED_BTN_COLOR
280                );
281                this.btnDisableColor = ColorMetrics.resourceColor(
282                    Constants.NORMAL_LIGHT_DISABLE_BTN_COLOR
283                );
284                this.textDisableColor = ColorMetrics.resourceColor(
285                    Constants.NORMAL_LIGHT_DISABLE_TEXT_COLOR
286                );
287                this.textPressColor = ColorMetrics.resourceColor(
288                    Constants.NORMAL_LIGHT_TEXT_COLOR
289                );
290                break;
291            case ArcButtonStyleMode.NORMAL_DARK:
292                this.btnNormalColor = ColorMetrics.resourceColor(
293                    Constants.NORMAL_DARK_NORMAL_BTN_COLOR
294                );
295                this.textNormalColor = ColorMetrics.resourceColor(
296                    Constants.NORMAL_DARK_TEXT_COLOR
297                );
298                this.btnPressColor = ColorMetrics.resourceColor(
299                    Constants.NORMAL_DARK_PRESSED_BTN_COLOR
300                );
301                this.btnDisableColor = ColorMetrics.resourceColor(
302                    Constants.NORMAL_DARK_DISABLE_BTN_COLOR
303                );
304                this.textDisableColor = ColorMetrics.resourceColor(
305                    Constants.NORMAL_DARK_DISABLE_TEXT_COLOR
306                );
307                this.textPressColor = ColorMetrics.resourceColor(
308                    Constants.NORMAL_DARK_TEXT_COLOR
309                );
310                break;
311            case ArcButtonStyleMode.EMPHASIZED_DARK:
312                this.btnNormalColor = ColorMetrics.resourceColor(
313                    Constants.EMPHASIZEWARN_NORMAL_BTN_COLOR
314                );
315                this.textNormalColor = ColorMetrics.resourceColor(
316                    Constants.EMPHASIZEWARN_TEXT_COLOR
317                );
318                this.btnPressColor = ColorMetrics.resourceColor(
319                    Constants.EMPHASIZEWARN_PRESSED_BTN_COLOR
320                );
321                this.btnDisableColor = ColorMetrics.resourceColor(
322                    Constants.EMPHASIZEWARN_DISABLE_BTN_COLOR
323                );
324                this.textDisableColor = ColorMetrics.resourceColor(
325                    Constants.EMPHASIZEWARN_DISABLE_TEXT_COLOR
326                );
327                this.textPressColor = ColorMetrics.resourceColor(
328                    Constants.EMPHASIZEWARN_TEXT_COLOR
329                );
330                break;
331            default:
332                this.btnNormalColor = this.options.backgroundColor;
333                this.textNormalColor = this.options.fontColor;
334                this.btnPressColor = this.options.backgroundColor;
335                this.textPressColor = this.options.pressedFontColor;
336                break;
337        }
338        if (this.options.status === ArcButtonStatus.DISABLED) {
339            this.btnColor = this.btnDisableColor;
340            this.fontColor = this.textDisableColor;
341        } else {
342            this.btnColor = this.btnNormalColor;
343            this.fontColor = this.textNormalColor;
344        }
345    }
346
347    /**
348     * 初始化数据
349     */
350    initValues() {
351        this.isUp = this.options.position == ArcButtonPosition.TOP_EDGE;
352        this.btnColor = this.options.backgroundColor;
353        this.fontColor = this.options.fontColor;
354        this.curves = Curves.interpolatingSpring(10, 1, 350, 35);
355        this.scaleValue = 0.95;
356        this.changeStatus();
357    }
358
359    getArcButtonThemeVpValue(res) {
360        if (!res) {
361        return 0;
362        }
363        let metrics = LengthMetrics.resource(res);
364        let value = metrics.value;
365        switch (metrics.unit) {
366        case LengthUnit.PX:
367            return px2vp(value);
368        case LengthUnit.LPX:
369            return px2vp(lpx2px(value));
370        case LengthUnit.FP:
371            return px2vp(fp2px(value));
372        }
373        return value;
374    }
375
376    /**
377     * 判断是否超出文本框宽度
378     */
379    judgeTextWidth() {
380        const measureTextWidth = measure.measureText({
381            textContent: this.options.label,
382            fontStyle: this.options.fontStyle,
383            fontFamily: this.options.fontFamily,
384            fontWeight: FontWeight.Medium,
385            maxLines: 1,
386            fontSize: `${Constants.MIN_FONT_SIZE}fp`,
387        });
388        this.isExceed =
389            measureTextWidth > this.getUIContext().vp2px(this.textWidth);
390    }
391
392    aboutToAppear() {
393        if (this.arcButtonTheme.BUTTON_HEIGHT === 0) {
394            console.error("arcbutton can't obtain sys float value.");
395            return;
396        }
397        this.initValues();
398        this.dataProcessUtil.initData();
399        const pathData = this.dataProcessUtil.calculate();
400        this.generatePath(pathData);
401    }
402
403    calculateActualPosition(pos, canvasTopPos) {
404        const x = this.getUIContext().vp2px(pos.x - canvasTopPos.x);
405        const y = this.getUIContext().vp2px(pos.y - canvasTopPos.y);
406        return new ArcButtonPoint(x, y);
407    }
408
409    generatePath(data) {
410        if (data == null) {
411            return;
412        }
413        this.canvasWidth = data.btnWidth + Constants.SHADOW_BLUR * 2;
414        this.canvasHeight = data.btnHeight + Constants.DISTANCE_FROM_BORDER * 2;
415        const margin = this.options.fontMargin;
416        const start = margin?.start?.value ?? 0;
417        const end = margin?.end?.value ?? 0;
418        const top = margin?.top?.value ?? 0;
419        const bottom = margin?.bottom?.value ?? 0;
420        this.textWidth = data.btnWidth - start - end;
421        this.textHeight = data.btnHeight - top - bottom;
422        this.judgeTextWidth();
423        const canvasLeftTopPoint = data.canvasLeftTop;
424        canvasLeftTopPoint.x -= Constants.SHADOW_BLUR;
425        canvasLeftTopPoint.y -= Constants.DISTANCE_FROM_BORDER;
426        const leftTopPoint = this.calculateActualPosition(
427            data.leftTopPoint,
428            canvasLeftTopPoint
429        );
430        const upperArcCircleR = this.getUIContext().vp2px(
431            this.arcButtonTheme.ARC_CIRCLE_DIAMETER / 2
432        );
433        const rightTopPoint = this.calculateActualPosition(
434            data.rightTopPoint,
435            canvasLeftTopPoint
436        );
437        const chamferCircleR = this.getUIContext().vp2px(
438            this.arcButtonTheme.CHAMFER_CIRCLE_RADIUS
439        );
440        const rightBottomPoint = this.calculateActualPosition(
441            data.rightBottomPoint,
442            canvasLeftTopPoint
443        );
444        const lowerArcCircleR = this.getUIContext().vp2px(
445            this.arcButtonTheme.DIAL_CIRCLE_DIAMETER / 2
446        );
447        const leftBottomPoint = this.calculateActualPosition(
448            data.leftBottomPoint,
449            canvasLeftTopPoint
450        );
451        const pathStr =
452            `M ${leftTopPoint.x} ${leftTopPoint.y} A ${upperArcCircleR} ${upperArcCircleR}, 0, 0, 0,
453            ${rightTopPoint.x} ${rightTopPoint.y}` +
454            `Q ${rightTopPoint.x - chamferCircleR * 1.2} ${
455            rightTopPoint.y + chamferCircleR * 0.6
456            } ${rightBottomPoint.x} ${rightBottomPoint.y}` +
457            `A ${lowerArcCircleR} ${lowerArcCircleR}, 0, 0, 0, ${leftBottomPoint.x}
458            ${leftBottomPoint.y}` +
459            `Q ${leftTopPoint.x + chamferCircleR * 1.2} ${
460            leftTopPoint.y + chamferCircleR * 0.6
461            } ${leftTopPoint.x} ${leftTopPoint.y}`;
462        this.pathString = pathStr;
463    }
464
465    TextBuilderIsExceed(parent = null) {
466        this.observeComponentCreation2((elmtId, isInitialRender) => {
467            Text.create(this.options.label);
468            Text.width(this.textWidth);
469            Text.height(this.textHeight);
470            Text.fontColor(this.fontColor.color);
471            Text.fontSize(this.fontSize);
472            Text.maxLines(1);
473            Text.textAlign(TextAlign.Center);
474            Text.fontWeight(FontWeight.Medium);
475            Text.fontStyle(this.options.fontStyle);
476            Text.fontFamily(this.options.fontFamily);
477            Text.backgroundColor(Color.Transparent);
478            Text.textOverflow({ overflow: TextOverflow.MARQUEE });
479            Text.margin({
480                start: this.options.fontMargin.start,
481                top: this.isUp
482                    ? this.options.fontMargin.bottom
483                    : this.options.fontMargin.top,
484                end: this.options.fontMargin.end,
485                bottom: this.options.fontMargin.bottom,
486            });
487        }, Text);
488        Text.pop();
489    }
490
491    TextBuilderNormal(parent = null) {
492        this.observeComponentCreation2((elmtId, isInitialRender) => {
493            Text.create(this.options.label);
494            Text.width(this.textWidth);
495            Text.height(this.textHeight);
496            Text.textAlign(TextAlign.Center);
497            Text.fontColor(this.fontColor.color);
498            Text.maxFontSize(`${Constants.MAX_FONT_SIZE}fp`);
499            Text.minFontSize(`${Constants.MIN_FONT_SIZE}fp`);
500            Text.fontWeight(FontWeight.Medium);
501            Text.fontStyle(this.options.fontStyle);
502            Text.fontFamily(this.options.fontFamily);
503            Text.maxLines(1);
504            Text.margin({
505                start: this.options.fontMargin.start,
506                top: this.isUp
507                    ? this.options.fontMargin.bottom
508                    : this.options.fontMargin.top,
509                end: this.options.fontMargin.end,
510                bottom: this.options.fontMargin.bottom,
511            });
512        }, Text);
513        Text.pop();
514    }
515
516    cover(params) {
517        switch (params.unit) {
518            case LengthUnit.VP:
519                return `${params.value}vp`;
520            case LengthUnit.PX:
521                return `${params.value}px`;
522            case LengthUnit.FP:
523                return `${params.value}fp`;
524            case LengthUnit.LPX:
525                return `${params.value}lpx`;
526            case LengthUnit.PERCENT:
527                return `${params.value}%`;
528        }
529    }
530
531    getShadow() {
532        if (!this.options.shadowEnabled) {
533            return undefined;
534        }
535        return {
536            radius: Constants.SHADOW_BLUR,
537            color: this.options.shadowColor.color,
538            offsetY: Constants.SHADOW_OFFSET_Y,
539        };
540    }
541
542    initialRender() {
543        this.observeComponentCreation2((elmtId, isInitialRender) => {
544            Stack.create({ alignContent: Alignment.Center });
545            Context.animation({ curve: this.curves });
546            Stack.enabled(this.options.status !== ArcButtonStatus.DISABLED);
547            Stack.opacity(
548                this.options.styleMode === ArcButtonStyleMode.EMPHASIZED_LIGHT &&
549                    this.options.status === ArcButtonStatus.DISABLED
550                    ? Constants.DEFAULT_TRANSPARENCY
551                    : 1
552            );
553            Context.animation(null);
554            Stack.width(this.canvasWidth);
555            Stack.height(this.canvasHeight);
556            Stack.scale({
557                x: this.scaleX,
558                y: this.scaleY,
559                centerY: this.isUp ? 0 : this.canvasHeight,
560            });
561            Stack.onTouch((event) => {
562                this.dealTouchEvent(event);
563            });
564            Stack.onClick((event) => {
565                if (this.options.onClick) {
566                    this.options.onClick(event);
567                }
568            });
569        }, Stack);
570        this.observeComponentCreation2((elmtId, isInitialRender) => {
571            Button.createWithLabel({ type: ButtonType.Normal, stateEffect: true });
572            Button.width('100%');
573            Button.height('100%');
574            Button.rotate({ angle: !this.isUp ? 0 : 180 });
575            Button.clipShape(new Path({ commands: this.pathString }));
576            Button.backgroundColor(this.btnColor.color);
577            Button.backgroundBlurStyle(this.options.backgroundBlurStyle);
578            Button.shadow(this.getShadow());
579        }, Button);
580        Button.pop();
581        this.observeComponentCreation2((elmtId, isInitialRender) => {
582            If.create();
583            if (this.isExceed) {
584                this.ifElseBranchUpdateFunction(0, () => {
585                    this.TextBuilderIsExceed.bind(this)(this);
586                });
587            } else {
588                this.ifElseBranchUpdateFunction(1, () => {
589                    this.TextBuilderNormal.bind(this)(this);
590                });
591            }
592        }, If);
593        If.pop();
594        Stack.pop();
595    }
596
597    dealTouchEvent(event) {
598        const x = event.touches[0].windowX;
599        const y = event.touches[0].windowY;
600        if (this.options.onTouch) {
601            this.options.onTouch(event);
602        }
603        switch (event.type) {
604            case TouchType.Down:
605                this.scaleX = this.scaleValue;
606                this.scaleY = this.scaleValue;
607                this.btnColor = this.btnPressColor;
608                this.fontColor = this.textPressColor;
609                break;
610            case TouchType.Up:
611                this.scaleX = 1;
612                this.scaleY = 1;
613                this.btnColor = this.btnNormalColor;
614                this.fontColor = this.textNormalColor;
615                break;
616            default:
617                break;
618        }
619    }
620
621    updateStateVars(params) {
622        if (params === undefined) {
623            return;
624        }
625        if ('options' in params) {
626            this.updateParam('options', params.options);
627        }
628    }
629
630    rerender() {
631        this.updateDirtyElements();
632    }
633}
634__decorate([Param], ArcButton.prototype, 'options', void 0);
635__decorate([Local], ArcButton.prototype, 'canvasWidth', void 0);
636__decorate([Local], ArcButton.prototype, 'canvasHeight', void 0);
637__decorate([Local], ArcButton.prototype, 'scaleX', void 0);
638__decorate([Local], ArcButton.prototype, 'scaleY', void 0);
639__decorate([Local], ArcButton.prototype, 'btnColor', void 0);
640__decorate([Local], ArcButton.prototype, 'textWidth', void 0);
641__decorate([Local], ArcButton.prototype, 'textHeight', void 0);
642__decorate([Local], ArcButton.prototype, 'fontColor', void 0);
643__decorate([Local], ArcButton.prototype, 'isExceed', void 0);
644__decorate([Local], ArcButton.prototype, 'pathString', void 0);
645__decorate([Local], ArcButton.prototype, 'fontSize', void 0);
646__decorate(
647    [
648        Monitor(
649        'options.label',
650        'options.type',
651        'options.fontSize',
652        'options.styleMode',
653        'options.status',
654        'options.backgroundColor',
655        'options.fontColor'
656        ),
657    ],
658    ArcButton.prototype,
659    'optionsChange',
660    null
661);
662
663class DataProcessUtil {
664    constructor(theme) {
665        this.dial = new ArcButtonCircle(0, 0, 0);
666        this.arc = new ArcButtonCircle(0, 0, 0);
667        this.height = 0;
668        this.width = 0;
669        this.arcButtonTheme = undefined;
670        this.arcButtonTheme = theme;
671    }
672
673    initData() {
674        const dialRadius = this.arcButtonTheme.DIAL_CIRCLE_DIAMETER / 2;
675        this.dial = new ArcButtonCircle(dialRadius, dialRadius, dialRadius);
676        const arcRadius = this.arcButtonTheme.ARC_CIRCLE_DIAMETER / 2;
677        this.height = this.arcButtonTheme.BUTTON_HEIGHT;
678        const arcX = this.dial.center.x;
679        const arcY = this.dial.center.y + dialRadius + arcRadius - this.height;
680        this.arc = new ArcButtonCircle(arcRadius, arcX, arcY);
681    }
682
683    calculate() {
684        const chamferCircleR = this.arcButtonTheme.CHAMFER_CIRCLE_RADIUS;
685        const innerDial = new ArcButtonCircle(
686            this.dial.radius - chamferCircleR,
687            this.dial.center.x,
688            this.dial.center.y
689        );
690        const innerArc = new ArcButtonCircle(
691            this.arc.radius - chamferCircleR,
692            this.arc.center.x,
693            this.arc.center.y
694        );
695        const intersections = this.findCircleIntersections(innerArc, innerDial);
696        const tp1 = this.calculateIntersection(
697            this.arc.center,
698            this.arc.radius,
699            intersections[0]
700        );
701        const tp2 = this.calculateIntersection(
702            this.arc.center,
703            this.arc.radius,
704            intersections[1]
705        );
706        const tp3 = this.calculateIntersection(
707            this.dial.center,
708            this.dial.radius,
709            intersections[1]
710        );
711        const tp4 = this.calculateIntersection(
712            this.dial.center,
713            this.dial.radius,
714            intersections[0]
715        );
716        this.width =
717        this.calculateDistance(intersections[0], intersections[1]) +
718            chamferCircleR * 2;
719        const canvasLeftTop = new ArcButtonPoint(
720            intersections[0].x - chamferCircleR,
721            this.dial.center.y + this.dial.radius - this.height
722        );
723        return new AllPoints(
724            this.width,
725            this.height,
726            tp2,
727            tp1,
728            tp3,
729            tp4,
730            canvasLeftTop
731        );
732    }
733
734    /**
735     * 计算两点间距离
736     * @param point1 点1
737     * @param point2 点2
738     * @returns 距离
739     */
740    calculateDistance(point1, point2) {
741        return Math.sqrt((point2.x - point1.x) ** 2 + (point2.y - point1.y) ** 2);
742    }
743
744    calculateIntersection(circleCenter, circleRadius, point) {
745        const h = circleCenter.x;
746        const k = circleCenter.y;
747        const x = point.x;
748        const y = point.y;
749        //计算直线斜率
750        let m = 0;
751        if (x != h) {
752            m = (y - k) / (x - h);
753        } else {
754            m = -1;
755        }
756        //计算截距
757        let intercept = 0;
758        if (m != -1) {
759            intercept = y - m * x;
760        }
761        //保存焦点位置
762        let resultPoint = [];
763        //判断斜率
764        if (m != -1) {
765            const a = Math.pow(m, 2) + 1;
766            const b = 2 * (m * intercept - m * k - h);
767            const c =
768                k ** 2 -
769                circleRadius ** 2 +
770                h ** 2 -
771                2 * intercept * k +
772                intercept ** 2;
773            const x1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a);
774            const x2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a);
775            const y1 = m * x1 + intercept;
776            const y2 = m * x2 + intercept;
777            resultPoint = [new ArcButtonPoint(x1, y1), new ArcButtonPoint(x2, y2)];
778        } else {
779            const x1 = h;
780            const y1 = k + circleRadius;
781            const y2 = k - circleRadius;
782            resultPoint = [new ArcButtonPoint(x1, y1), new ArcButtonPoint(x1, y2)];
783        }
784        const d1 = this.calculateDistance(resultPoint[0], point);
785        const d2 = this.calculateDistance(resultPoint[1], point);
786        if (d1 < d2) {
787            return resultPoint[0];
788        } else {
789            return resultPoint[1];
790        }
791    }
792
793    /**
794     * 查找两圆的交点
795     * @param C1 第一个圆
796     * @param c2 第二个圆
797     * @returns 两圆相交的点的数组
798     */
799    findCircleIntersections(firstCircus, secondCircus) {
800        const firstCircusR = firstCircus.radius;
801        const firstCircusCenterX = firstCircus.center.x;
802        const firstCircusCenterY = firstCircus.center.y;
803        const secondCircusR = secondCircus.radius;
804        const secondCircusCenterX = secondCircus.center.x;
805        const secondCircusCenterY = secondCircus.center.y;
806        // 计算两个圆心之间的距离
807        const distance = Math.sqrt(
808            (firstCircusCenterX - secondCircusCenterX) ** 2 +
809            (firstCircusCenterY - secondCircusCenterY) ** 2
810        );
811        // 检查异常情况
812        if (distance > firstCircusR + secondCircusR) {
813            //两个圆分离,不相交
814            return [];
815        } else if (distance < Math.abs(firstCircusR - secondCircusR)) {
816            //一个圆包含在另一个圆内,不相交
817            return [];
818        } else if (distance === 0 && firstCircusR === secondCircusR) {
819            //两个圆完全重合,具有无穷多交点
820            return [];
821        }
822        // 计算交点
823        const a =
824            (firstCircusR ** 2 - secondCircusR ** 2 + distance ** 2) / (2 * distance);
825        const h = Math.sqrt(firstCircusR ** 2 - a ** 2);
826        // 中间变量
827        const x2 =
828            firstCircusCenterX +
829            (a * (secondCircusCenterX - firstCircusCenterX)) / distance;
830        const y2 =
831            firstCircusCenterY +
832            (a * (secondCircusCenterY - firstCircusCenterY)) / distance;
833        // 交点
834        let intersection1 = new ArcButtonPoint(
835            x2 + (h * (secondCircusCenterY - firstCircusCenterY)) / distance,
836            y2 - (h * (secondCircusCenterX - firstCircusCenterX)) / distance
837        );
838        let intersection2 = new ArcButtonPoint(
839            x2 - (h * (secondCircusCenterY - firstCircusCenterY)) / distance,
840            y2 + (h * (secondCircusCenterX - firstCircusCenterX)) / distance
841        );
842        if (intersection1.x > intersection2.x) {
843            const mid = intersection1;
844            intersection1 = intersection2;
845            intersection2 = mid;
846        }
847        return [intersection1, intersection2];
848    }
849}
850
851class ArcButtonCircle {
852    constructor(radius, x, y) {
853        this.radius = radius;
854        this.center = new ArcButtonPoint(x, y);
855    }
856}
857
858class ArcButtonPoint {
859    constructor(x, y) {
860        this.x = x;
861        this.y = y;
862    }
863}
864
865class AllPoints {
866    constructor(
867        btnWidth,
868        btnHeight,
869        leftTopPoint,
870        rightTopPoint,
871        leftBottomPoint,
872        rightBottomPoint,
873        canvasLeftTop
874    ) {
875        this.btnWidth = btnWidth;
876        this.btnHeight = btnHeight;
877        this.leftTopPoint = leftTopPoint;
878        this.rightTopPoint = rightTopPoint;
879        this.leftBottomPoint = leftBottomPoint;
880        this.rightBottomPoint = rightBottomPoint;
881        this.canvasLeftTop = canvasLeftTop;
882    }
883}
884
885export default {
886    ArcButton,
887    ArcButtonOptions,
888    ArcButtonPosition,
889    ArcButtonStyleMode,
890    ArcButtonStatus,
891};
892//# sourceMappingURL=ArcButton.js.map
893