提交 6a07d662 编写于 作者: E ester.zhou

Update docs (9763)

Signed-off-by: Nester.zhou <ester.zhou@huawei.com>
上级 af9afc41
......@@ -11,7 +11,7 @@ As a child component of **[\<text>](../arkui-js/js-components-basic-text.md)**,
None
## Child Component
## Child Components
Not supported
......
......@@ -47,7 +47,7 @@ In addition to the [universal events](../arkui-js/js-components-common-events.md
| Name | Parameter | Description |
| ------ | ------------------------------- | -------------- |
| change | { checked: isChecked }| Triggered when the toggle is selected or unselected.|
| change | { checked: isChecked } | Triggered when the toggle is selected or unselected.|
## Methods
......
......@@ -4,7 +4,7 @@
>
> This component is supported since API version 5. Updates will be marked with a superscript to indicate their earliest API version.
As a child component of **\<toolbar>**, the **\<toolbar-item>** component is used to display an operation option on the toolbar.
As a child component of **[\<toolbar>](js-components-basic-toolbar.md)**, the **\<toolbar-item>** component is used to display an operation option on the toolbar.
## Child Components
......@@ -32,18 +32,18 @@ Only the following styles are supported.
| font-size | &lt;length&gt; | 16px | No | Font size. |
| allow-scale | boolean | true | No | Whether the font size changes with the system's font size settings. |
| font-style | string | normal | No | Font style. Available values are as follows:<br> - **normal**: standard font style<br>- **italic**: italic font style|
| font-weight | number\|string | normal | No | Font weight. The number value must be an exact multiple of 100 ranging from 100 to 900. The default value is **400**. A larger value indicates a bigger weight. Available values of the string type are **lighter**, **normal**, **bold**, or **bolder**.|
| font-weight | number\|string | normal | No | Font weight. The number value must be an exact multiple of 100 ranging from 100 to 900. The default value is 400. A larger value indicates a bigger weight. Available values of the string type are **lighter**, **normal**, **bold**, or **bolder**. |
| text-decoration | string | none | No | Text decoration. Available values are as follows:<br>- **underline**: An underline is used.<br>- **line-through**: A strikethrough is used.<br>- **none**: The standard text is used.|
| font-family | string | sans-serif | No | Font family, in which fonts are separated by commas (,). Each font is set using a font name or font family name. The first font in the family or the specified [custom font](../arkui-js/js-components-common-customizing-font.md) is used for the text.|
| background | &lt;linear-gradient&gt; | - | No | Background. This attribute supports [gradient styles](../arkui-js/js-components-common-gradient.md) only and is not compatible with **background-color** or **background-image**.|
| background-color | &lt;color&gt; | - | No | Background color. |
| background-image | string | - | No | Background image. Currently, this attribute is not compatible with **background-color** or **background**. Both online and local image resources are supported.|
| background-size | - string<br>- &lt;length&gt; &lt;length&gt;<br>- &lt;percentage&gt; &lt;percentage&gt; | auto | No | Background image size.<br>- The **string** values are as follows:<br> - **contain**: Expands the image to the maximum size so that its height and width are fully applicable to the content area.<br> - **cover**: Extends the background image to a large enough size so that it completely covers the background area. Some parts of the image may not be displayed in the background area.<br> - **auto**: Retains the original aspect ratio of the image.<br>- The two **length** values are width and height of the background image. The first value indicates the width, and the second value indicates the height. If you only set one value, the other value is set to **auto** by default.<br>- The two **\<percentage>** values are width and height of the background image in percentage of the parent element. The first value indicates the width, and the second value indicates the height. If you only set one value, the other value is set to **auto** by default. |
| background-repeat | string | repeat | No | How a background image is repeatedly drawn. By default, a background image is repeated both horizontally and vertically.<br>- **repeat**: The image is repeated along the x-axis and y-axis at the same time.<br>- **repeat-x**: The image is repeated along the x-axis.<br>- **repeat-y**: The image is repeated along the y-axis.<br>- **no-repeat**: The image is not repeated.|
| background-position | - string string<br>- &lt;length&gt; &lt;length&gt;<br>- &lt;percentage&gt; &lt;percentage&gt; | 0px 0px | No | Position of the background image.<br>- Using keywords: If only one keyword is specified, the other value is **center** by default. The two values define the horizontal position and vertical position, respectively.<br> - **left**: leftmost in the horizontal direction.<br> - **right**: rightmost in the horizontal direction.<br> - **top**: top in the vertical direction.<br> - **bottom**: bottom in the vertical direction.<br> - **center**: center position.<br>- Using **\<length>**: The first value indicates the horizontal position, and the second value indicates the vertical position. For the upper left corner, the value is **0 0**. The unit is pixel. If only one value is specified, the other one is **50%**.<br>- Using **\<percentage>**: The first value indicates the horizontal position, and the second value indicates the vertical position. **0% 0%** indicates the upper left corner. **100% 100%** indicates the lower right corner. If only one value is specified, the other one is **50%**.<br>- Using both **\<percentage>** and **\<length>**.|
| background-size | - string<br>- &lt;length&gt; &lt;length&gt;<br>- &lt;percentage&gt; &lt;percentage&gt; | auto | No | Background image size.<br>- The available values of the **string** type are as follows:<br> - **contain**: extends the image to the maximum size so that its height and width are fully applicable to the content area.<br> - **cover**: extends the background image to a large enough size so that it completely covers the background area. Some parts of the image may not be displayed in the background area.<br> - **auto**: retains the original aspect ratio of the image.<br>- Values of the **\<length>** type: The two values are width and height of the background image. The first value indicates the width, and the second value indicates the height. If you only set one value, the other value is set to **auto** by default.<br>- Values of the **\<percentage>** type: The two values are width and height of the background image in percentage of the parent element. The first value indicates the width, and the second value indicates the height. If you only set one value, the other value is set to **auto** by default. |
| background-repeat | string | repeat | No | How a background image is repeatedly drawn. By default, a background image is repeated both horizontally and vertically.<br>- **repeat**: The image is repeated along both the x-axis and y-axis.<br>- **repeat-x**: The image is repeated along the x-axis.<br>- **repeat-y**: The image is repeated along the y-axis.<br>- **no-repeat**: The image is not repeated.|
| background-position | - string string<br>- &lt;length&gt; &lt;length&gt;<br>- &lt;percentage&gt; &lt;percentage&gt; | 0px 0px | No | Position of the background image.<br>- Values of the **string** type: If you set only one value, the other value is set to **center** by default. The two values define the horizontal position and vertical position, respectively.<br> - **left**: leftmost in the horizontal direction.<br> - **right**: rightmost in the horizontal direction.<br> - **top**: top in the vertical direction.<br> - **bottom**: bottom in the vertical direction.<br> - **center**: center in the horizontal or vertical direction.<br>- Values of the **\<length>** type: The first value indicates the horizontal position, and the second value indicates the vertical position. For the upper left corner, the value is 0 0 in px (**0px 0px**). If you only set one value, the other value is set to **50%**.<br>- Values of the **\<percentage>** type: The first value indicates the horizontal position, and the second value indicates the vertical position. For the upper left corner, the value is **0% 0%**. For the lower right corner, the value is **100% 100%**. If you only set one value, the other value is set to **50%**.<br>- Values of the **\<percentage>** type and **\<length>** type can be used together.|
| opacity | number | 1 | No | Opacity of an element. The value ranges from **0** to **1**. The value **1** means opaque, and **0** means completely transparent. |
| display | string | flex | No | Type of the box containing an element. Available values are as follows:<br>- **flex**: Flexible layout.<br>- **none**: The box is disabled.|
| visibility | string | visible | No | Whether to display the box containing an element. A hidden box still occupies layout space. (To remove the box, set the **display** attribute to **none**.) Available values are as follows:<br>- **visible**: The element is visible.<br>- **hidden**: The box is hidden but still takes up space.<br>If both **visibility** and **display** are set, only **display** takes effect.|
| display | string | flex | No | Type of the box containing an element. Available values are as follows:<br>- **flex**: flexible layout<br>- **none**: not rendered|
| visibility | string | visible | No | Whether to display the box containing an element. A hidden box still occupies layout space. (To remove the box, set the **display** attribute to **none**.) Available values are as follows:<br>- **visible**: The box is visible.<br>- **hidden**: The box is hidden but still takes up space.<br>If both **visibility** and **display** are set, only **display** takes effect.|
## Events
......
......@@ -32,7 +32,7 @@ In addition to the [universal attributes](../arkui-js/js-components-common-attri
| duration | number | - | No | Duration of the autoplay for child component switching. |
| vertical | boolean | false | No | Whether the swipe gesture is performed vertically. A vertical swipe uses the vertical indicator. |
| cachedsize<sup>7+</sup> | number | -1 | No | Minimum number of cached items during delayed loading of the **\<swiper>** component. The value **-1** indicates that all content is cached. |
| scrolleffect<sup>7+</sup> | string | spring | No | Scroll effect. The options are as follows:<br>- **spring**: Similar to the physical dynamic effect of a spring. After scrolling to the edge, you can continue to scroll for a distance based on the initial speed or by touching the knob of the scrollbar. After you release your hand, the knob is rebounded.<br>- **fade**: Similar to the physical dynamic effect of fade. When you scroll to the edge, a wave shape fades. The fade changes according to the speed and scrolling distance.<br>- **none**: No effect after the scroll bar is moved to the edge.<br>This attribute is valid only when **loop** is set to **false**.|
| scrolleffect<sup>7+</sup> | string | spring | No | Scroll effect. The options are as follows:<br>- **spring**: Similar to the physical dynamic effect of a spring. When the scrollbar reaches the edge, it can continue to scroll for a distance based on the initial speed or a touch event. It rebounds after being released.<br>- **fade**: Similar to the physical dynamic effect of fade. When the scrollbar reaches the edge, a wave shape fades. The fade changes according to the speed and scrolling distance.<br>- **none**: No effect when the scrollbar reaches the edge.<br>This attribute is valid only when **loop** is set to **false**.|
## Styles
......@@ -65,7 +65,7 @@ In addition to the [universal methods](../arkui-js/js-components-common-methods.
| Name | Parameter | Description |
| ------------ | -------------------------------------- | --------------- |
| swipeTo | { index: number(specified position) }| Scrolls the child component to the position at the specified index.|
| swipeTo | { index: number(specificLocation) } | Scrolls the child component to the position at the specified index.|
| showNext | - | Shows the next child component. |
| showPrevious | - | Shows the previous child component. |
......
# ArkUI Overview
ArkUI is a UI development framework for building OpenHarmony applications. It provides effortlessly natural UI syntax and UI development infrastructure including UI components, animation mechanisms, and event interaction, to meet the visualized GUI development requirements of application developers.
## Introduction
## Basic Concepts
ArkUI is a UI development framework that provides what you'll need to develop application UIs.
- **Component**: the smallest unit for UI building and display. You build a UI that meets your needs through flexible combinations of components.
- **Page**: the smallest unit for ArkUI application scheduling. You can design multiple pages for your application, manage their files on a per-page basis, and schedule page redirection through [page routing](../reference/apis/js-apis-router.md) APIs, so as to implement decoupling of application functions.
## Basic Concepts
## Key Features
- Component: the smallest unit for UI building and display. You build a UI that meets your needs through flexible combinations of components.
- **UI components**: ArkUI comes with a diverse array of built-in polymorphic components, including basic components (such as text, image, and button), container components with one or more child components, drawing components allowing for customization, and media components that provide video playback capabilities. By being polymorphic, a component provides variant forms to adapt to different types of devices and platforms.
- Page: the smallest unit for ArkUI application scheduling. You can design multiple pages for your application, manage their files on a per-page basis, and schedule page redirection through routing APIs, so as to implement decoupling of application functions.
- **Flexible layouts**: Creating a responsive UI in ArkUI is easy, with the carefully-designed layout approaches: Besides the basic linear and flexible layouts, you also have access to the advanced list, grid, and column grid layouts as well as the atomic layouts that auto-adapt to screen resolutions.
- **Animation**: Apart from animations embedded in components, ArkUI offers additional animation features: attribute animation, transition animation, and custom animation.
## Key Features
- **Drawing**: ArkUI offers advanced drawing capabilities that allow you to draw custom shapes with a range of editors, from images to fill colors and texts.
- **Interaction**: ArkUI allows users to interact with your application UI properly, regardless of the system platform and input device. By default, the UI accepts input from touch gestures, remote controls, keyboards, and mouse devices, with support for event callbacks where you can define interaction logic of your own.
- UI components: In addition to a wide range of basic components, such as components for text display, image display, and keypress interaction, ArkUI provides media components that support video playback. Better yet, it also provides polymorphic components, which can adapt to styles of different devices.
- Layout: Creating a responsive UI in ArkUI is easy, with our carefully-designed layout approaches: Besides the classic flexible layout capability, you also have access to the list, grid, and atomic layouts that auto-adapt to screen resolutions.
- Animation: Apart from animations embedded in components, ArkUI offers additional animation features: attribute animation, transition animation, and custom animation.
- Drawing: ArkUI offers advanced drawing capabilities that allow you to draw custom shapes with a range of editors, from images to fill colors and texts.
- Interaction: ArkUI allows users to interact with your application UI properly, regardless of the system platform and input device. By default, the UI accepts input from touch gestures, remote controls, and mouse devices, with support for the event notification capability.
- Platform API channel: ArkUI provides an API extension mechanism through which platform capabilities are encapsulated to produce JavaScript APIs in a unified style.
- Two development paradigms: ArkUI comes with two development paradigms: eTS-based declarative development paradigm (declarative development paradigm for short) and JavaScript-compatible web-like development paradigm (web-like development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
- **Platform API channel**: ArkUI provides an API extension mechanism through which platform capabilities are encapsulated to produce JavaScript (JS) APIs in a unified style.
| Development Paradigm | Description | Applicable To | Intended Audience |
| -------- | -------- | -------- | -------- |
| Web-like development paradigm | Uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically updates with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications. | Small- and medium-sized applications and service widgets with simple UIs | Frontend web developers |
| Declarative development paradigm | Uses the TypeScript programming language and extends the declarative UI syntax, providing UI drawing capabilities from three dimensions: component, animation, and state management. The programming mode used is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development. With type annotations in TypeScript, you can enforce type checking at compile time. | Applications involving technological sophistication and teamwork | Mobile application and system application developers |
- **Two development paradigms**: ArkUI comes with two development paradigms: [ArkTS-based declarative development paradigm](./ui-ts-overview.md) (declarative development paradigm for short) and [JS-compatible web-like development paradigm](./ui-js-overview.md) (web-like development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
| Development Paradigm | Description | Applicable To | Target Audience |
| -------- | ---------------------------------------- | ---------------- | ------------------- |
| Declarative development paradigm | Uses [ArkTS](../quick-start/arkts-get-started.md) – a superset of TypeScript with declarative UI syntax, providing UI drawing capabilities from three dimensions: component, animation, and status management. The programming mode used is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development.| Applications involving technological sophistication and teamwork| Mobile application and system application developers|
| Web-like development paradigm| Uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JS for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically refreshes with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications.| Small- and medium-sized applications and service widgets with simple UIs | Frontend web developers |
### Framework Structure
## Framework Structure
![en-us_image_0000001267647869](figures/en-us_image_0000001267647869.png)
As shown above, the two development paradigms share the UI backend engine and language runtime. The UI backend engine implements the six basic capabilities of the ArkUI framework. The declarative development paradigm does not require the JS Framework for managing the page DOM. As such, it has more streamlined rendering and update links and less memory usage. This makes the declarative development paradigm a better choice for building application UIs.
As shown above, the two development paradigms share the UI backend engine and language runtime. The UI backend engine implements the six basic capabilities of ArkUI. The declarative development paradigm does not require the JS Framework for managing the page DOM. As such, it has more streamlined rendering and update links and less memory usage. This makes the declarative development paradigm a better choice for building application UIs.
## Relationship Between UI and Ability Framework
Ability is an essential part of OpenHarmony applications. The [ability framework](../ability/ability-brief.md) provides two models: Feature Ability (FA) model and stage model. The table below describes the relationship between the two models of the ability framework and the two development paradigms of ArkUI.
**FA Model**
| Type| UI Development Paradigm | Description|
| -------- | --------------------------- | --------------------------- |
| Application| Web-like development paradigm| UI development: HML, CSS, and JS<br>Service entries: files with fixed file names, which are **app.ets** (Page ability), **service.ts** (Service ability), and **data.ts** (Data ability)<br>Service logic: JS and TS|
| | Declarative development paradigm| UI development: ArkTS<br>Service entries: files with fixed file names, which are **app.ets** (Page ability), **service.ts** (Service ability), and **data.ts** (Data ability)<br>Service logic: JS and TS|
| Service widget| Web-like development paradigm| UI development: HML, CSS, and JSON (action)<br>Service entry: **form.ts**<br>Service logic: JS and TS|
| | Declarative development paradigm| Not supported currently|
**Stage Model**
| Type| UI Development Paradigm | Description|
| -------- | --------------------------- | --------------------------- |
| Application| Web-like development paradigm| Not supported currently|
| | Declarative development paradigm| UI development: ArkTS<br>Service entries: derived from **ohos.application.Ability**/**ExtensionAbility**<br>Service logic: TS|
| Service widget| Web-like development paradigm| UI development: HML, CSS, and JSON (action)<br>Service entries: derived from **FormExtensionAbility**<br>Service logic: TS|
| | Declarative development paradigm| Not supported currently|
......@@ -76,7 +76,7 @@ The ES6 syntax is supported.
```
- Page objects
| Attribute | Type | Description |
| Name | Type | Description |
| -------- | -------- | -------- |
| data | Object/Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The attribute name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid).<br/>Do not use this attribute and private or public at the same time. |
| $refs | Object | DOM elements or child component instances that have registered the ref attribute. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element). |
......@@ -171,8 +171,8 @@ The ES6 syntax is supported.
images: [
{ src: '/common/frame1.png' },
{ src: '/common/frame2.png' },
{ src: '/common/frame3.png' },
],
{ src: '/common/frame3.png' }
]
},
handleClick() {
const animator = this.$refs.animator; // Obtain the DOM element whose $refs attribute is animator.
......@@ -204,8 +204,8 @@ The ES6 syntax is supported.
images: [
{ src: '/common/frame1.png' },
{ src: '/common/frame2.png' },
{ src: '/common/frame3.png' },
],
{ src: '/common/frame3.png' }
]
},
handleClick() {
const animator = this.$element('animator'); // Obtain the DOM element whose ID is animator.
......@@ -255,8 +255,8 @@ Customize the parent component.
<!-- parent.hml -->
<element name='childComp' src='../child/child.hml'></element>
<div class="item" onclick="textClicked">
<text class="text-style" onclick="parentClicked">Click this parent component</text>
<text class="text-style" if="{{show}}">Hello parent component!</text>
<text class="text-style" onclick="parentClicked">parent component click</text>
<text class="text-style" if="{{showValue}}">hello parent component!</text>
<childComp id = "selfDefineChild"></childComp>
</div>
```
......@@ -265,11 +265,11 @@ Customize the parent component.
// parent.js
export default {
data: {
show: false,
text: 'I am the parent component!',
showValue: false,
text: 'I am parent component!',
},
parentClicked () {
this.show = !this.show;
this.showValue = !this.showValue;
console.info('parent component get parent text');
console.info(`${this.$parent().text}`);
console.info("The parent component gets the child function.");
......
# Path2D
**&lt;Path2D&gt;** allows you to describe a path through an existing path. This path can be drawn through the **stroke** API of **Canvas**. For details, see [Path2D](../reference/arkui-js/js-components-canvas-path2d.md).
**\<Path2D>** allows you to describe a path through an existing path. This path can be drawn through the **stroke** API of **Canvas**. For details, see [Path2D](../reference/arkui-js/js-components-canvas-path2d.md).
## Drawing Line Segments
Create a **&lt;Path2D&gt;** object and use line segments to create different shapes.
## Drawing Line Segments
Create a **\<Path2D>** object and use line segments to create different shapes.
```html
<!-- xxx.hml -->
......@@ -18,58 +17,63 @@ Create a **&lt;Path2D&gt;** object and use line segments to create different sha
```css
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
.container {
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
canvas{
width: 600px;
height: 600px;
background-color: #fdfdfd;
border: 5px solid red;
canvas {
width: 600px;
height: 600px;
background-color: #fdfdfd;
border: 5px solid red;
}
```
```js
// xxx.js
import prompt from '@system.prompt';
export default {
onShow(){
let ctx = this.$refs.canvas.getContext('2d',{antialias: true});
let path = ctx.createPath2D();
// Roof
path.moveTo(10, 300);
path.lineTo(210,100);
path.lineTo(410, 300);
// House
path.moveTo(10, 300);
path.lineTo(410, 300);
path.lineTo(410, 600);
path.lineTo(10, 600);
path.closePath();
// Window
path.moveTo(50, 450);
path.bezierCurveTo(70, 350, 130, 350, 150, 450);
path.closePath();
// Door
path.moveTo(250, 450);
path.rect(250, 450, 350, 600);
path.closePath();
// Chimney
path.moveTo(365, 250);
path.ellipse(310, 215, 30, 130,0, Math.PI * 0.04, Math.PI * 1.1, 1);
// Tree
path.moveTo(485, 450);
path.quadraticCurveTo(510, 500, 485, 600);
path.moveTo(550, 450);
path.quadraticCurveTo(525, 500, 550, 600);
path.moveTo(600, 535);
path.arc(520, 450, 85, 0, 6);
ctx.stroke(path);
},
onShow() {
let ctx = this.$refs.canvas.getContext('2d', {
antialias: true
});
let path = ctx.createPath2D();
// Roof
path.moveTo(10, 300);
path.lineTo(210, 100);
path.lineTo(410, 300);
// House
path.moveTo(10, 300);
path.lineTo(410, 300);
path.lineTo(410, 600);
path.lineTo(10, 600);
path.closePath();
// Window
path.moveTo(50, 450);
path.bezierCurveTo(70, 350, 130, 350, 150, 450);
path.closePath();
// Door
path.moveTo(250, 450);
path.rect(250, 450, 350, 600);
path.closePath();
// Chimney
path.moveTo(365, 250);
path.ellipse(310, 215, 30, 130, 0, Math.PI * 0.04, Math.PI * 1.1, 1);
// Tree
path.moveTo(485, 450);
path.quadraticCurveTo(510, 500, 485, 600);
path.moveTo(550, 450);
path.quadraticCurveTo(525, 500, 550, 600);
path.moveTo(600, 535);
path.arc(520, 450, 85, 0, 6);
ctx.stroke(path);
}
}
```
......@@ -79,52 +83,56 @@ export default {
## Drawing Graphs
Use **createPath2D** to create a path object and draw only **path1** so that only **path1** is displayed on the canvas. Click the **&lt;text&gt;** component to trigger the **addPath** method. The **path2** object is passed to **path1** as a parameter. After the **stroke** operation is performed on the **path1** object, **path1** and **path2** are displayed on the canvas. Click **Change** to change the value of **setTransform** to** setTransform(2, 0.1, 0.1, 2, 0,0)**. The graph is enlarged and tilted to the left.
Use **createPath2D** to create a path object and draw only **path1** so that only **path1** is displayed on the canvas. Click the **\<text>** component to trigger the **addPath** method. The **path2** object is passed to **path1** as a parameter. After the **stroke** operation is performed on the **path1** object, **path1** and **path2** are displayed on the canvas. Click **Change** to change the value of **setTransform** to** setTransform(2, 0.1, 0.1, 2, 0,0)**. The graph is enlarged and tilted to the left.
```html
<!-- xxx.hml -->
<div class="container">
<canvas ref="canvas"></canvas>
<div class="content">
<text onclick="addPath">{{ isAdd }}</text>
<text onclick="setTransform">{{textName}}</text>
</div>
<canvas ref="canvas"></canvas>
<div class="content">
<text onclick="addPath">{{ isAdd }}</text>
<text onclick="setTransform">{{ textName }}</text>
</div>
</div>
```
```css
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
.container {
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
canvas{
width: 600px;
height: 600px;
background-color: #fdfdfd;
border: 5px solid red;
canvas {
width: 600px;
height: 600px;
background-color: #fdfdfd;
border: 5px solid red;
}
.content{
width: 80%;
margin-top: 50px;
margin-bottom: 50px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
.content {
width: 80%;
margin-top: 50px;
margin-bottom: 50px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
text{
width: 150px;
height: 80px;
color: white;
border-radius: 20px;
text-align: center;
background-color: #6060e7;
margin-bottom: 30px;
text {
width: 150px;
height: 80px;
color: white;
border-radius: 20px;
text-align: center;
background-color: #6060e7;
margin-bottom: 30px;
}
```
......@@ -132,58 +140,66 @@ text{
```js
// xxx.js
import prompt from '@system.prompt';
export default {
data:{
ctx: null,
path1: null,
path2: null,
path3: null,
isAdd: "addPath2",
isChange: true,
textName: 'change'
},
onShow(){
this.ctx = this.$refs.canvas.getContext('2d',{antialias:true});
this.path1 = this.ctx.createPath2D();
this.path1.moveTo(200, 200);
this.path1.lineTo(400, 200);
this.path1.lineTo(400, 400);
this.path1.lineTo(200, 400);
this.path1.closePath();
this.path2 = this.ctx.createPath2D();
this.path2.arc(300, 300, 75, 0, 6.28)
this.ctx.stroke(this.path1);
},
addPath(){
if(this.isAdd == "addPath2"){
this.ctx.clearRect(0,0,600,600)
this.ctx.beginPath();
this.path2.addPath(this.path1)
this.ctx.stroke(this.path2);
this.isAdd = "clearPath2"
}else{
this.ctx.clearRect(0,0,600,600)
this.ctx.stroke(this.path1);
this.isAdd = "addPath2"
}
},
setTransform(){
if(this.isChange){
this.ctx.clearRect(0,0,600,600)
this.path3 = this.ctx.createPath2D();
this.path3.arc(150, 150, 100, 0, 6.28)
this.path3.setTransform(2, 0.1, 0.1, 2, 0,0);
this.ctx.stroke(this.path3);
this.isChange = !this.isChange;
this.textName = "back"
}else{
this.ctx.clearRect(0,0,600,600)
this.path3.setTransform(0.5, -0.1, -0.1, 0.5, 0,0);
this.ctx.stroke(this.path3);
this.isChange = !this.isChange;
this.textName = "change"
data: {
ctx: null,
path1: null,
path2: null,
path3: null,
isAdd: "addPath2",
isChange: true,
textName: 'change'
},
onShow() {
this.ctx = this.$refs.canvas.getContext('2d', {
antialias: true
});
this.path1 = this.ctx.createPath2D();
// Square
this.path1.moveTo(200, 200);
this.path1.lineTo(400, 200);
this.path1.lineTo(400, 400);
this.path1.lineTo(200, 400);
this.path1.closePath();
this.path2 = this.ctx.createPath2D();
// Arc
this.path2.arc(300, 300, 75, 0, 6.28);
this.ctx.stroke(this.path1);
},
addPath() {
if (this.isAdd == "addPath2") {
// Clear the content in the specified area on the canvas.
this.ctx.clearRect(0, 0, 600, 600);
this.ctx.beginPath();
// Add a path to the current path.
this.path2.addPath(this.path1);
this.ctx.stroke(this.path2);
this.isAdd = "clearPath2";
} else {
this.ctx.clearRect(0, 0, 600, 600);
this.ctx.stroke(this.path1);
this.isAdd = "addPath2";
}
},
setTransform() {
if (this.isChange) {
this.ctx.clearRect(0, 0, 600, 600);
this.path3 = this.ctx.createPath2D();
this.path3.arc(150, 150, 100, 0, 6.28);
// Reset and create a new transformation matrix.
this.path3.setTransform(2, 0.1, 0.1, 2, 0, 0);
this.ctx.stroke(this.path3);
this.isChange = !this.isChange;
this.textName = "back"
} else {
this.ctx.clearRect(0, 0, 600, 600);
this.path3.setTransform(0.5, -0.1, -0.1, 0.5, 0, 0);
this.ctx.stroke(this.path3);
this.isChange = !this.isChange;
this.textName = "change";
}
}
},
}
```
......
......@@ -4,7 +4,7 @@
The diet application allows food on the home page to display in list or grid mode. You can implement switching between food categories through tabs in grid mode.
1. Import the Category enumeration type to the **FoodCategoryList** page.
1. Import the **Category** enumeration type to the **FoodCategoryList** page.
```ts
import { Category, FoodData } from '../model/FoodData'
......@@ -121,9 +121,9 @@ The diet application allows food on the home page to display in list or grid mod
![en-us_image_0000001222807800](figures/en-us_image_0000001222807800.gif)
6. Create a tab to display all food categories (All). Create the **\<Tabs>** component and its child component **TabContent** in the **FoodCategory** component, and set **tabBar** to **All**. Set the width of the **TabBars** to **280** and the layout mode to **Scrollable**. This means that the TabBars can be scrolled when the total length exceeds 280. The **\<Tabs>** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a TabContent.
6. Create a tab to display all food categories (**All**). Create the **\<Tabs>** component and its child component **TabContent** in the **FoodCategory** component, and set **tabBar** to **All**. Set the width of the **TabBars** to **280** and the layout mode to **Scrollable**. This means that the TabBars can be scrolled when the total length exceeds 280. The **\<Tabs>** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a TabContent.
```
```ts
@Component
struct FoodCategory {
private foodItems: FoodData[]
......@@ -204,7 +204,7 @@ The diet application allows food on the home page to display in list or grid mod
.objectFit(ImageFit.Contain)
.height(152)
.width('100%')
}.backgroundColor('#FFf1f3f5')
}
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Text(this.foodItem.name)
.fontSize(14)
......@@ -251,120 +251,122 @@ The diet application allows food on the home page to display in list or grid mod
10. Create the Category.Vegetable, Category.Fruit, Category.Nut, Category.SeaFood, and Category.Dessert tabs.
```ts
@Component
struct FoodCategory {
private foodItems: FoodData[]
build() {
Stack() {
Tabs() {
TabContent() {
FoodGrid({ foodItems: this.foodItems })
}.tabBar('All')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Vegetable)) })
}.tabBar('Vegetable')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Fruit)) })
}.tabBar('Fruit')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Nut)) })
}.tabBar('Nut')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Seafood)) })
}.tabBar('Seafood')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Dessert)) })
}.tabBar('Dessert')
```ts
@Component
struct FoodCategory {
private foodItems: FoodData[]
build() {
Stack() {
Tabs() {
TabContent() {
FoodGrid({ foodItems: this.foodItems })
}.tabBar('All')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Vegetable)) })
}.tabBar('Vegetable')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Fruit)) })
}.tabBar('Fruit')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Nut)) })
}.tabBar('Nut')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Seafood)) })
}.tabBar('Seafood')
TabContent() {
FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Dessert)) })
}.tabBar('Dessert')
}
.barWidth(280)
.barMode(BarMode.Scrollable)
}
.barWidth(280)
.barMode(BarMode.Scrollable)
}
}
}
```
```
11. Set the number of rows and height of grids for different food categories. Because the number of foods varies according to the category, the **'1fr 1fr 1fr 1fr 1fr 1fr'** constant cannot be used to set the number of rows to 6.
Create member variables **gridRowTemplate** and **HeightValue**, and set the number of grid rows and height by using these member variables.
```ts
@Component
struct FoodGrid {
private foodItems: FoodData[]
private gridRowTemplate : string = ''
private heightValue: number
build() {
Scroll() {
Grid() {
ForEach(this.foodItems, (item: FoodData) => {
GridItem() {
FoodGridItem({foodItem: item})
}
}, (item: FoodData) => item.id.toString())
}
.rowsTemplate(this.gridRowTemplate)
.columnsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height(this.heightValue)
}
.scrollBar(BarState.Off)
.padding({left: 16, right: 16})
}
}
```
Invoke the aboutToAppear API to calculate the number of rows (**gridRowTemplate**) and height (**heightValue**).
```ts
aboutToAppear() {
var rows = Math.round(this.foodItems.length / 2);
this.gridRowTemplate = '1fr '.repeat(rows);
this.heightValue = rows * 192 - 8;
}
```
The custom component provides two lifecycle callbacks: **aboutToAppear** and **aboutToDisappear**. **aboutToAppear** is executed after the custom component is created and before the build method of the custom component is executed. **aboutToDisappear** is executed when the custom component is deinitialized.
![en-us_image_0000001267647885](figures/en-us_image_0000001267647885.png)
Create member variables **gridRowTemplate** and **HeightValue**, and set the number of grid rows and height by using these member variables.
```ts
@Component
struct FoodGrid {
private foodItems: FoodData[]
private gridRowTemplate : string = ''
private heightValue: number
aboutToAppear() {
var rows = Math.round(this.foodItems.length / 2);
this.gridRowTemplate = '1fr '.repeat(rows);
this.heightValue = rows * 192 - 8;
}
build() {
Scroll() {
Grid() {
ForEach(this.foodItems, (item: FoodData) => {
GridItem() {
FoodGridItem({foodItem: item})
}
}, (item: FoodData) => item.id.toString())
}
.rowsTemplate(this.gridRowTemplate)
.columnsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height(this.heightValue)
}
.scrollBar(BarState.Off)
.padding({left: 16, right: 16})
}
}
```
![en-us_image_0000001267887869](figures/en-us_image_0000001267887869.gif)
```ts
@Component
struct FoodGrid {
private foodItems: FoodData[]
private gridRowTemplate: string = ''
private heightValue: number
build() {
Scroll() {
Grid() {
ForEach(this.foodItems, (item: FoodData) => {
GridItem() {
FoodGridItem({ foodItem: item })
}
}, (item: FoodData) => item.id.toString())
}
.rowsTemplate(this.gridRowTemplate)
.columnsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height(this.heightValue)
}
.scrollBar(BarState.Off)
.padding({ left: 16, right: 16 })
}
}
```
Invoke the **aboutToAppear** API to calculate the number of rows (**gridRowTemplate**) and height (**heightValue**).
```ts
aboutToAppear() {
var rows = Math.round(this.foodItems.length / 2);
this.gridRowTemplate = '1fr '.repeat(rows);
this.heightValue = rows * 192 - 8;
}
```
The custom component provides two lifecycle callbacks: **aboutToAppear** and **aboutToDisappear**. **aboutToAppear** is executed after the custom component is created and before the build method of the custom component is executed. **aboutToDisappear** is executed when the custom component is deinitialized.
![en-us_image_0000001267647885](figures/en-us_image_0000001267647885.png)
```ts
@Component
struct FoodGrid {
private foodItems: FoodData[]
private gridRowTemplate: string = ''
private heightValue: number
aboutToAppear() {
var rows = Math.round(this.foodItems.length / 2);
this.gridRowTemplate = '1fr '.repeat(rows);
this.heightValue = rows * 192 - 8;
}
build() {
Scroll() {
Grid() {
ForEach(this.foodItems, (item: FoodData) => {
GridItem() {
FoodGridItem({ foodItem: item })
}
}, (item: FoodData) => item.id.toString())
}
.rowsTemplate(this.gridRowTemplate)
.columnsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height(this.heightValue)
}
.scrollBar(BarState.Off)
.padding({ left: 16, right: 16 })
}
}
```
![en-us_image_0000001267887869](figures/en-us_image_0000001267887869.gif)
\ No newline at end of file
......@@ -14,7 +14,7 @@ Media queries are widely used on mobile devices. You can use them to modify the
Invoke the **mediaquery** API to set the media query condition and the callback, and change the page layout or implement service logic in the callback corresponding to the condition.
First, import the mediaquery module, as shown below:
```
```ts
import mediaquery from '@ohos.mediaquery'
```
Then, use the **matchMediaSync** API to set the media query condition and save the returned listener, as shown below:
......@@ -63,10 +63,10 @@ You can use logical operators (**and**, **or**, **not**, and **only**) to compos
| Type | Description |
| -------- | ---------------------------------------- |
| and | The **and** operator is used to combine multiple media features into one media query, in a logical AND operation. The query is valid only when all media features are true. It can also combine media types and media functions.<br>For example, **screen and (device-type: wearable) and (max-height: 600) ** indicates that the query is valid when the device type is wearable and the maximum height of the application is 600 pixel units.|
| or | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true.<br>For example, **screen and (max-height: 1000) or (round-screen: true)** indicates that the query is valid when the maximum height of the application is 1000 pixel units or the device screen is round. |
| not | The **not** operator is used to perform a logical negation for a media query. **true** is returned if the query condition is not met. Otherwise, **false** is returned. In a media query list, logical negation is performed only for the media query using the **not** operator.<br>For example, **not screen and (min-height: 50) and (max-height: 600) ** indicates that the query is valid when the height of the application is less than 50 pixel units or greater than 600 pixel units.<br>**NOTE**<br>When the **not** operator is used, the media type must be specified. |
| only | The **only** operator applies the selected style only when the entire expression is matched. It can be used to prevent ambiguity on browsers of earlier versions. The statements that contain both media types and media features produce ambiguity when they are received by some browsers of earlier versions. For example:<br>screen and (min-height: 50)<br>The browsers of earlier versions would mislead this sentence into screen, causing the fact that the specified style is applied when only the media type is matched. In this case, the **only** operator can be used to avoid this problem.<br>**NOTE**<br>When the **only** operator is used, the media type must be specified. |
| ,(comma) | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true. The effect of a comma operator is equivalent to that of the **or** operator.<br>For example, **screen and (min-height: 1000), (round-screen: true) ** indicates that the query is valid when the minimum height of the application is 1000 pixel units or the device screen is round.|
| or | The **or** operator is used to combine multiple media features into one media query, in a logical OR operation. The query is valid if a media feature is true.<br>For example, **screen and (max-height: 1000) or (round-screen: true)** indicates that the query is valid when the maximum height of the application is 1000 pixel units or the device screen is round.|
At MediaQuery Level 4, range query is imported so that you can use the operators including &lt;=, &gt;=, &lt;, and &gt; besides the max- and min-operators.
......@@ -107,41 +107,41 @@ At MediaQuery Level 4, range query is imported so that you can use the operators
Use media queries to apply different content and styles to the page text when the screen is switched between landscape and portrait modes.
```
import mediaquery from '@ohos.mediaquery'
let portraitFunc = null
@Entry
@Component
struct MediaQueryExample {
@State color: string = '#DB7093'
@State text: string = 'Portrait'
@State fontSize: number = 24
listener = mediaquery.matchMediaSync('(orientation: landscape)')
onPortrait(mediaQueryResult) {
if (mediaQueryResult.matches) {
this.color = '#FFD700'
this.text = 'Landscape'
} else {
this.color = '#DB7093'
this.text = 'Portrait'
}
}
aboutToAppear() {
portraitFunc = this.onPortrait.bind(this) //bind current js instance
this.listener.on('change', portraitFunc)
```ts
import mediaquery from '@ohos.mediaquery'
let portraitFunc = null
@Entry
@Component
struct MediaQueryExample {
@State color: string = '#DB7093'
@State text: string = 'Portrait'
listener = mediaquery.matchMediaSync('(orientation: landscape)') // The query is valid when the device is in landscape mode.
onPortrait(mediaQueryResult) {
if (mediaQueryResult.matches) {
this.color = '#FFD700'
this.text = 'Landscape'
} else {
this.color = '#DB7093'
this.text = 'Portrait'
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.text).fontSize(50).fontColor(this.color)
}
.width('100%').height('100%')
}
aboutToAppear() {
portraitFunc = this.onPortrait.bind(this) // Bind to the current application instance.
this.listener.on('change', portraitFunc)
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.text).fontSize(50).fontColor(this.color)
}
.width('100%').height('100%')
}
```
}
```
When the device is in landscape orientation, the text content is displayed in landscape mode in the color of #FFD700.<br>
![en-us_image_0000001262954829](figures/en-us_image_0000001262954829.png)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册