• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 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
16import { BroadCast, Constants, Log } from '@ohos/common';
17
18const TAG: string = 'editor_PcCropRulerBar';
19
20/**
21 * 天枢PC图库编辑使用的角度调节尺工具栏
22 */
23@Component
24export struct PcCropRulerBar {
25  @Consume broadCast: BroadCast;
26  @State cWidth: number = 250;
27  @State cHeight: number = 57;
28  private current_def: number = 0;
29  private startPos: number = 0;
30  private setting: RenderingContextSettings = new RenderingContextSettings(true);
31  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.setting);
32  private resetClicked: Function = (): void => {};
33  private previous: number = 0;
34  private rulerLength: number = 0
35  private rulerWidth: number = 0
36  private isVerticalScreen: boolean = true;
37  private rulerDrawHeight = 24;
38
39  iniSize() {
40    this.rulerLength = this.cWidth
41    this.rulerWidth = this.cHeight
42  }
43
44  multiScreenAdaptation() {
45    if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_1) {
46      this.context.font = Constants.RULER_CONTEXT_FONT_10PX
47    } else if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_2) {
48      this.context.font = Constants.RULER_CONTEXT_FONT_20PX
49    } else if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_3) {
50      this.context.font = Constants.RULER_CONTEXT_FONT_30PX
51    } else {
52      this.context.font = Constants.RULER_CONTEXT_FONT_20PX
53    }
54  }
55
56  drawMidLine() {
57    // 中点
58    const mid_x = Math.floor(this.rulerLength / Constants.NUMBER_2);
59    this.context.beginPath();
60    this.context.fillStyle = Constants.RULER_FILL_STYLE_100;
61    this.context.strokeStyle = Constants.RULER_FILL_STYLE_100;
62    this.context.lineCap = 'round';
63
64    this.context.lineWidth = Constants.MID_LINE_WIDTH;
65    this.context.moveTo(mid_x, this.rulerDrawHeight - Constants.EDITOR_LARGE_TICK_LINE_HEIGHT);
66    this.context.lineTo(mid_x, this.rulerDrawHeight - Constants.NUMBER_1);
67
68    this.context.stroke();
69    this.context.closePath();
70  }
71
72  drawIntegerLine(cur_x: number, cur_num: number) {
73    this.context.moveTo(cur_x, this.rulerDrawHeight - Constants.EDITOR_MIDDLE_TICK_LINE_HEIGHT);
74    this.context.shadowBlur = Constants.RULER_LINE_WIDTH
75    this.context.lineCap = 'round';
76    if (Math.round(cur_num) != Math.round(this.current_def) && Math.round(cur_num) == 0) {
77      this.context.textBaseline = 'bottom'
78      this.context.font = Constants.RULER_CONTEXT_FONT_25PX;
79      this.context.fillText(cur_num.toString(), cur_x, this.rulerDrawHeight - Constants.EDITOR_MIDDLE_TICK_LINE_HEIGHT);
80    }
81    this.context.lineTo(cur_x, this.rulerDrawHeight);
82
83  }
84
85  drawLine() {
86    // 起始绘制位置
87    let begin_num = this.current_def - (this.rulerLength / Constants.NUMBER_2) / Constants.NUMBER_5;
88    let end_num = this.current_def + (this.rulerLength / Constants.NUMBER_2) / Constants.NUMBER_5;
89    let cur_x = 0;
90    let cur_num = 0;
91    const scale_len = Math.ceil((this.rulerLength) / Constants.NUMBER_5) + Constants.NUMBER_1;
92    for (let i = 0; i < scale_len; i++) {
93      cur_num = begin_num + i;
94      this.context.beginPath();
95      this.multiScreenAdaptation();
96      this.context.textAlign = 'center';
97
98      // 设置默认线型
99      this.context.strokeStyle = Constants.RULER_FILL_STYLE_40;
100      this.context.fillStyle = Constants.RULER_FILL_STYLE_40;
101
102      // 边缘第三根线
103      if (cur_num <= (begin_num + Constants.NUMBER_3) || cur_num >= (end_num - Constants.NUMBER_3)) {
104        this.context.strokeStyle = Constants.RULER_FILL_STYLE_30;
105        this.context.fillStyle = Constants.RULER_FILL_STYLE_30;
106      }
107
108      // 次边缘的线
109      if (cur_num <= (begin_num + Constants.NUMBER_2) || cur_num >= (end_num - Constants.NUMBER_2)) {
110        this.context.strokeStyle = Constants.RULER_FILL_STYLE_20;
111        this.context.fillStyle = Constants.RULER_FILL_STYLE_20;
112      }
113      // 最边缘的线
114      if (cur_num <= (begin_num + Constants.NUMBER_2) || cur_num >= (end_num - Constants.NUMBER_2)) {
115        this.context.strokeStyle = Constants.RULER_FILL_STYLE_10;
116        this.context.fillStyle = Constants.RULER_FILL_STYLE_10;
117      }
118
119      // 标尺0与当前数值之间的白色竖线
120      if ((cur_num < this.current_def && cur_num >= 0) || (cur_num > this.current_def && cur_num <= 0)) {
121        this.context.strokeStyle = Constants.RULER_FILL_STYLE_100;
122        this.context.fillStyle = Constants.RULER_FILL_STYLE_100;
123      }
124
125      // 设置线宽
126      this.context.shadowBlur = 0;
127      this.context.lineCap = 'round';
128      cur_x = i * Constants.NUMBER_5
129      if (cur_x == 0 || cur_x == this.rulerLength) {
130        // 边界位置刻度线宽度为一半
131        this.context.lineWidth = (Constants.RULER_LINE_WIDTH / Constants.NUMBER_2);
132        if (cur_x < 0) {
133          cur_x = 0;
134        }
135      } else {
136        this.context.lineWidth = Constants.RULER_LINE_WIDTH;
137      }
138
139      // 绘制刻度线
140      if (Math.abs(cur_num) % Constants.NUMBER_10 === 0) {
141        // 每隔10个刻度绘制一个中刻度线
142        this.drawIntegerLine(cur_x, cur_num)
143      } else if ((cur_num < this.current_def && cur_num >= 0) || (cur_num > this.current_def && cur_num <= 0)) {
144        // 0和当前刻度之间的线
145        this.context.moveTo(cur_x, this.rulerDrawHeight - Constants.EDITOR_MIDDLE_TICK_LINE_HEIGHT);
146        this.context.lineTo(cur_x, this.rulerDrawHeight);
147      } else {
148        // 其他短刻度线
149        this.context.moveTo(cur_x, this.rulerDrawHeight - Constants.EDITOR_SMALL_TICK_LINE_HEIGHT);
150        this.context.lineTo(cur_x, this.rulerDrawHeight);
151      }
152      this.context.stroke();
153      this.context.closePath();
154    }
155  }
156
157  onTouchEvent(event: TouchEvent): void {
158    let axis = this.isVerticalScreen ? 'x' : 'y';
159    if (event.type === TouchType.Down) {
160      this.startPos = event.touches[0][axis];
161      this.previous = new Date().getTime();
162    }
163    if (event.type !== TouchType.Move) {
164      return;
165    }
166    let now = new Date().getTime();
167    if (now - this.previous < Constants.TIMEOUT) {
168      return;
169    }
170    this.previous = now;
171    let dir = this.startPos - event.touches[0][axis];
172    if (Math.abs(dir / 5) < 1) {
173      return;
174    }
175    this.current_def += Number.parseInt((dir / 5).toFixed(0));
176    this.startPos = event.touches[0][axis];
177    if (Math.abs(this.current_def) > Constants.EDGE_ANGLE) {
178      this.current_def = this.current_def > Constants.EDGE_ANGLE ? Constants.EDGE_ANGLE : -Constants.EDGE_ANGLE;
179    }
180    this.drawRuler();
181    this.broadCast.emit(Constants.RULER_CHANGED, [this.current_def]);
182  }
183
184  onResetClicked() {
185    this.current_def = 0;
186    this.drawRuler();
187  }
188
189  integerAngleToString(currentAngle: number): string | undefined {
190    if (currentAngle % 10 === 0 && Math.abs(currentAngle) <= 40) {
191      return currentAngle.toString();
192    }
193
194    return undefined;
195  }
196
197  aboutToAppear() {
198    this.resetClicked = (): void => this.onResetClicked();
199    this.broadCast.on(Constants.CROP_RESET_CLICKED, this.resetClicked);
200    this.iniSize()
201  }
202
203  drawRuler() {
204    this.context.clearRect(0, 0, this.cWidth, this.cHeight);
205    this.drawMidLine();
206    this.drawLine();
207  }
208
209  aboutToDisappear() {
210    this.broadCast.off(Constants.CROP_RESET_CLICKED, this.resetClicked);
211  }
212
213  build() {
214    Flex({
215      direction: FlexDirection.Column,
216      alignItems: ItemAlign.Center,
217      justifyContent: FlexAlign.Center
218    }) {
219      Canvas(this.context)
220        .width('100%')
221        .height('100%')
222        .onReady(() => {
223          this.drawRuler()
224        })
225    }
226    .onTouch((event?: TouchEvent) => {
227      this.onTouchEvent(event as TouchEvent);
228    })
229    .backgroundColor('#33000000')
230    .borderRadius($r('app.float.edit_menu_item_radius'))
231    .height($r('app.float.edit_menu_crop_ruler_bar_height'))
232    .width($r('app.float.edit_menu_crop_ruler_bar_width'))
233    .padding({ left: '12vp', right: '12vp', top: '16vp', bottom: '15vp' }) //旋转刻度尺的内边距
234  }
235}
236