未验证 提交 610a70c7 编写于 作者: O openharmony_ci 提交者: Gitee

!2215 JS指南更新

Merge pull request !2215 from LiAn/master
# svg动画
为svg组件添加动画效果。
## 属性样式动画
在Svg的子组件[animate](../reference/arkui-js/js-components-svg-animate.md)中,通过attributeName设置需要进行动效的属性,from设置开始值,to设置结束值。
```
<!-- xxx.hml -->
<div class="container">
<svg>
<text x="300" y="300" fill="blue">
Hello
<animate attributeName="font-size" from="30" to="60" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="fill" from="red" to="blue" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="opacity" from="1" to="0.3" dur="3s" repeatCount="indefinite">
</animate>
</text>
<text x="300" y="600" fill="blue">
World
<animate attributeName="font-size" from="30" to="60" values="30;80" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="fill" from="red" to="blue" dur="3s" repeatCount="indefinite">
</animate>
<animate attributeName="opacity" from="0.3" to="1" dur="3s" repeatCount="indefinite">
</animate>
</text>
</svg>
</div>
```
![zh-cn_image_0000001183871404](figures/zh-cn_image_0000001183871404.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 在设置动画变化值时,如果已经设置了values属性,则from和to都失效。
## 路径动画
在Svg的子组件[animateMotion](../reference/arkui-js/js-components-svg-animatemotion.md)中,通过path设置动画变化的路径。
```
<!-- xxx.hml -->
<div class="container">
<svg fill="white" width="800" height="900">
<path d="M300,200 h-150 a150 150 0 1 0 150 -150 z" fill="white" stroke="blue" stroke-width="5" >
</path>
<path fill="red" d="M-5,-5 L10,0 L-5,5 L0,0 Z" >
<animateMotion dur="2000" repeatCount="indefinite" rotate="auto-reverse"path="M300,200 h-150 a150 150 0 1 0 150 -150 z">
</animateMotion>
</path>
</svg>
</div>
```
![zh-cn_image_0000001229510983](figures/zh-cn_image_0000001229510983.gif)
## animateTransform动画
在Svg的子组件[animateMotion](../reference/arkui-js/js-components-svg-animatetransform.md)中,通过attributeName绑定transform属性,type设置动画类型,from设置开始值,to设置结束值。
```
<!-- xxx.hml -->
<div class="container" style="">
<svg>
<line x1="90" y1="300" x2="90" y2="730" stroke-width="10" stroke="black" stroke-linecap="round">
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="3s" values="0;30;10;30;20;30;25;30" keyTimes="0;0.3;0.5;0.7;0.8;0.9;1.0;1.1"
fill="freeze">
</animateTransform>
</line>
<circle cx="500" cy="500" r="50" stroke-width="15" fill="red" stroke="#e70d0d">
<animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="3s" values="0;30;10;30;20;30;25;30" keyTimes="0;0.3;0.5;0.7;0.8;0.9;1.0;1.1" fill="freeze">
</animateTransform>
<animateTransform attributeName="transform" attributeType="XML" type="scale" dur="6s" values="1;1;1.3" keyTimes="0;0.5;1" fill="freeze"></animateTransform>
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="9s" values="0;0;300 7" keyTimes="0;0.6;0.9" fill="freeze"></animateTransform>
</circle>
<rect width="500" height="200" x="90" y="840">
<animateTransform attributeName="transform" attributeType="XML" type="skewY" dur="6s" values="0;0;30" keyTimes="0;0.5;1" fill="freeze"></animateTransform>
</rect>
<line x1="650" y1="300" x2="650" y2="600" stroke-width="20" stroke="blue" stroke-linecap="round">
<animateTransform attributeName="transform" attributeType="XML" type="translate" dur="9s" values="0;0;0 800" keyTimes="0;0.6;1" fill="freeze"></animateTransform>
</line>
</svg>
</div>
```
```
/* xxx.css */
.container {
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001182832088](figures/zh-cn_image_0000001182832088.gif)
# 基础组件
- **[Text开发指导](ui-js-components-text.md)**
- **[Input开发指导](ui-js-components-input.md)**
- **[Button开发指导](ui-js-components-button.md)**
- **[Picker开发指导](ui-js-components-picker.md)**
- **[Image开发指导](ui-js-components-images.md)**
- **[Image-animator开发指导](ui-js-components-image-animator.md)**
- **[Rating开发指导](ui-js-components-rating.md)**
- **[Slider开发指导](ui-js-components-slider.md)**
- **[Chart开发指导](ui-js-components-chart.md)**
- **[Switch开发指导](ui-js-components-switch.md)**
- **[Toolbar开发指导](ui-js-components-toolbar.md)**
- **[Menu](ui-js-components-menu.md)**
- **[Marquee开发指导](ui-js-components-marquee.md)**
- **[Qrcode](ui-js-components-qrcode.md)**
- **[Search](ui-js-components-search.md)**
\ No newline at end of file
# 常见组件开发指导
- **[Text](ui-js-components-text.md)**
- **[Input](ui-js-components-input.md)**
- **[Button](ui-js-components-button.md)**
- **[List](ui-js-components-list.md)**
- **[Picker](ui-js-components-picker.md)**
- **[Dialog](ui-js-components-dialog.md)**
- **[Form](ui-js-components-form.md)**
- **[Stepper](ui-js-components-stepper.md)**
- **[Tabs](ui-js-component-tabs.md)**
- **[Image](ui-js-components-images.md)**
\ No newline at end of file
# ui
- 常见组件开发指导
- 容器组件
- [List开发指导](ui-js-components-list.md)
- [Dialog开发指导](ui-js-components-dialog.md)
- [Form开发指导](ui-js-components-form.md)
- [Stepper开发指导](ui-js-components-stepper.md)
- [Tabs开发指导](ui-js-component-tabs.md)
- [Swiper开发指导](ui-js-components-swiper.md)
- 基础组件
- [Text开发指导](ui-js-components-text.md)
- [Input开发指导](ui-js-components-input.md)
- [Button开发指导](ui-js-components-button.md)
- [Picker开发指导](ui-js-components-picker.md)
- [Image开发指导](ui-js-components-images.md)
- [Image-animator开发指导](ui-js-components-image-animator.md)
- [Rating开发指导](ui-js-components-rating.md)
- [Slider开发指导](ui-js-components-slider.md)
- [Chart开发指导](ui-js-components-chart.md)
- [Switch开发指导](ui-js-components-switch.md)
- [Toolbar开发指导](ui-js-components-toolbar.md)
- [Menu开发指导](ui-js-components-menu.md)
- [Marquee开发指导](ui-js-components-marquee.md)
- [Qrcode开发指导](ui-js-components-qrcode.md)
- [Search开发指导](ui-js-components-search.md)
- Canvas开发指导
- [CanvasRenderingContext2D对象](ui-js-components-canvasrenderingcontext2d.md)
- [Path2D对象](ui-js-components-path2d.md)
- [OffscreenCanvas对象](ui-js-components-offscreencanvas.md)
- [栅格布局](ui-js-components-calendar.md)
- Svg开发指导
- [基础知识](ui-js-components-svg-overview.md)
- [绘制图形](ui-js-components-svg-graphics.md)
- [绘制路径](ui-js-components-svg-path.md)
- [绘制文本](ui-js-components-svg-text.md)
# Grid
栅格布局容器根节点,使用grid-row与grid-col进行栅格布局。具体请参考[Grid-container](../reference/arkui-js/js-components-grid-container.md)
## 创建grid-container组件
在pages/index目录下的hml文件中创建一个grid-container组件,并添加[Grid-row](../reference/arkui-js/js-components-grid-row.md)子组件。
```
<!-- index.hml -->
<div class="container">
<grid-container id="mygrid" columns="5" gutter="20px" style="background-color: pink;">
<grid-row style="height:100px;justify-content:space-around;width: 80%;background-color: #f67002;margin-left:
10%;"></grid-row>
<grid-row style="height:300px;justify-content:space-around;background-color: #ffcf00;width: 100%;"></grid-row>
<grid-row style="height:150px;justify-content:space-around;background-color: #032cf8;width: 100%;"></grid-row>
</grid-container>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
justify-content: center;
align-items: center;
}
```
![zh-cn_image_0000001226897009](figures/zh-cn_image_0000001226897009.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> grid-container仅支持grid-row为子组件。
## 调用方法
grid-container点击组件调用getColumns、getColumnWidth、getGutterWidth方法,返回栅格容器列数、column宽度及gutter宽度。长按调用getSizeType方法返回当前容器响应尺寸类型(xs|sm|md|lg)。
```
<!-- index.hml -->
<div class="container">
<grid-container id="mygrid" columns="6" gutter="20px" style="background-color: pink;padding-top: 100px;"
onclick="getColumns" onlongpress="getSizeType">
<grid-row style="height:100px;justify-content:space-around;background-color: #4cedf3;width: 20%;margin-left:
40%;"></grid-row>
<grid-row style="height:150px;justify-content:space-around;background-color: #4cbff3;width: 50%;margin-left:
25%;"></grid-row>
<grid-row style="height:200px;justify-content:space-around;background-color: #465ff6;width: 80%;margin-left:
10%;"></grid-row>
<grid-row style="height:200px;justify-content:space-around;background-color: #5011ec;width: 100%;"></grid-row>
</grid-container>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
justify-content: center;
align-items: center;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
data:{
gutterWidth:'',
columnWidth:'',
columns:'',
},
getColumns(){
this.$element('mygrid').getColumnWidth((result)=>{
this.columnWidth = result;
})
this.$element('mygrid').getGutterWidth((result)=>{
this.gutterWidth = result;
})
this.$element('mygrid').getColumns((result)=>{
this.columns= result;
})
setTimeout(()=>{
prompt.showToast({duration:5000,message:'columnWidth:'+this.columnWidth+',gutterWidth:'+
this.gutterWidth+',getColumns:'+this.columns})
})
},
getSizeType(){
this.$element('mygrid').getSizeType((result)=>{
prompt.showToast({duration:2000,message:'get size type:'+result})
})
},
}
```
![zh-cn_image_0000001227135613](figures/zh-cn_image_0000001227135613.gif)
## 添加grild-col
创建grid-container组件并添加grid-row,在grid-row组件内添加grild-col组件形成布局。
```
<!-- index.hml -->
<div class="container">
<grid-container id="mygrid" columns="4" gutter="0" style="background-color: pink;" onclick="getColumns" onlongpress="getSizeType">
<grid-row style="height: 100px;justify-content: space-around;background-color: #4cbff3;width: 100%;">
<grid-col span="0">
<div style="align-items: center;justify-content: center;height: 100%;width: 100%;">
<text style="color: dodgerblue;" onclick="getCol">top</text>
</div>
</grid-col>
</grid-row>
<grid-row style="height:500px;justify-content:space-around;background-color: #3b55ef;width: 100%;">
<grid-col span="0" style="width: 20%;">
<div style="align-items: center;justify-content: center;height: 100%;width: 100%;">
<text style="color: dodgerblue;">left</text>
</div>
</grid-col>
<grid-col span="0" style="background-color:orange;width: 80%;">
<div style="width: 100%;height: 100%;align-items: center;justify-content: center;">
<text>right</text>
</div>
</grid-col>
</grid-row>
<grid-row style="height: 100px;justify-content: space-around;background-color: #4cbff3;width: 100%;">
<grid-col style="background-color:#c075ef;" span="0">
<div style="width: 100%;height: 100%;padding: 20px;align-items: center;justify-content: center;">
<text>bottom</text>
</div>
</grid-col>
</grid-row>
</grid-container>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
justify-content: center;
align-items: center;
}
text{
color: white;
font-size: 40px;
```
![zh-cn_image_0000001227135731](figures/zh-cn_image_0000001227135731.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> grid-row仅支持grid-col为子组件,只能在grid-col组件中添加填充的内容。
## 场景示例
本场景中循环输出list中的内容,创建出网格布局。进行下拉操时触发refresh(刷新页面)方法,这时会向list数组中添加一条数据并设置setTimeout(延迟触发),达到刷新请求数据的效果。
```
<!-- index.hml -->
<div class="container">
<refresh refreshing="{{fresh}}" onrefresh="refresh">
<grid-container id="mygrid" gutter="20" style="margin: 10px;">
<grid-row style="height:200px;width: 100%;background-color: #e7e7e2;margin-top: 50px; padding: 0px 20px;border-radius: 15px;" for="item in list">
<grid-col span="0" style="width: 40%;">
<div style="align-items: center;justify-content: center">
<image src="{{item.src}}" style="object-fit: contain;border-radius: 30px;"></image>
</div>
</grid-col>
<grid-col span="0" style="width: 60%;">
<div style="align-items: center;justify-content: center;width: 100%;height: 100%;text-align: center;">
<text>image{{item.id}}</text>
</div>
</grid-col>
</grid-row>
</grid-container>
</refresh>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
}
text{
color: #0a0aef;
font-size: 60px;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
data:{
list:[
{src:'common/images/1.png',id:'1'},
{src:'common/images/2.png',id:'2'},
{src:'common/images/3.png',id:'3'}
],
fresh:false
},
refresh(e) {
prompt.showToast({
message: 'refreshing'
})
var that = this;
that.fresh = e.refreshing;
setTimeout(function () {
that.fresh = false;
that.list.unshift({src: 'common/images/4.png',id:'4'});
prompt.showToast({
message: 'succeed'
})
}, 2000)
}
}
```
![zh-cn_image_0000001263160403](figures/zh-cn_image_0000001263160403.gif)
# Canvas开发指导
Canvas组件提供画布,用于自定义绘制图形。具体用法请参考[CanvasRenderingContext2D对象](../reference/arkui-js/js-components-canvas-canvasrenderingcontext2d.md)
## 创建Canvas组件
在pages/index目录下的hml文件中创建一个Canvas组件。
```
<!-- xxx.hml -->
<div class="container">
<canvas></canvas>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
canvas{
background-color: #00ff73;
}
```
![zh-cn_image_0000001222984605](figures/zh-cn_image_0000001222984605.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - Canvas组件默认背景色与父组件的背景色一致。
>
> - Canvas默认宽高为width: 300px,height: 150px。
## 添加样式
Canvas组件设置宽(width)、高(height)、背景色(background-color)及边框样式(border)。
```
<!-- xxx.hml -->
<div class="container">
<canvas></canvas>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
canvas{
width: 500px; height: 500px; background-color: #fdfdfd; border: 5px solid red;
}
```
![zh-cn_image_0000001177623482](figures/zh-cn_image_0000001177623482.png)
## 添加事件
Canvas添加长按事件,长按后可获取Canvas组件的dataUrl值(toDataURL方法返回的图片信息),打印在下方文本区域内。
```
<!-- xxx.hml -->
<div class="container">
<canvas ref="canvas1" onlongpress="getUrl"></canvas>
<text>dataURL</text>
<text class="content">{{dataURL}}</text>
</div>
```
```
/* xxx.css */.container{ flex-direction: column; justify-content: center; align-items: center; background-color: #F1F3F5;}canvas{ width: 500px; height: 500px; background-color: #fdfdfd; border: 5px solid red;
margin-bottom: 50px;
}.content{ border: 5px solid blue; padding: 10px; width: 90%; height: 400px; overflow: scroll;}
```
```
// xxx.js
import prompt from '@system.prompt';
export default {
data:{
dataURL:null,
antialia: false,
porc:'open',
},
onShow(){
let el = this.$refs.canvas1 let ctx = el.getContext("2d") ctx.strokeRect(100,100,300,300)
},
getUrl(){
let el = this.$refs.canvas1
let dataUrl = el.toDataURL()
this.dataURL = dataUrl;
prompt.showToast({duration:2000,message:"long press,get dataURL"})
}
}
```
![zh-cn_image_0000001222985331](figures/zh-cn_image_0000001222985331.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 画布不支持在onInit和onReady中进行创建。
# Chart开发指导
Chart为图表组件,用于呈现线形图、柱状图和量规图界面。具体用法请参考[Chart](../reference/arkui-js/js-components-basic-chart.md)
## 创建Chart组件
在pages/index目录下的hml文件中创建一个Chart组件。
```
<!-- xxx.hml -->
<div class="container">
<chart class="chart-data" type="line" options="{{lineOps}}" datasets="{{lineData}}"></chart>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.chart-data {
width: 700px;
height: 600px;
}
```
```
/* xxx.js */
export default {
data: {
lineData: [
{
data: [763, 550, 551, 554, 731, 654, 525, 696, 595, 628, 791, 505, 613, 575, 475, 553, 491, 680, 657, 716]
}
],
lineOps: {
xAxis: {
min: 0,
max: 20,
display: false,
},
yAxis: {
min: 0,
max: 1000,
display: false,
},
series: {
lineStyle: {
width: 15,
},
}
},
}
}
```
![zh-cn_image_0000001181974568](figures/zh-cn_image_0000001181974568.png)
## 设置图表类型
Chart组件通过设置type属性定义图表t类型,如将图表设置为柱状图。
```
<!-- xxx.hml -->
<div class="container">
<div class="container">
<div class="switch-block">
<text class="title">
{{ title }}
</text>
</div>
<tabs class="tabs" index="0" vertical="false" onchange="changes">
<tab-content class="tabcontent" scrollable="true">
<tabs >
<tab-bar class="tab-bar" mode="fixed"style="margin-bottom: 50px;">
<text class="tab-text">线形图</text>
<text class="tab-text">柱状图</text>
<text class="tab-text">量规图</text>
</tab-bar>
<tab-content>
<div class="bar-block" style="margin-left: 30px;">
<chart class="chart-data" type="line" ref="linechart" options="{{ lineOps }}" datasets="{{ lineData }}">
</chart>
</div>
<div class="bar-block">
<chart class="data-bar" type="bar" id="bar-chart" options="{{ barOps }}" datasets="{{ barData }}">
</chart>
</div>
<div class="chart-block">
<chart type="gauge" ></chart>
</div>
</tab-content>
</tabs>
</tab-content>
</tabs>
</div>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
background-color: #F1F3F5;
}
.chart-data {
width: 700px;
height: 600px;
}
.title{
margin-left: 50px;
margin-top: 50px;
font-size: 50px;
}
.line-block{
align-items: center;
justify-content: center;
}
.bar-block{
align-items: center;
justify-content: center;
}
.chart-block{
width: 90%;
margin-left: 30px;
}
```
```
/* xxx.js */
export default {
data: {
title: "类型展示",
barData: [
{
fillColor: '#3848e8',
data: [763, 550, 551, 554, 731, 654, 525, 696, 595],
}
],
lineData: [
{
strokeColor: '#0081ff',
fillColor: '#cce5ff',
data: [763, 550, 551, 554, 731, 654, 525, 696, 595, 628, 791, 505, 613, 575, 475, 553, 491, 680, 657, 716],
gradient: true,
}
],
lineOps: {
xAxis: {
min: 0,
max: 20,
display: false,
},
yAxis: {
min: 0,
max: 1000,
display: false,
},
series:{
lineStyle: {
width: "5px",
smooth: true,
},
headPoint: {
shape:"circle",
size: 20,
strokeWidth: 5,
fillColor: '#ffffff',
strokeColor: '#007aff',
display: true,
},
loop:{
margin: 2,
gradient: true
}
},
},
barOps: {
xAxis: {
min: 0,
max: 20,
display: false,
axisTick: 10,
},
yAxis: {
min: 0,
max: 1000,
},
},
},
}
```
![zh-cn_image_0000001227423251](figures/zh-cn_image_0000001227423251.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> Chart不支持显示每个点的值。
## 设置图表属性
Chart组件在options属性中设置对x轴、y轴和数据序列参数的设置,在datasets属性里添加对线条颜色、填充颜色、填充渐变颜色和绘制点集的设置。
```
<!-- xxx.hml -->
<div class="container">
<chart class="chart-data" type="line" options="{{lineOps}}" datasets="{{lineData}}"></chart>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.chart-data {
width: 700px;
height: 600px;
}
```
```
/* xxx.js */
export default {
data: {
//线形图数据
lineData: [
{
strokeColor: '#0081ff',
fillColor: '#cce5ff', //填充色
data: [463, 250, 251, 254, 431, 354, 225, 396, 295, 328, 491, 205, 313, 275, 475, 553, 491, 380, 357, 416],
gradient: true,
}
],
lineOps: {
//x轴参数设置
xAxis: { min: 0, max: 20, display: false, },
//y轴参数设置
yAxis: { min: 0, max: 1000, display: false, },
//数据序列参数设置
series: {
//线样式设置
lineStyle: { width: "5px", smooth: true, },
//线最前端位置白点的样式和大小
headPoint: { shape: "circle", size: 20, strokeWidth: 5, fillColor: '#ffffff', strokeColor: '#007aff', display: true, },
//设置屏幕显示满时,是否需要重头开始绘制
loop: { margin: 2, gradient: true } } },
},
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - options只支持柱状图和线形图设置参数,量规图不生效。
>
> - datasets只支持柱状图和线形图设置数据集合,量规图不生效。
>
> - series只有线形图支持。
## 添加数据
通过Chart组件的append方法,实现动态添加数据。
```
<!-- xxx.hml -->
<div class="container">
<stack class="chart-region">
<chart class="chart-data" type="line" ref="linechart" options="{{lineOps}}" datasets="{{lineData}}"></chart>
</stack>
<button value="Add data" onclick="addData"></button>
</div>
```
```
/* xxx.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.chart-region {
height: 400px;
width: 700px;
}
.chart-data {
width: 700px;
height: 600px;
}
button {
width: 100%;
height: 50px;
background-color: #F4F2F1;
text-color: #0C81F3;
margin-top: 30px;
}
```
```
// xxx.js
export default {
data: {
lineData: [
{
strokeColor: '#de0b6e',
fillColor: '#bb09a3',
data: [763, 550, 551, 554, 731, 654, 525, 696, 595, 628, 791, 505, 613, 575, 475, 553, 491, 680, 657, 716],
gradient: true,
}
],
lineOps: {
xAxis: {
min: 0,
max: 20,
display: false,
},
yAxis: {
min: 0,
max: 1000,
display: false,
},
series: {
lineStyle: {
width: "5px",
smooth: true,
},
headPoint: {
shape: "circle",
size: 20,
strokeWidth: 5,
fillColor: '#ffffff',
strokeColor: '#f8145c',
display: true,
},
loop: {
margin: 2,
gradient: true,
}
}
},
},
addData() { this.$refs.linechart.append({ serial: 0, data: [Math.floor(Math.random() * 400) + 200] }) }
}
```
![zh-cn_image_0000001221913395](figures/zh-cn_image_0000001221913395.gif)
## 场景示例
开发者可以根据开关Switch的状态来选择数据展示的状态,当Switch状态为true时,通过定时器来实现数据的动态展示。
```
<!-- xxx.hml -->
<div class="container">
<div class="container">
<div class="switch-block">
<text class="title">{{ title }} </text>
<switch class="switch" showtext="{{ showText }}" allow-scale="{{ allowScale }}"onchange="change">
</switch>
</div>
<tabs class="tabs" index="0" vertical="false" onchange="changes">
<tab-content class="tabcontent" scrollable="true">
<div>
<tabs class="tabs" index="0" vertical="false" onchange="changes">
<tab-content class="tabcontent" scrollable="true">
<div class="line-class">
<div class="bar-block">
<chart class="chart-data" type="line" ref="linechart" options="{{ lineOps }}"
datasets="{{ lineData }}">
</chart>
</div>
<div class="bar-block">
<chart class="data-bar" type="bar" id="bar-chart" options="{{ barOps }}"datasets="{{ barData }}">
</chart>
</div>
</div>
</tab-content>
</tabs>
</div>
<div>
<div class="container">
<list class="todo-wrapper">
<list-item for="{{ barData }}" class="todo-item">
<text class="todo-title">{{ $item.data }}</text>
</list-item>
</list>
<list class="todo-wrapper">
<list-item for="{{ lineData.data }}" class="todo-item">
<text class="todo-title">{{ $item.value }}</text>
</list-item>
</list>
</div>
</div>
</tab-content>
</tabs>
</div>
</div>
```
```
/* xxx.css */
.container{
display:flex;
flex-direction:column;
background-color: #F1F3F5;
}
.line-class{
display: flex;
flex-direction: column;
}
.title{
font-size: 40px;
margin-left: 40px;
}
.switch-block {
margin-top: 30px;
width: 98%;
height: 80px;
display: flex;
justify-content: space-between;
}
.switch{
font-size: 40px;
}
.bar-block {
margin-top: 80px;
margin-left: 40px;
position: relative;
width: 90%;
border-radius: 10px;
background-color: #25FAB27B;
height: 40%;
justify-content: center;
}
```
```
// xxx.js
export default {
data: {
interval: null,
title: "数据展示",
allowScale: true,
barGroup: 3,
lineData: null,
lineOps: {
xAxis: {
min: 0,
max: 5
},
yAxis: {
min: 0,
max: 100
},
series: {
lineStyle: {
width: '1px',
},
headPoint: {
shape: 'circle',
size: 10,
strokeWidth: 2,
fillColor: '#ffffff',
strokeColor: '#8477DF'
},
loop: {
margin: 2
}
}
},
barData: [
{
fillColor: '#97CF0A2C',
data: [20, 20,40, 56]
},
{
fillColor: '#6D0A7ACF',
data: [52, 40, 2, 67]
},
{
fillColor: '#6A0ACFA1',
data: [56, 2, 77, 40]
}
],
barOps: {
xAxis: {
min: 0,
max: 20,
axisTick: 5
},
yAxis: {
min: 0,
max: 100
}
}
},
onInit() {
this.changeLine();
},
change(e) {
if (e.checked) {
this.interval = setInterval(() => {
this.changeLine();
this.changeBar();
}, 1000)
} else {
clearInterval(this.interval);
}
},
changeLine() {
var dataArray = [];
for (var i = 0; i < this.dataLength; i++) {
var nowValue = Math.floor(Math.random() * 99 + 1);
var obj = {
"value": nowValue,
"description": nowValue + "",
"textLocation": "top",
"textColor": "#CDCACA",
"pointStyle": {
"shape": "circle",
"size": 5,
"fillColor": "#CF0A2C",
"strokeColor": "#CF0A2C"
}
};
dataArray.push(obj);
}
this.lineData = [
{
strokeColor: '#0081ff',
fillColor: '#FF07CDC4',
data: dataArray,
gradient: true,
}
]
},
changeBar() {
for (var i = 0;i < this.barGroup; i++) {
var dataArray = this.barData[i].data;
for (var j = 0;j < 4; j++) {
dataArray[j] = Math.floor(Math.random() * 99 + 1);
}
}
this.barData = this.barData.splice(0, this.barGroup + 1);
},
changes(e) {
console.log("Tab index: " + e.index);
},
}
```
![zh-cn_image_0000001179018876](figures/zh-cn_image_0000001179018876.gif)
# Image-animator开发指导
Image-animator组件为图片帧动画播放器。具体用法请参考[Image-animator](../reference/arkui-js/js-components-basic-image-animator.md)
## 创建Image-animator组件
在pages/index目录下的hml文件中创建一个Image-animator组件,css文件中编写组件样式,js文件中引用图片。
```
<!-- xxx.hml -->
<div class="container">
<image-animator class="animator" images="{{frames}}" duration="3s"/>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.animator {
width: 500px;
height: 500px;
}
```
```
/* index.js */
export default {
data: {
frames: [
{
src: "/common/landscape1.jpg",
},
{
src: "/common/landscape2.jpg",
}
],
},
};
```
![zh-cn_image_0000001218278612](figures/zh-cn_image_0000001218278612.gif)
## 设置Image-animator组件属性
添加iteration(播放次数)、reverse(播放顺序)、fixedsize(图片大小是否固定为组件大小)、duration(播放时长)和fillmode(执行结束后的状态)属性,控制图片的播放效果。
```
<!-- xxx.hml -->
<div class="container">
<image-animator class="animator" fixedsize="false" iteration='2' reverse="false" ref="animator" fillmode="none" images="{{frames}}" duration="5s" />
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
background-color: #F1F3F5;
}
.animator {
width: 500px;
height: 500px;
}
```
```
/* index.js */
export default {
data: {
frames: [
{
src: 'common/landscape1.jpg',
width: '250px',
height: '250px',
left: '150px',
top: '50px',
},
{
src: 'common/landscape2.jpg',
width: '300px',
height: '300px',
left: '150px',
top: '100px',
},
{
src: 'common/landscape1.jpg',
width: '350px',
height: '350px',
left: '150px',
top: '150px',
},
{
src: 'common/landscape2.jpg',
width: '400px',
height: '400px',
left: '150px',
top: '200px',
},
{
src: 'common/landscape3.jpg',
width: '450px',
height: '450px',
left: '150px',
top: '250px',
},
{
src: 'common/landscape4.jpg',
width: '500px',
height: '500px',
left: '150px',
top: '300px',
},
],
},
};
```
![zh-cn_image_0000001218598678](figures/zh-cn_image_0000001218598678.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - 如果在images属性中设置了单独的duration属性,在Image-animator组件中设置的duration属性无效。
>
> - 如果fixedsize属性值设置为true,图片的width 、height 、top 和left属性无效。
>
> - 如果reverse属性值设置为false,表示从第1张图片播放到最后1张图片。 如果reverse属性值设置为true,表示从最后1张图片播放到第1张图片。
## 绑定事件
向Image-animator组件添加start、pause、stop和resume事件。当图片播放器开始播放时触发start事件,当图片播放器被点击时触发pause事件,长按图片播放器触发resume事件,图片播放器停止播放时触发stop事件。
```
<!-- xxx.hml -->
<div class="doc-page">
<image-animator class="img" id="img" images="{{imginfo}}" iteration="1" duration="10s" onstart="popstart" onpause="poppause" onstop="popstop" onresume="popresume" onlongpress="setresume" onclick="setpause">
</image-animator>
</div>
```
```
/* xxx.css */
.doc-page {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
.img {
width: 600px;
height: 600px;
border: 3px solid orange;
}
```
```
/* index.js */
import prompt from '@system.prompt';
export default {
data: {
imginfo: [
{
src: 'common/landscape1.jpg',
},{
src: 'common/landscape2.jpg',
},{
src: 'common/landscape3.jpg',
},{
src: 'common/landscape4.jpg',
}
],
},
onInit() {
},
setpause(e) {
this.$element('img').pause()
},
setresume(e) {
this.$element('img').resume()
},
popstart(e) {
prompt.showToast({
message: '开始'
})
},
poppause(e) {
prompt.showToast({
message: '暂停'
})
},
popstop(e) {
prompt.showToast({
message: '停止'
})
},
popresume(e) {
prompt.showToast({
message: '恢复'
})
}
}
```
![zh-cn_image_0000001263278477](figures/zh-cn_image_0000001263278477.gif)
## 场景示例
在本场景中,开发者可通过开始播放、停止播放等按钮切换图片的播放状态。
Image-animator组件通过调用start、pause、stop和resume方法控制图片的开始、暂停、停止和重新播放,通过getState方法查询图片的播放状态。
```
<!-- xxx.hml -->
<div class="doc-page">
<image-animator class="img" id="img" images="{{imginfo}}" iteration="2" reverse="{{rev}}" duration="10s">
</image-animator>
<div style="width: 700px;height:450px;margin-top: 40px;flex-direction:column;justify-content:space-around;">
<div class="container">
<button type="capsule" value="开始播放" onclick="startimg"></button>
<button type="capsule" value="暂停播放" onclick="pauseimg"></button>
</div>
<div class="container">
<button type="capsule" value="停止播放" onclick="stopimg"></button>
<button type="capsule" value="重新播放" onclick="resumeimg"></button>
</div>
<div class="container">
<button type="capsule" value="获取播放状态" onclick="getimgstate"></button>
<button type="capsule" value="{{revVal}}" onclick="revimg"></button>
</div>
</div>
</div>
```
```
/* xxx.css */
.doc-page {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
.img {
width: 600px;
height: 600px;
border: 3px solid orange;
}
button{
width: 260px
}
.container {
width: 100%;
height: 120px;
align-items: center;
justify-content: space-around;
}
```
```
/* index.js */
import prompt from '@system.prompt';
export default {
data: {
rev:false,
imginfo: [
{
src: 'common/landscape1.jpg',
},{
src: 'common/landscape2.jpg',
},{
src: 'common/landscape3.jpg',
},{
src: 'common/landscape4.jpg',
}
],
revVal: '反向播放'
},
onInit() {
},
startimg(e) {
this.$element('img').start()
},
pauseimg(e) {
this.$element('img').pause()
},
stopimg(e) {
this.$element('img').stop()
},
resumeimg(e) {
this.$element('img').resume()
},
getimgstate(e) {
prompt.showToast({
message: '当前状态:' + this.$element('img').getState()
})
},
revimg(e) {
this.rev = !this.rev
if (this.rev) {
this.revVal = '正向播放'
} else {
this.revVal = '反向播放'
}
}
}
```
![zh-cn_image_0000001218758816](figures/zh-cn_image_0000001218758816.gif)
# Marquee开发指导
Marquee为跑马灯组件,用于展示一段单行滚动的文字。具体用法请参考[marquee](../reference/arkui-js/js-components-basic-marquee.md)
## 创建Marquee组件
在pages/index目录下的hml文件中创建一个Marquee组件。
```
<!-- xxx.hml -->
<div class="container">
<marquee style="width: 100%;height: 80px; color: #ffffff; background-color: #0820ef;padding-left: 200px;">This is a marquee.</marquee>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001227694473](figures/zh-cn_image_0000001227694473.png)
## 设置属性和样式
Marquee通过color和font-weight属性设置跑马灯中文本的颜色、字体粗细和边框样式。
```
<!-- xxx.hml -->
<div class="container">
<marquee class="customMarquee">It's a racing lamp.</marquee>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.customMarquee {
width: 100%;
height: 80px;
padding: 10px;
margin: 20px;
border: 4px solid #6712f1;
border-radius: 20px;
font-size: 40px;
color: #ffffff; font-weight: bolder;
font-family: serif;
background-color: #1567f3;
}
```
![zh-cn_image_0000001227416205](figures/zh-cn_image_0000001227416205.png)
通过scrollamount、loop和direction属性实现跑马灯滚动时移动的最大长度、滚动次数和文字滚动方向。
```
<!-- xxx.hml -->
<div class="tutorial-page">
<div class="mymarquee">
<marquee loop="{{loopval}}" scrollamount="{{scroll}}" direction="{{isleft}}" class="marqueetext" id="testmarquee" onclick="makestart">
It's a racing lamp
</marquee>
</div>
<div style="width: 600px;height: 150px;flex-direction: row;justify-content: space-around;">
<button onclick="setleft" value="left"></button>
<button onclick="setright" value="right"></button>
</div>
</div>
```
```
/* xxx.css */
.tutorial-page {
width: 750px;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
.marqueetext {
color: #ffffff;
font-family: serif;
font-size: 37px;
}
.mymarquee {
margin-top: 20px;
width:100%;
height: 100px;
margin-left: 50px;
margin-right: 50px;
border: 1px solid #6712f1;
background-color: #1567f3;
border-radius: 15px;
align-items: center;
}
button{
width: 200px;
height: 80px;
margin-top: 100px;
}
```
```
// xxx.js
export default {
private: {
loopval: -1, scroll: 10, isleft: "left",
},
onInit(){
},
setleft(e) {
this.isleft = "left"
},
setright(e) {
this.isleft = "right"
},
makestart(e) {
this.$element('testmarquee').start()
}
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 当loop的值小于等于零时,跑马灯marquee将连续滚动。如果loop未指定,则默认为-1。
![zh-cn_image_0000001227701867](figures/zh-cn_image_0000001227701867.gif)
## 场景示例
本场景可以控制跑马灯文字的滚动和暂停。
跑马灯的次数设置为1,在结束的时候触发finish事件使跑马灯的次数加1,字体颜色变为随机颜色,调用start方法使跑马灯再次开始滚动。
```
<!-- xxx.hml -->
<div class="tutorial-page">
<div class="mymarquee">
<marquee style="color: {{color1}}" loop="{{loopval}}" scrollamount="{{scroll}}" direction="{{isleft}}" class="marqueetext"
id="testmarquee" onfinish="setfinish">
It's a racing lamp
</marquee>
</div>
<div style="width: 600px;height: 150px;flex-direction: row;justify-content: space-around;">
<button onclick="makestart" value="start"></button>
<button onclick="makestop" value="stop"></button>
</div>
</div>
```
```
/* xxx.css */
.tutorial-page {
width: 750px;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
}
.marqueetext {
font-size: 37px;
}
.mymarquee {
margin-top: 20px;
width:100%;
height: 100px;
margin-left: 50px;
margin-right: 50px;
border: 1px solid #dc0f27;
border-radius: 15px;
align-items: center;
}
button{
width: 200px;
height: 80px;
margin-top: 100px;
}
```
```
// xxx.js
export default {
private: {
loopval: 1,
scroll: 8,
color1: 'red'
},
onInit(){
},
setfinish(e) {
this.loopval= this.loopval + 1,
this.r = Math.floor(Math.random()*255),
this.g = Math.floor(Math.random()*255),
this.b = Math.floor(Math.random()*255),
this.color1 = 'rgba('+ this.r +','+ this.g +','+ this.b +',0.8)',
this.$element('testmarquee').start(),
this.loopval= this.loopval - 1
},
makestart(e) {
this.$element('testmarquee').start()
},
makestop(e) {
this.$element('testmarquee').stop()
}
}
```
![zh-cn_image_0000001176075554](figures/zh-cn_image_0000001176075554.gif)
# Menu
提供菜单组件,作为临时性弹出窗口,用于展示用户可执行的操作,具体用法请参考[Menu](../reference/arkui-js/js-components-basic-menu.md)
## 创建Menu组件
在pages/index目录下的hml文件中创建一个Menu组件,添加target、type、title属性。
```
<!-- xxx.hml-->
<div class="container">
<text class="title-text" id="textId">show menu</text>
<menu target="textId" type="click" title="title">
<option value="Item 1">Item 1</option>
<option value="Item 2">Item 2</option>
<option value="Item 3">Item 3</option>
</menu>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
.title-text{
font-size: 35px;
}
```
![zh-cn_image_0000001226815299](figures/zh-cn_image_0000001226815299.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - Menu仅支持[option](../reference/arkui-js/js-components-basic-option.md)子组件。
>
> - Menu组件不支持focusable、disabled属性。
## 设置样式
为menu组件设置样式,例如字体颜色、大小、字符间距等。
```
<!-- xxx.hml-->
<div class="container">
<text class="title-text" id="textId">show menu</text>
<menu target="textId" type="click" title="title">
<option value="Item 1">Item 1</option>
<option value="Item 2">Item 2</option>
<option value="Item 3">Item 3</option>
</menu>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
.title-text{
font-size: 35px;
background-color: #5a5aee;
color: white;
width: 70%;
text-align: center;
height: 85px;
border-radius: 12px;
}
menu{
text-color: blue;
font-size: 35px;
letter-spacing: 2px;
}
option{
color: #6a6aef;
font-size: 30px;
}
```
![zh-cn_image_0000001181337170](figures/zh-cn_image_0000001181337170.gif)
## 绑定事件
为menu组件绑定onselected事件(菜单中某个值被点击选中时触发)和oncancel事件(取消操作时触发),点击text组件调用show方法可设置menu组件的坐标。
```
<!-- xxx.hml-->
<div class="container">
<text class="title-text" id="textId" onclick="textClick">show menu</text>
<menu title="title" onselected="select" oncancel="cancel" id="menuId">
<option value="Item 1">Item 1</option>
<option value="Item 2">Item 2</option>
<option value="Item 3">Item 3</option>
</menu>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
}
.title-text{
font-size: 35px;
background-color: #5a5aee;
color: white;
width: 70%;
text-align: center;
height: 85px;
border-radius: 12px;
margin-top: 500px;
margin-left: 15%;
}
menu{
text-color: blue;
font-size: 35px;
letter-spacing: 2px;
}
option{
color: #6a6aef;
font-size: 30px;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
select(e) {
prompt.showToast({
message: e.value
})
},
cancel(){
prompt.showToast({
message: "cancel"
})
},
textClick() {
this.$element("menuId").show({x:175,y:590});
},
}
```
![zh-cn_image_0000001181495744](figures/zh-cn_image_0000001181495744.gif)
## 场景示例
本场景中开发者可点击toggle组件修改文字颜色,选择menu组件修改渐变色块大小。
```
<!-- xxx.hml-->
<div class="container">
<div class="contentToggle">
<toggle class="toggle" for="{{item in togglesList}}" onclick="toggleClick({{$idx}})" checked="{{item.checked}}">{{item.name}}</toggle>
</div>
<text class="size" style="color: {{color}};">width:{{width}},height:{{height}}</text>
<div style="width: {{width}}'px';height: {{height}}px;background:linear-gradient(to right,#FF0000,#0000FF);"></div>
<text id="menuId" class="text">change size</text>
<menu onselected="select" oncancel="cancel" target="menuId">
<option value="{{item.value}}" for="item in optionList">{{item.text}}</option>
</menu>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
width: 100%;
justify-content: center;
align-items: center;
}
.contentToggle{
width: 100%;
justify-content: space-around;
}
.toggle{
padding: 10px;
height:80px;
font-size: 35px;
width: 200px;
height: 85px;
}
.size{
width: 100%;
height: 200px;
text-align: center;
font-size: 40px;
text-align: center;
}
.text{
width: 300px;
height: 80px;
background-color: #615def;
color: white;
font-size: 35px;
text-align: center;
margin-top: 100px;
}
menu{
text-color: blue;
font-size: 35px;
letter-spacing: 2px;
}
option{
color: #6a6aef;
font-size: 30px;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
data:{
fresh: false,
width: 200,
height: 200,
color: '',
optionList:[
{text:'200 x 200',value:2},
{text:'300 x 300',value:3},
{text:'500 x 500',value:5},
],
togglesList:[
{name:"red", checked:false},
{name:"blue", checked:false},
{name: "black", checked:false},
],
},
toggleClick(index){ for(let i=0;i<this.togglesList.length;i++){ if(i == index){ this.color = this.togglesList[index].name this.togglesList[i].checked = true; }else{ this.togglesList[i].checked = false; } } },
select(e) {
this.width = e.value * 100;
this.height = e.value * 100;
}
}
```
![zh-cn_image_0000001226815403](figures/zh-cn_image_0000001226815403.gif)
# OffscreenCanvasRenderingContext2D对象
使用OffscreenCanvas在离屏Canvas画布组件上进行绘制,绘制对象可以是矩形、文本、图片等。具体请参考[OffscreenCanvasRenderingContext2D对象](../reference/arkui-js/js-offscreencanvasrenderingcontext2d.md)
以下示例创建了一个OffscreenCanvas画布,再在画布上创建一个getContext2d对象,并设置filter属性改变图片样式。
```
<!-- xxx.hml -->
<div class="container">
<canvas ref="canvas1"></canvas>
<select @change="change()">
<option value="blur(5px)">blur</option>
<option value="grayscale(50%)">grayscale</option>
<option value="hue-rotate(45deg)">hue-rotate</option>
<option value="invert(100%)">invert</option>
<option value="drop-shadow(8px 8px 10px green)">drop-shadow</option>
<option value="brightness(0.4)">brightness</option>
<option value="opacity(0.25)">opacity</option>
<option value="saturate(30%)">saturate</option>
<option value="sepia(60%)">sepia</option>
<option value="contrast(200%)">contrast</option>
</select>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
canvas{
width: 600px;
height: 500px;
background-color: #fdfdfd;
border: 5px solid red;
}
select{
margin-top: 50px;
width: 250px;
height: 100px;
background-color: white;
}
```
```
// xxx.js
import prompt from '@system.prompt';
export default {
data:{
el: null,
ctx: null,
offscreen: null,
offCanvas: null,
img: null,
},
onShow(){
this.ctx = this.$refs.canvas1.getContext("2d");
this.offscreen = new OffscreenCanvas(600, 500);
this.offCanvas = this.offscreen.getContext("2d");
this.img = new Image();
this.img.src = 'common/images/2.png';
// 图片成功获取触发方法
let _this = this;
this.img.onload = function() {
_this.offCanvas.drawImage(_this.img, 100, 100, 400, 300);
};
this.img.onerror = function() {
prompt.showToast({message:"error",duration:2000})
};
var bitmap = this.offscreen.transferToImageBitmap(); this.ctx.transferFromImageBitmap(bitmap);
},
change(e){
this.offCanvas.filter = e.newValue;this.offCanvas.drawImage(this.img, 100, 100, 400, 300);
var bitmap = this.offscreen.transferToImageBitmap();
this.ctx.transferFromImageBitmap(bitmap);
},
}
```
![zh-cn_image_0000001218599708](figures/zh-cn_image_0000001218599708.gif)
## 判断位置
使用isPointInPath判断坐标点是否在路径的区域内,使用isPointInStroke判断坐标点是否在路径的边缘线上,并在页面上显示返回结果。
```
<!-- xxx.hml -->
<div class="container">
<div class="content">
<text>坐标:{{X}}, {{Y}}</text>
<text>In path:{{textValue}}</text>
<text>In stroke:{{textValue1}}</text>
</div>
<canvas ref="canvas"></canvas>
<button onclick="change">Add(50)</button>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
canvas{
width: 600px;
height: 500px;
background-color: #fdfdfd;
border: 5px solid red;
}
.content{
flex-direction: column;
justify-content: center;
align-items: center;
}
text{
font-size: 30px;
width: 300px;
height: 80px;
text-align: center;
}
button{
width: 180px;
height: 75px;
margin-top: 50px;
}
```
```
// xxx.js
export default {
data: {
textValue: 0,
textValue1: 0,
X:0,
Y:250,
},
onShow(){
let canvas = this.$refs.canvas.getContext('2d');
let offscreen = new OffscreenCanvas(500,500);
let offscreenCanvasCtx = offscreen.getContext("2d");
let offscreenCanvasCtx1 = offscreen.getContext("2d");
offscreenCanvasCtx1.arc(this.X, this.Y, 2, 0, 6.28);
offscreenCanvasCtx.lineWidth=20;
offscreenCanvasCtx.rect(200,150, 200, 200);
offscreenCanvasCtx.stroke();
this.textValue1 = offscreenCanvasCtx.isPointInStroke(this.X, this.Y)?'true':'false';
this.textValue = offscreenCanvasCtx.isPointInPath(this.X, this.Y)?'true':'false';
let bitmap = offscreen.transferToImageBitmap();
canvas.transferFromImageBitmap(bitmap);
},
change(){
if(this.X < 500){
this.X = this.X+50;
}else{
this.X = 0;
}
let canvas = this.$refs.canvas.getContext('2d');
let offscreen = new OffscreenCanvas(500,500);
let offscreenCanvasCtx = offscreen.getContext("2d");
let offscreenCanvasCtx1 = offscreen.getContext("2d");
offscreenCanvasCtx1.arc(this.X, this.Y, 1, 0, 6.28)
offscreenCanvasCtx.lineWidth=20
offscreenCanvasCtx.rect(200,150, 200, 200);
offscreenCanvasCtx.stroke();
this.textValue1 = offscreenCanvasCtx.isPointInStroke(this.X, this.Y)?'true':'false';
this.textValue = offscreenCanvasCtx.isPointInPath(this.X, this.Y)?'true':'false';
let bitmap = offscreen.transferToImageBitmap();
canvas.transferFromImageBitmap(bitmap);
}
}
```
![zh-cn_image_0000001178084014](figures/zh-cn_image_0000001178084014.gif)
# Path2D对象
路径对象,支持通过对象的接口进行路径的描述,并通过Canvas的stroke接口进行绘制。具体请参考[Path2D对象](../reference/arkui-js/js-components-canvas-path2d.md)
## 画线段
创建Path2D,使用多条线段组合图形。
```
<!-- xxx.hml -->
<div class="container">
<canvas ref="canvas"></canvas>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
canvas{
width: 600px;
height: 600px;
background-color: #fdfdfd;
border: 5px solid red;
}
```
```
// xxx.js
import prompt from '@system.prompt';
export default {
onShow(){
let ctx = this.$refs.canvas.getContext('2d',{antialias: true});
let path = ctx.createPath2D();
// 房顶
path.moveTo(10, 300);
path.lineTo(210,100);
path.lineTo(410, 300);
// 屋子
path.moveTo(10, 300);
path.lineTo(410, 300);
path.lineTo(410, 600);
path.lineTo(10, 600);
path.closePath();
// 窗子
path.moveTo(50, 450);
path.bezierCurveTo(70, 350, 130, 350, 150, 450);
path.closePath();
// 门
path.moveTo(250, 450);
path.rect(250, 450, 350, 600);
path.closePath();
// 烟囱
path.moveTo(365, 250);
path.ellipse(310, 215, 30, 130,0, Math.PI * 0.04, Math.PI * 1.1, 1);
// 树
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);
},
}
```
![zh-cn_image_0000001177930616](figures/zh-cn_image_0000001177930616.png)
## 画图形
先使用createPath2D创建出路径对象,只对path1路径进行描边,所以画布上就只会出现path1的路径图形。点击text组件触发addPath方法会把path2路径对象当参数传入path1中,再对path1对象进行描边(stroke)操作后画布出现path1和path2两个图形。点击change文本改变setTransform属性值为setTransform(2, 0.1, 0.1, 2, 0,0),图形变大并向左倾斜。
```
<!-- xxx.hml -->
<div class="container">
<canvas ref="canvas"></canvas>
<div class="content">
<text onclick="addPath">{{ isAdd }}</text>
<text onclick="setTransform">{{textName}}</text>
</div>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
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;
}
text{
width: 150px;
height: 80px;
color: white;
border-radius: 20px;
text-align: center;
background-color: #6060e7;
margin-bottom: 30px;
}
```
```
// 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"
}
},
}
```
![zh-cn_image_0000001177784684](figures/zh-cn_image_0000001177784684.gif)
# Qrcode
生成并显示二维码,具体用法请参考[Qrcode](../reference/arkui-js/js-components-basic-qrcode.md)
## 创建Qrcode组件
在pages/index目录下的hml文件中创建一个Qrcode组件。
```
<!-- xxx.hml-->
<div class="container">
<qrcode value="Hello"></qrcode>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001229155403](figures/zh-cn_image_0000001229155403.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> Qrcode组件在创建的时候value的值为必填项。
## 设置组件类型
通过设置Qrcode的type属性来选择按钮类型,如定义Qrcode为矩形二维码、圆形二维码。
```
<!-- xxx.hml-->
<div class="container">
<select onchange="settype">
<option for="{{bcol_list}}" value="{{$item}}">{{$item}}</option>
</select>
<qrcode value="Hello" type="{{qr_type}}"></qrcode>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
select{
margin-top: 50px;
margin-bottom: 50px;
}
```
```
// index.js
export default {
data: {
qr_type: 'rect',
bcol_list: ['rect','circle']
},
settype(e) {
this.qr_type = e.newValue
},
}
```
![zh-cn_image_0000001218439850](figures/zh-cn_image_0000001218439850.gif)
## 设置样式
通过color和background-color样式为二维码设置显示颜色和背景颜色。
```
<!-- xxx.hml-->
<div class="container">
<qrcode value="Hello" type="rect"></qrcode>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
qrcode{
width: 300px;
height: 300px;
color: blue; background-color: #ffffff;
}
```
![zh-cn_image_0000001183595750](figures/zh-cn_image_0000001183595750.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - width和height不一致时,取二者较小值作为二维码的边长,且最终生成的二维码居中显示。
>
> - width和height只设置一个时,取设置的值作为二维码的边长。都不设置时,使用200px作为默认边长。
>
## 场景示例
在本场景中将二维码与输入框绑定,通过改变输入框的内容改变二维码。
```
<!-- xxx.hml-->
<div class="container">
<input style="margin-bottom: 100px;" onchange="change"></input>
<qrcode value="{{textVal}}"></qrcode>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
qrcode{
width: 400px;
height: 400px;
}
```
```
// index.js
export default{
data: {
textVal: ''
},
change(e){
this.textVal = e.value
}
}
```
![zh-cn_image_0000001183431656](figures/zh-cn_image_0000001183431656.gif)
# Rating开发指导
Rating为评分条组件,表示用户使用感受的衡量标准条。具体用法请参考[Rating](../reference/arkui-js/js-components-basic-rating.md)
## 创建Rating组件
在pages/index目录下的hml文件中创建一个Rating组件。
```
<!-- xxx.hml -->
<div class="container">
<rating></rating>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
rating {
width: 80%;
height: 150px;
}
```
![zh-cn_image_0000001227701031](figures/zh-cn_image_0000001227701031.gif)
## 设置评分星级
Rating组件通过设置numstars和rating属性设置评分条的星级总数和当前评星数。
```
<!-- xxx.hml -->
<div class="container">
<rating numstars="6" rating="5">
</rating>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
rating {
width: 80%;
height: 150px;
}
```
![zh-cn_image_0000001227422709](figures/zh-cn_image_0000001227422709.gif)
## 设置评分样式
Rating组件通过star-background、star-foreground和star-secondary属性设置单个星级未选择、选中和选中的次级背景图片。
```
<!-- xxx.hml -->
<div class="container">
<div style="width: 500px;height: 500px;align-items: center;justify-content: center;flex-direction: column;;">
<rating numstars="5" rating="1" class="myrating" style="width: {{ratewidth}}; height:{{rateheight}};
star-background: {{backstar}}; star-secondary: {{secstar}};star-foreground: {{forestar}};rtl-flip: true;">
</rating>
</div>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
```
```
/* index.js */
export default {
data: {
backstar: 'common/love.png',
secstar: 'common/love.png',
forestar: 'common/love1.png',
ratewidth: '400px',
rateheight: '150px'
},
onInit(){
}
}
```
![zh-cn_image_0000001178685854](figures/zh-cn_image_0000001178685854.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - star-background、star-secondary、star-foreground属性的星级图源必须全部设置,否则默认的星级颜色为灰色,提示图源设置错误。
>
> - star-background、star-secondary、star-foreground属性只支持本地路径图片,图片格式为png和jpg。
## 绑定事件
向Rating组件添加change事件,打印当前评分。
```
<!-- xxx.hml -->
<div class="container">
<rating numstars="5" rating="0" onchange="showrating"></rating>
</div>
```
```
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
rating {
width: 80%;
height: 150px;
}
```
```
import prompt from '@system.prompt';
export default {
showrating(e) {
prompt.showToast({
message: '当前评分' + e.rating
})
}
}
```
![zh-cn_image_0000001181823160](figures/zh-cn_image_0000001181823160.gif)
## 场景示例
开发者可以通过改变开关状态切换星级背景图,通过改变滑动条的值调整星级总数。
```
<!-- xxx.hml -->
<div style="width: 100%;height:100%;flex-direction: column;align-items: center;background-color: #F1F3F5;">
<div style="width: 500px;height: 500px;align-items: center;justify-content: center;flex-direction: column;;">
<rating numstars="{{stars}}" rating="{{rate}}" stepsize="{{step}}" onchange="showrating" class="myrating"
style="width: {{ratewidth}};height:{{rateheight}};star-background: {{backstar}};star-secondary: {{secstar}};
star-foreground: {{forestar}};rtl-flip: true;"></rating>
</div>
<div style="flex-direction: column;width: 80%;align-items: center;">
<div style="width: 100%;height: 100px;align-items: center;justify-content: space-around;">
<text>替换自定义图片</text>
<switch checked="false" showtext="true" onchange="setstar"></switch>
</div>
<div style="width: 100%;height:120px;margin-top: 50px;margin-bottom: 50px;flex-direction: column;align-items: center;
justify-content: space-around;">
<text>numstars {{stars}}</text>
<slider id="sli1" min="-1" max="10" value="5" step="1" onchange="setnumstars"></slider>
</div>
<div style="width: 100%;height:120px;flex-direction: column;align-items: center;justify-content: space-around;">
<text>rating {{rate}}</text>
<slider id="sli2" min="-1" max="10" value="0" step="1" onchange="setrating"></slider>
</div>
</div>
</div>
```
```
/* xxx.css */
.myrating:active {
width: 500px;
height: 100px;
}
switch{
font-size: 40px;
}
```
```
/* index.js */
import prompt from '@system.prompt';
export default {
data: {
backstar: '',
secstar: '',
forestar: '',
stars: 5,
ratewidth: '300px',
rateheight: '60px',
step: 0.5,
rate: 0
},
onInit(){
},
setstar(e) {
if (e.checked == true) {
this.backstar = 'common/love.png'
this.secstar = 'common/love.png'
this.forestar = 'common/love1.png'
} else {
this.backstar = ''
this.secstar = ''
this.forestar = ''
}
},
setnumstars(e) {
this.stars = e.progress
this.ratewidth = 60 * parseInt(this.stars) + 'px'
},
setstep(e) {
this.step = e.progress
},
setrating(e){
this.rate = e.progress
},
showrating(e) {
prompt.showToast({
message: '当前评分' + e.rating
})
}
}
```
![zh-cn_image_0000001224086459](figures/zh-cn_image_0000001224086459.gif)
# Search
提供搜索框组件,用于提供用户搜索内容的输入区域,具体用法请参考[Search](../reference/arkui-js/js-components-basic-search.md)
## 创建Search组件
在pages/index目录下的hml文件中创建一个Search组件。
```
<!-- xxx.hml-->
<div class="container">
<search></search>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001218760480](figures/zh-cn_image_0000001218760480.png)
## 设置属性
通过设置hint、icon和searchbutton属性设置搜索框的提示文字、图标和末尾搜索按钮的内容。
```
<!-- xxx.hml-->
<div class="container">
<search hint="Please enter the search content" searchbutton="search" icon="/common/search1.png"></search>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001183438596](figures/zh-cn_image_0000001183438596.png)
## 添加样式
通过color、placeholder和caret-color样式来设置搜索框的文本颜色、提示文本颜色和光标颜色。
```
<!-- xxx.hml-->
<div class="container">
<search hint="Please enter the search content" searchbutton="search" ></search>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
search{
color: black; placeholder-color: black; caret-color: red;
}
```
![zh-cn_image_0000001228920921](figures/zh-cn_image_0000001228920921.gif)
## 绑定事件
向Search组件添加change、search、submit、share和translate事件,对输入信息进行操作。
```
<!-- xxx.hml-->
<div class="container">
<text style="margin-left: -7px;">
<span>Enter text and then touch and hold what you've entered</span>
</text>
<search hint="Please enter the search content" searchbutton="search" onsearch="search" onchange="change" ontranslate="translate" onshare="share"
onsubmit="submit">
</search>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
text{
width: 100%;
font-size: 25px;
text-align: center;
margin-bottom: 100px;
}
```
```
// index.js
import prompt from '@system.prompt'
export default {
search(e){
prompt.showToast({
message: e.value,
duration: 3000,
});
},
translate(e){
prompt.showToast({
message: e.value,
duration: 3000,
});
},
share(e){
prompt.showToast({
message: e.value,
duration: 3000,
});
},
change(e){
prompt.showToast({
message: e.value,
duration: 3000,
});
},
submit(e){
prompt.showToast({
message: 'submit',
duration: 3000,
});
}
}
```
![zh-cn_image_0000001182187434](figures/zh-cn_image_0000001182187434.gif)
## 场景示例
在本场景中通过下拉菜单选择Search、Textarea和Input组件来实现搜索和输入效果。
```
<!-- xxx.hml-->
<div style="flex-direction: column;align-items: center;justify-content: center; width: 100%;">
<select class="slt1" id="slt1" onchange="setfield">
<option value="search">Search</option>
<option value="textarea">Textarea</option>
<option value="input">Input</option>
</select>
<div if="{{showsearch}}" style="flex-direction: column;align-items: center;margin-top: 50px;height: 400px;justify-content: space-around;">
<search class="field" id="search1" hint="search1" onsubmit="submit" onchange="change" ></search>
<search class="field" id="search2" icon="common/search1.png" hint="search2" show="{{showsec}}" onsubmit="submit" onchange="change" ></search>
</div>
<div if="{{showtextarea}}" style="flex-direction: column;align-items: center;margin-top: 50px;height: 400px;justify-content: space-around;">
<textarea class="field" id="textarea1" extend="true" placeholder="textarea1" onchange="change" ></textarea>
<textarea class="field" id="textarea2" extend="true" placeholder="textarea2" onchange="change" show="{{showsec}}"></textarea>
</div>
<div if="{{showinput}}" style="flex-direction: column;align-items: center;margin-top: 50px;height: 400px;justify-content: space-around;">
<input type="text" class="field" id="input1" placeholder="input1" onchange="change" ></input>
<input type="text" class="field" id="input2" placeholder="input2" onchange="change" show="{{showsec}}"></input>
</div>
</div>
```
```
/* xxx.css */
.field {
width: 80%;
color: mediumaquamarine;
font-weight: 600;
placeholder-color: orangered;
}
.slt1{
font-size: 50px;
position: absolute;
left: 50px;
top: 50px;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
data: {
showsearch: true,
showtextarea: false,
showinput: false,
showsec: true,
},
setfield(e) {
this.field = e.newValue
if (e.newValue == 'search') {
this.showsearch = true
this.showtextarea = false
this.showinput = false
} else if (e.newValue == 'textarea') {
this.showsearch = false
this.showtextarea = true
this.showinput = false
} else {
this.showsearch = false
this.showtextarea = false
this.showinput = true
}
},
submit(e) {
prompt.showToast({
message: '搜索!',
duration: 2000
})
},
change(e) {
prompt.showToast({
message: '内容:' + e.text,
duration: 2000
})
}
}
```
![zh-cn_image_0000001183283966](figures/zh-cn_image_0000001183283966.gif)
# Slider开发指导
Slider为滑动条组件,用来快速调节音量、亮度等。具体用法请参考[Slider](../reference/arkui-js/js-components-basic-slider.md)
## 创建Slider组件
在pages/index目录下的hml文件中创建一个Slider组件。
```
<!-- xxx.hml -->
<div class="container">
<slider></slider>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
background-color: #F1F3F5;
flex-direction: column;
justify-content: center;
align-items: center;
}
```
![zh-cn_image_0000001176072876](figures/zh-cn_image_0000001176072876.gif)
## 设置样式和属性
Slider组件通过color、selected-color、block-color样式分别为滑动条设置背景颜色、已选择颜色和滑块颜色。
```
<!-- xxx.hml -->
<div class="container">
<slider class= "sli"></slider>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.sli{
color: #fcfcfc;
scrollbar-color: aqua;
background-color: #b7e3f3;
}
```
![zh-cn_image_0000001227661529](figures/zh-cn_image_0000001227661529.gif)
通过添加mix、max、value、step、mode属性分别为滑动条设置最小值、最大值、初始值、滑动步长和滑动条样式。
```
<!-- xxx.hml -->
<div class="container">
<slider min="0" max="100" value="1" step="2" mode="inset" showtips="true"></slider>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001179438692](figures/zh-cn_image_0000001179438692.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> mode属性为滑动条样式,仅在手机和平板上生效,可选值为:
>
> - outset:滑块在滑杆上;
>
> - inset:滑块在滑杆内。
## 绑定事件
向Rating组件添加change事件,添加时需要传入ChangeEvent参数。
```
<!-- xxx.hml -->
<div class="container">
<text>slider start value is {{startValue}}</text>
<text>slider current value is {{currentValue}}</text>
<text>slider end value is {{endValue}}</text>
<slider min="0" max="100" value="{{value}}" onchange="setvalue"></slider>
</div>
```
```
/* xxx.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
```
```
// xxx.js
export default {
data: {
value: 0,
startValue: 0,
currentValue: 0,
endValue: 0,
},
setvalue(e) {
if (e.mode == "start") {
this.value = e.value;
this.startValue = e.value;
} else if (e.mode == "move") {
this.value = e.value;
this.currentValue = e.value;
} else if (e.mode == "end") {
this.value = e.value;
this.endValue = e.value;
}
}
}
```
![zh-cn_image_0000001176551446](figures/zh-cn_image_0000001176551446.gif)
## 场景示例
开发者可以通过调整滑动条的值来改变图片大小,并且动态打印当前图片的宽和高。
```
<!-- xxx.hml -->
<div class="container">
<image src="common/landscape3.jpg" style=" width: {{WidthVal}}px;height:{{HeightVal}}px;margin-top: -150px;"></image>
<div class="txt">
<slider min="0" max="100" value="{{value}}" onchange="setvalue"></slider>
<text>The width of this picture is {{WidthVal}}</text>
<text>The height of this picture is {{HeightVal}}</text>
</div>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
.txt{
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
top: 65%;
}
text{
margin-top: 30px;
}
```
```
// xxx.js
export default{
data: {
value: 0,
WidthVal: 200,
HeightVal: 200
},
setvalue(e) {
this.WidthVal = 200 + e.value;
this.HeightVal = 200 + e.value
}
}
```
![zh-cn_image_0000001263038799](figures/zh-cn_image_0000001263038799.gif)
# 绘制图形
Svg组件可以用来绘制常见图形和线段,如矩形(&lt;rect&gt;)、圆形(&lt;circle&gt;)、线条(&lt;line&gt;)等,具体支持图形样式还请参考svg组件。
在本场景中,绘制各种图形拼接组成一个小房子。
```
<!-- xxx.hml -->
<div class="container">
<svg width="1000" height="1000">
<polygon points="100,400 300,200 500,400" fill="red"></polygon> //屋顶
<polygon points="375,275 375,225 425,225 425,325" fill="orange"></polygon> //烟囱
<rect width="300" height="300" x="150" y="400" fill="orange"> //房子
</rect>
<rect width="100" height="100" x="180" y="450" fill="white"> //窗户
</rect>
<line x1="180" x2="280" y1="500" y2="500" stroke-width="4" fill="white" stroke="black"></line> //窗框
<line x1="230" x2="230" y1="450" y2="550" stroke-width="4" fill="white" stroke="black"></line> //窗框
<polygon points="325,700 325,550 400,550 400,700" fill="red"></polygon> //门
<circle cx="380" cy="625" r="20" fill="black"></circle> //门把手
</svg>
</div>
```
```
/* xxx.css */
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001226911459](figures/zh-cn_image_0000001226911459.png)
# 基础知识
Svg组件主要作为svg画布的根节点使用,也可以在svg中嵌套使用。具体用法请参考[Svg](../reference/arkui-js/js-components-svg.md)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - 从API version 7开始支持。
>
> - svg父组件或者svg组件需要定义宽高值,否则不进行绘制。
## 创建Svg组件
在pages/index目录下的hml文件中创建一个Svg组件。
```
<!-- xxx.hml -->
<div class="container">
<svg width="400" height="400"> </svg>
</div>
```
```
/* xxx.css */
.container{
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
svg{
background-color: blue;
}
```
![zh-cn_image_0000001218280036](figures/zh-cn_image_0000001218280036.png)
## 设置属性
通过设置width、height、x、y和viewBox属性为Svg设置宽度、高度、x轴坐标、y轴坐标和Svg视口。
```
<!-- xxx.hml -->
<div class="container">
<svg width="400" height="400" viewBox="0 0 100 100"> <svg class="rect" width="100" height="100" x="20" y="10"> </svg> </svg>
</div>
```
```
/* xxx.css */
.container{
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #F1F3F5;
}
svg{
background-color: yellow;
}
.rect{
background-color: red;
}
```
![zh-cn_image_0000001218599996](figures/zh-cn_image_0000001218599996.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - x和y设置的的是当前Svg的x轴和y轴坐标,如果当前Svg为根节点,x轴和y轴属性无效。
>
> - viewBox的宽高和svg的宽高不一致,会以中心对齐进行缩放。
# 绘制路径
Svg组件绘制路径时,通过Path中的M(起点)、H(水平线)、a(绘制弧形到指定位置)路径控制指令,并填充颜色实现 饼状图效果。
```
<!-- xxx.hml -->
<div class="container">
<svg fill="#00FF00" x="100" y="400">
<path d="M300,200 h-150 a150 150 0 1 0 150 -150 z" fill="red" stroke="blue" stroke-width="5" > </path> <path d="M275,175 v-150 a150 150 0 0 0 -150 150 z" fill="yellow" stroke="blue" stroke-width="5"> </path>
</svg>
</div>
```
```
/* xxx.css */
.container {
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
height: 1200px;
width: 600px;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001181511962](figures/zh-cn_image_0000001181511962.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - M/m = moveto 参数x和y表示需要移动到点的x轴和y轴的坐标。在使用M命令移动画笔后,只会移动画笔,但不会在两点之间画线。所以M命令经常出现在路径的开始处,用来指明从何处开始画。
>
> - L/l = lineto 参数x和y表示一个点的x轴和y轴坐标,L命令将会在当前位置和新位置(L前面画笔所在的点)之间画一条线段。
>
> - H/h = horizontal lineto 绘制平行线。
>
> - V/v = vertical lineto 绘制垂直线。
>
> - C/c = curveto 三次贝塞尔曲线 设置三组坐标参数: x1 y1, x2 y2, x y。
>
> - S/s = smooth curveto 三次贝塞尔曲线命令 设置两组坐标参数: x2 y2, x y。
>
> - Q/q = quadratic Belzier curve 二次贝塞尔曲线 设置两组坐标参数: x1 y1, x y。
>
> - T/t = smooth quadratic Belzier curveto 二次贝塞尔曲线命令 设置参数: x y。
>
> - A/a = elliptical Arc 弧形命令 设置参数: rx ry x-axis-rotation(旋转角度)large-arc-flag(角度大小) sweep-flag(弧线方向) x y。large-arc-flag决定弧线是大于还是小于180度,0表示小角度弧,1表示大角度弧。sweep-flag表示弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧。
>
> - Z/z = closepath 从当前点画一条直线到路径的起点。
# 绘制文本
Svg组件还可以绘制文本。
## 文本
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - 文本的展示内容需要写在元素标签text内,可嵌套tspan子元素标签分段。
>
> - 只支持被父元素标签svg嵌套。
>
> - 只支持默认字体sans-serif。
通过设置x(x轴坐标)、y(y轴坐标)、dx(文本x轴偏移)、dy(文本y轴偏移)、fill(字体填充颜色)、stroke(文本边框颜色)、stroke-width(文本边框宽度)等属性实现文本的不同展示样式。
```
<!-- xxx.hml -->
<div class="container">
<svg>
<text x="200" y="300" font-size="80px" fill="blue" >Hello World</text> <text x="200" y="300" dx="20" dy="80" font-size="80px" fill="blue" fill-opacity="0.5" stroke="red" stroke-width="2">Hello World</text>
<text x="20" y="550" fill="#D2691E">
<tspan dx="40" fill="red" font-size="80" fill-opacity="0.4">Hello World </tspan>
</text>
</svg>
</div>
```
![zh-cn_image_0000001227151887](figures/zh-cn_image_0000001227151887.png)
## 沿路径绘制文本
textpath文本内容沿着属性path中的路径绘制文本。
```
<!-- xxx.hml -->
<div class="container">
<svg fill="#00FF00" x="100" y="400">
<path d="M40,360 Q360,360 360,180 Q360,20 200,20 Q40,40 40,160 Q40,280 180,180 Q180,180 200,100" stroke="red" fill="none"></path>
<text>
<textpath fill="blue" startOffset="20%" path="M40,360 Q360,360 360,180 Q360,20 200,20 Q40,40 40,160 Q40,280 180,180 Q180,180 200,100" font-size="30px">
This is textpath test.
</textpath>
</text>
</svg>
</div>
```
![zh-cn_image_0000001181354262](figures/zh-cn_image_0000001181354262.png)
# Svg
- **[基础知识](ui-js-components-svg-overview.md)**
- **[绘制图形](ui-js-components-svg-graphics.md)**
- **[绘制路径](ui-js-components-svg-path.md)**
- **[绘制文本](ui-js-components-svg-text.md)**
\ No newline at end of file
# Swiper开发指导
Swiper为滑动容器,提供切换显示子组件的能力。具体用法请参考[Swiper](../reference/arkui-js/js-components-container-swiper.md)
## 创建Swiper组件
在pages/index目录下的hml文件中创建一个Swiper组件。
```
<!-- xxx.hml-->
<div class="container">
<swiper>
<div class="item" style="background-color: #bf45ea;">
<text>item1</text>
</div>
<div class="item" style="background-color: #088684;">
<text>item2</text>
</div>
<div class="item" style="background-color: #7786ee;">
<text>item3</text>
</div>
</swiper>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
.item{
width: 100%;
height: 500px;
}
text{
width: 100%;
text-align: center;
font-size: 50px;
color: white;
}
```
![zh-cn_image_0000001181495038](figures/zh-cn_image_0000001181495038.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> Swiper组件支持除&lt;list&gt;之外的子组件。
## 添加属性
Swiper组件当不开启循环播放(loop="false")时添加自动播放属性(autoplay),设置自动播放时播放时间间隔(interval),页面会自动切换并停留在最后一个子组件页面。添加digital属性启用数字导航点,设置切换时为渐隐滑动效果(scrolleffect="fade"))。
```
<!-- xxx.hml-->
<div class="container">
<swiper index="1" autoplay="true" interval="2000" indicator="true" digital="true" duration="500"
scrolleffect="fade" loop="false">
<div class="item" style="background-color: #bf45ea;">
<text>item1</text>
</div>
<div class="item" style="background-color: #088684;">
<text>item2</text>
</div>
<div class="item" style="background-color: #7786ee;">
<text>item3</text>
</div>
<div class="item" style="background-color: #c88cee;">
<text>item4</text>
</div>
</swiper>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
.item{
width: 100%;
height: 500px;
}
text{
width: 100%;
text-align: center;
font-size: 50px;
color: white;
}
```
![zh-cn_image_0000001181655292](figures/zh-cn_image_0000001181655292.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - 设置indicator(是否启用导航点指示器)属性为true时digital(是否启用数字导航点)属性才会生效。
>
> - Swiper子组件的个数大于等于2时设置的loop属性才会生效。
>
> - scrolleffect属性仅在loop属性值为false时生效。
## 设置样式
设置Swiper组件的宽高,导航点指示器的直径大小(indicator-size)、颜色(indicator-color)、相对位置(ndicator-top)及选中时的颜色(indicator-selected-color)。
```
<!-- xxx.hml-->
<div class="container">
<swiper index="1" autoplay="true" interval="2000" duration="500" >
<div class="item" style="background: linear-gradient(to right,#806dd9,#5d44ea,#2eb9d5)">
<text>item1</text>
</div>
<div class="item" style="background: linear-gradient( to right,#2eb9d5,#0e7db4,#2673d9)">
<text>item2</text>
</div>
<div class="item" style="background: linear-gradient( to right,#2673d9,#0c89af,#806dd9)">
<text>item3</text>
</div>
</swiper>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
swiper{
width: 500px;
height: 500px;
border-radius: 250px;indicator-color: white; indicator-selected-color: blue; indicator-size: 40px; indicator-top: 100px;
overflow: hidden ;
}
.item{
width: 100%;
height: 500px;
}
text{
width: 100%;
text-align: center;
margin-top: 150px;
font-size: 50px;
color: white;
}
```
![zh-cn_image_0000001226896657](figures/zh-cn_image_0000001226896657.gif)
## 绑定事件
创建两个text组件添加点击事件,当点击后就调用showPrevious(显示上一个子组件)或showNext(显示下一个子组件)方法。添加select组件下拉选择时触发change事件后调用swiperTo方法跳转到指定轮播页面。Swiper组件绑定change(当前显示的组件索引变化时触发)和finish(切换动画结束时触发)事件。
```
<!-- xxx.hml-->
<div class="container">
<swiper interval="2000" onchange="change" loop="false" onanimationfinish="finish" id="swiper">
<div class="item" style="background-color: #bf45ea">
<text>item1</text>
</div>
<div class="item" style="background-color: #088684;">
<text>item2</text>
</div>
<div class="item" style="background-color: #7786ee;">
<text>item3</text>
</div>
<div class="item" style="background-color: #c88cee;">
<text>item4</text>
</div>
</swiper>
<div class="content">
<button class="pnbtn" onclick="previous">Previous</button>
<select onchange="selectChange">
<option value="0">swipeTo 1</option>
<option value="1">swipeTo 2</option>
<option value="2">swipeTo 3</option>
<option value="3">swipeTo 4</option>
</select>
<button class="pnbtn" onclick="next">Next</button>
</div>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
.item{
width: 100%;
height: 500px;
}
text{
width: 100%;
text-align: center;
font-size: 50px;
color: white;
}
select{
background-color: white;
width: 250px;
height: 80px;
}
.content{
margin-top: 100px;
justify-content: space-around;
}
.pnbtn{
width: 200px;
height: 80px;
font-size: 30px;
}
```
```
import prompt from '@system.prompt';
export default{
change(e){
prompt.showToast({duration:2000,message:"current index:"+e.index});
},
finish(){
prompt.showToast({duration:2000,message:"切换动作结束"});
},
selectChange(e){
this.$element('swiper').swipeTo({index: Number(e.newValue)});
},
previous(){
this.$element('swiper').showPrevious();
},
next(){
this.$element('swiper').showNext();
}
}
```
![zh-cn_image_0000001227016767](figures/zh-cn_image_0000001227016767.gif)
## 场景示例
本场景中使用Swiper创建一个轮播图,在轮播图底部制作一个缩略图,点击缩略图后调用swipeTo方法切换到对应的轮播图。
```
<!-- xxx.hml-->
<div class="container">
<swiper duration="500" indicator="false" id="swiper" onchange="change">
<div class="item" for="item in list">
<image src="{{item.src}}"></image>
</div>
</swiper>
<div class="content">
<div class="content_item {{index == $idx?'actived':''}}" for="item in list" onclick="imageTo({{$idx}})">
<image src="{{item.src}}"></image>
</div>
</div>
</div>
```
```
/* xxx.css */
.container{
flex-direction: column;
background-color: #F1F3F5;
align-items: center;
justify-content: center;
width: 100%;
}
swiper{
width: 100%;
height: 500px;
}
.item{
width: 100%;
height: 500px;
}
.content{
margin-top: -120px;
width: 70%;
display: flex;
justify-content: space-around;
height: 100px;
}
.content_item{
padding: 5px;
transform: scale(0.5);
}
.actived{
transform: scale(1);border: 1px solid #b20937ea;
}
```
```
// index.js
import prompt from '@system.prompt';
export default {
data:{
index: 0,
list:[
{src: 'common/images/1.png'},
{src: 'common/images/2.png'},
{src: 'common/images/3.png'},
{src: 'common/images/4.png'},]
},
imageTo(index){
this.index = index;
this.$element('swiper').swipeTo({index: index});
},
change(e){
this.index = e.index;
}
}
```
![zh-cn_image_0000001263359599](figures/zh-cn_image_0000001263359599.gif)
# Switch开发指导
Switch为开关选择器,切换开启或关闭状态。具体用法请参考[Switch](../reference/arkui-js/js-components-basic-switch.md)
## 创建Switch组件
在pages/index目录下的hml文件中创建一个Switch组件。
```
<div class="container">
<switch></switch>
</div>
```
```
/* xxx.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
```
![zh-cn_image_0000001229784239](figures/zh-cn_image_0000001229784239.png)
## 添加属性和方法
witch组件通过textoff和showtext属性设置文本选中和未选中时的状态。设置checked属性值为true(组件为打开状态)。添加change事件,当组件状态改变时触发,触发后执行switchChange函数获取组件当前状态(关闭/打开)。
```
<!-- xxx.hml -->
<div class="container">
<switch showtext="true" texton="open" textoff="close" checked="true" @change="switchChange"></switch>
</div>
```
```
/* xxx.css */
.container {
display: flex;
justify-content: center;
align-items: center;
background-color: #F1F3F5;
}
switch{
// 选中时的字体颜色
texton-color: #002aff;
// 未选中时的字体颜色
textoff-color: silver;
text-padding: 20px;
font-size: 50px;
}
```
```
// xxx.js
import prompt from '@system.prompt';
export default {
switchChange(e){
if(e.checked){
prompt.showToast({
message: "open"
});
}else{
prompt.showToast({
message: "close"
});
}
}
}
```
![zh-cn_image_0000001221030133](figures/zh-cn_image_0000001221030133.gif)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 当showtext属性值设置为true时,texton和textoff设置的文本才会生效。
## 场景示例
在下面示例中设置开关为打开状态(使用默认收货地址),关闭开关后页面显示选择地址按钮,点击按钮即可改变收货地址。
实现方法:创建Switch开关,设置checked属性为true,通过数据绑定改变收货地址。设置display属性(默认为none),当关闭开关改变display属性值为flex后显示地址模块,点击按钮改变颜色。
```
<!-- xxx.hml -->
<div class="container">
<div class="change">
<text>Choose default address:</text>
<switch showtext="true" texton="on" textoff="off" checked="true" @change="switchChange"></switch>
</div>
<div class="content">
<text class="address"><span>Shipping address:</span><span class="textSpan">{{address}}</span></text>
</div>
<div class="myAddress" style="display: {{addressDisplay}};">
<text style="font-size: 30px;margin-bottom: 50px;">Choose an address:</text>
<text class="addressText" style="background-color: {{item == address?'#0fabe7':''}};color: {{item == address?'white':'black'}};"
for="item in addressList"@click="changeAddress({{$idx}}})">{{item}}</text>
</div>
</div>
```
```
/* xxx.css */
.container {
background-color: #F1F3F5;
flex-direction: column;
padding: 50px;
}
.change{
margin-top: 20%;
width: 100%;
justify-content: center;
}
switch{
texton-color: #002aff;
textoff-color: silver;
text-padding: 20px;
}
.content{
width: 70%;
text-align: center;
flex-direction: column;
border: 1px solid #002aff;
margin-left: 15%;
text-align: center;
}
.address{
width: 100%;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 28px;
margin-bottom: 50px;
}
.textSpan{
color: #0aa9f1;
}
.myAddress{
flex-direction: column;
margin-top: 50px;
}
.addressText{
margin-left: 35%;
width: 30%;
height: 75px;
text-align: center;
color: white;
margin-bottom: 30px;
border-radius: 10px;
border: 1px solid #0fabe7;
}
```
```
// xxx.js
import prompt from '@system.prompt';
export default {
data:{
address: '',
addressDisplay: 'none',
addressList: ['family','company','commissary'],
},
onInit(){
// 初始化默认地址为地址列表中的第一个
this.address = this.addressList[0];
},
switchChange(e){
if(e.checked){
this.addressDisplay = "none";
}else{
this.addressDisplay = "flex";
}
},
changeAddress(i){
this.address= this.addressList[i];
}
}
```
![zh-cn_image_0000001220830223](figures/zh-cn_image_0000001220830223.gif)
此差异已折叠。
# 容器组件
- **[List开发指导](ui-js-components-list.md)**
- **[Dialog开发指导](ui-js-components-dialog.md)**
- **[Form开发指导](ui-js-components-form.md)**
- **[Stepper开发指导](ui-js-components-stepper.md)**
- **[Tabs开发指导](ui-js-component-tabs.md)**
- **[Swiper开发指导](ui-js-components-swiper.md)**
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册