• 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, ScreenManager } from '@ohos/common';
17
18const TAG: string = 'editor_CropRulerBar';
19
20interface RulerProperties {
21  rulerWidth: number;
22  rulerHeight: number;
23}
24
25@Component
26export struct CropRulerBar {
27  @Consume broadCast: BroadCast;
28  @Consume @Watch('iniSize') screenWidth: number;
29  @Consume @Watch('iniSize') screenHeight: number;
30  @State cWidth: number = 250;
31  @State cHeight: number = Constants.VERTICAL_RULER_COMPONENT_HEIGHT;
32  @State rulerLength: number = Constants.NUMBER_0;
33  @State rulerWidth: number = Constants.NUMBER_0;
34  @Consume('verticalScreen') isVerticalScreen: boolean;
35  private screenManager = ScreenManager.getInstance();
36  private current_def: number = Constants.NUMBER_0;
37  private startPos: number = Constants.NUMBER_0;
38  private setting: RenderingContextSettings = new RenderingContextSettings(true);
39  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.setting);
40  private resetClicked: Function = (): void => {};
41  private previous: number = Constants.NUMBER_0;
42
43  setRulerProperties(rulerWidth: number, rulerHeight: number): void {
44    AppStorage.SetOrCreate<RulerProperties>('rulerProperties', {
45      rulerWidth: rulerWidth,
46      rulerHeight: rulerHeight
47    } as RulerProperties)
48  }
49
50  iniSize(): void {
51    if (this.isVerticalScreen) {
52      this.rulerLength = this.cWidth;
53      this.rulerWidth = this.cHeight;
54    } else {
55      this.cWidth = Constants.HORIZONTAL_CROP_RULER_WIDTH;
56      this.cHeight = (this.screenHeight - this.screenHeight % Constants.NUMBER_20) - Constants.PADDING_HORIZONTAL;
57      this.rulerLength = this.cHeight;
58      this.rulerWidth = this.cWidth;
59    }
60    this.setRulerProperties(this.cWidth, this.cHeight);
61  }
62
63  multiScreenAdaptation(): void {
64    if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_1) {
65      this.context.font = Constants.RULER_CONTEXT_FONT_10PX;
66    } else if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_2) {
67      this.context.font = Constants.RULER_CONTEXT_FONT_20PX;
68    } else if (vp2px(Constants.NUMBER_1) == Constants.NUMBER_3) {
69      this.context.font = Constants.RULER_CONTEXT_FONT_30PX;
70    } else {
71      this.context.font = Constants.RULER_CONTEXT_FONT_35PX;
72    }
73  }
74
75  drawMidLine(): void {
76    const mid_x = Math.floor(this.rulerLength / Constants.NUMBER_2);
77    this.context.beginPath();
78    this.context.fillStyle = Constants.RULER_FILL_STYLE_100;
79    if (this.isVerticalScreen) {
80      this.context.fillRect(mid_x - Constants.MID_LINE_WIDTH / Constants.NUMBER_2,
81        this.rulerWidth * Constants.NUMBER_8 / Constants.NUMBER_15,
82        Constants.MID_LINE_WIDTH, Constants.MID_LINE_HEIGHT);
83    } else {
84      this.context.fillRect(this.rulerWidth * Constants.NUMBER_8_5 / Constants.NUMBER_15,
85        mid_x - Constants.MID_LINE_WIDTH / Constants.NUMBER_2, Constants.MID_LINE_HEIGHT,
86        Constants.MID_LINE_WIDTH);
87    }
88    this.context.stroke();
89    this.context.closePath();
90  }
91
92  drawIntegerLine(cur_x: number, cur_num: number): void {
93    if (!this.isVerticalScreen) {
94      this.context.moveTo((this.rulerWidth *  8.5) / 15, cur_x);
95    } else {
96      this.context.moveTo(cur_x, (this.rulerWidth *  8.5) / 15);
97    }
98
99    if (Math.abs(cur_num) > Constants.EDGE_ANGLE) {
100      this.context.strokeStyle = Constants.RULER_FILL_STYLE_40;
101      this.context.shadowColor = Constants.RULER_FILL_STYLE_40;
102    } else {
103      this.context.strokeStyle = Constants.RULER_FILL_STYLE_90;
104      this.context.shadowColor = Constants.RULER_FILL_STYLE_90;
105    }
106    this.context.shadowBlur = Constants.RULER_LINE_WIDTH
107    if (Math.round(cur_num) == Math.round(this.current_def)) {
108      if (!this.isVerticalScreen) {
109        this.context.fillText(this.integerAngleToString(Math.round(cur_num)) as string,
110          (this.rulerWidth * 6) / 15, cur_x);
111      } else {
112        this.context.fillText(this.integerAngleToString(Math.round(cur_num)) as string, cur_x,
113          (this.rulerWidth * 6) / 15);
114      }
115    } else {
116      if (!this.isVerticalScreen) {
117        this.context.fillText((-cur_num).toString(),
118          (this.rulerWidth * 6) / 15, cur_x);
119      } else {
120        this.context.fillText(cur_num.toString(), cur_x,
121          (this.rulerWidth * 6) / 15);
122      }
123
124    }
125    if (!this.isVerticalScreen) {
126      this.context.lineTo(this.rulerWidth *  10.5 / 15, cur_x);
127    } else {
128      this.context.lineTo(cur_x, this.rulerWidth *  10.5 / 15);
129    }
130  }
131
132  drawLine(): void {
133    let begin_num = this.current_def - (this.rulerLength / Constants.NUMBER_2) / Constants.NUMBER_5;
134    let cur_x = 0;
135    let cur_num = 0;
136    const scale_len = Math.ceil((this.rulerLength) / Constants.NUMBER_5) + Constants.NUMBER_1;
137    for (let i = 0; i < scale_len; i++) {
138      cur_num = begin_num + i;
139      this.context.beginPath();
140      this.multiScreenAdaptation();
141      this.context.textAlign = 'center';
142      if (!this.isVerticalScreen) {
143        this.context.textAlign = 'end';
144        this.context.textBaseline = 'middle';
145      }
146      if (Math.abs(cur_num) > Constants.EDGE_ANGLE) {
147        this.context.strokeStyle = Constants.RULER_FILL_STYLE_40;
148        this.context.fillStyle = Constants.RULER_FILL_STYLE_40;
149      } else {
150        this.context.strokeStyle = Constants.RULER_FILL_STYLE_90;
151        this.context.fillStyle = Constants.RULER_FILL_STYLE_90;
152      }
153      this.context.shadowBlur = 0;
154      cur_x = i * Constants.NUMBER_5;
155      if (cur_x == 0 || cur_x == this.rulerLength) {
156        this.context.lineWidth = (Constants.RULER_LINE_WIDTH / Constants.NUMBER_2);
157        if (cur_x < 0) {
158          cur_x = 0;
159        }
160      } else {
161        this.context.lineWidth = Constants.RULER_LINE_WIDTH;
162      }
163      if (Math.round(Math.abs(cur_num)) % Constants.NUMBER_10 == 0) {
164        this.drawIntegerLine(cur_x, cur_num);
165      } else {
166        if (!this.isVerticalScreen) {
167          this.context.moveTo((this.rulerWidth * Constants.NUMBER_9_5) / Constants.NUMBER_15, cur_x);
168          this.context.lineTo(this.rulerWidth * Constants.NUMBER_10_5 / Constants.NUMBER_15, cur_x);
169        } else {
170          this.context.moveTo(cur_x, (this.rulerWidth * Constants.NUMBER_9_5) / Constants.NUMBER_15);
171          this.context.lineTo(cur_x, this.rulerWidth * Constants.NUMBER_10_5 / Constants.NUMBER_15);
172        }
173      }
174      this.context.stroke();
175      this.context.closePath();
176    }
177  }
178
179  onTouchEvent(event: TouchEvent): void {
180    let axis = this.isVerticalScreen ? 'x' : 'y';
181    if (event.type === TouchType.Down) {
182      this.startPos = event.touches[0][axis];
183      this.previous = new Date().getTime();
184    }
185    if (event.type !== TouchType.Move) {
186      return;
187    }
188    let now = new Date().getTime();
189    if (now - this.previous < Constants.TIMEOUT) {
190      return;
191    }
192    this.previous = now;
193    let dir = this.startPos - event.touches[0][axis];
194    if (Math.abs(dir / 5) < 1) {
195      return;
196    }
197    this.current_def += Number.parseInt((dir / 5).toFixed(0));
198    this.startPos = event.touches[0][axis];
199    if (Math.abs(this.current_def) > Constants.EDGE_ANGLE) {
200      this.current_def = this.current_def > Constants.EDGE_ANGLE ? Constants.EDGE_ANGLE : -Constants.EDGE_ANGLE;
201    }
202    this.drawRuler();
203    this.broadCast.emit(Constants.RULER_CHANGED, [this.current_def]);
204  }
205
206  onResetClicked(): void {
207    this.current_def = Constants.NUMBER_0;
208    this.drawRuler();
209  }
210
211  integerAngleToString(currentAngle: number): string | undefined{
212    if (currentAngle % 10 === 0 && Math.abs(currentAngle) <= 40) {
213      return currentAngle.toString();
214    }
215
216    return undefined;
217  }
218
219  aboutToAppear(): void {
220    this.resetClicked = (): void => this.onResetClicked();
221    this.broadCast.on(Constants.CROP_RESET_CLICKED, this.resetClicked);
222    this.iniSize();
223  }
224
225  drawRuler(): void {
226    this.context.clearRect(0, 0, this.cWidth, this.cHeight);
227    this.drawMidLine();
228    this.drawLine();
229  }
230
231  aboutToDisappear(): void {
232    this.broadCast.off(Constants.CROP_RESET_CLICKED, this.resetClicked);
233  }
234
235  build() {
236    Flex({
237      direction: this.isVerticalScreen ? FlexDirection.Column : FlexDirection.Row,
238      alignItems: ItemAlign.Center,
239      justifyContent: FlexAlign.Center
240    }) {
241      Column() {
242        Canvas(this.context)
243          .onReady(() => {
244            this.drawRuler();
245          })
246      }
247      .onTouch((event?: TouchEvent) => {
248        this.onTouchEvent(event as TouchEvent);
249      })
250      .width(this.isVerticalScreen ? this.rulerLength : Constants.CROP_RULER_WIDTH)
251      .height(this.isVerticalScreen ? this.rulerWidth : this.rulerLength)
252    }
253  }
254}
255