• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Border Image
2
3You can draw an image around a component.
4
5>  **NOTE**
6>
7>  The APIs of this module are supported since API version 9. Updates will be marked with a superscript to indicate their earliest API version.
8
9## borderImage
10
11borderImage(value: BorderImageOption)
12
13Sets the border image of the component.
14
15**Widget capability**: Since API version 9, this feature is supported in ArkTS widgets.
16
17**Atomic service API**: This API can be used in atomic services since API version 11.
18
19**System capability**: SystemCapability.ArkUI.ArkUI.Full
20
21**Parameters**
22
23| Name     | Type                                           | Mandatory| Description                            |
24| ----------- | ----------------------------------------------- | ---- | -------------------------------- |
25| value | [BorderImageOption](#borderimageoption) | Yes  | Border image or border gradient.|
26
27## BorderImageOption
28
29**Widget capability**: Since API version 9, this feature is supported in ArkTS widgets.
30
31| Name  | Type                                                        | Mandatory| Description                                                        |
32| ------ | ------------------------------------------------------------ | ---- |  ------------------------------------------------------------ |
33| source | string \| [Resource](ts-types.md#resource) \| [linearGradient](ts-universal-attributes-gradient-color.md) | No| Source or gradient color of the border image. When the type is string, this parameter sets the border image source. For details about how to reference image resources, see [Loading Image Resources ](../../../ui/arkts-graphics-display.md#loading-image-resources).<br>**NOTE**<br>The border image source applies only to container components, such as [Row](ts-container-row.md), [Column](ts-container-column.md), and [Flex](ts-container-flex.md).<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
34| slice  | [Length](ts-types.md#length) \| [EdgeWidths](ts-types.md#edgewidths9)  \| [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>| No| Slice width of the upper left corner, upper right corner, lower left corner, and lower right corner of the border image.<br>Default value: **0**<br>**NOTE**<br>If this parameter is set to a negative value, the default value is used.<br>When this parameter is set to a value of the [Length](ts-types.md#length) type, the value applies to the four corners in a unified manner.<br>When this parameter is set to a value of the [EdgeWidths](ts-types.md#edgewidths9) type:<br>- **Top**: slice height of the upper left or upper right corner of the image.<br>- **Bottom**: slice height of the lower left or lower right corner of the image.<br>- **Left**: slice width of the upper left or lower left corner of the image.<br>- **Right**: slice width of the upper right or lower right corner of the image.<br>When the parameter type is [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>:<br>- **Top**: slice height of the upper left or upper right corner of the image.<br>- **Bottom**: slice height of the lower left or lower right corner of the image.<br>- **Start**: slice width of the upper left or lower left corner of the image for left-to-right scripts;<br>slice width of the upper right or lower right corner of the image for right-to-left scripts.<br>- **End**: slice width of the upper right or lower right corner of the image for left-to-right scripts; slice width of the upper left or lower left corner of the image for right-to-left scripts.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
35| width  | [Length](ts-types.md#length) \| [EdgeWidths](ts-types.md#edgewidths9) \| [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup> | No| Width of the border image.<br>Default value: **0**<br>**NOTE**<br>If this parameter is set to a negative value, the default value is used.<br>When this parameter is set to a value of the [Length](ts-types.md#length) type, the value applies to the four corners in a unified manner.<br>When this parameter is set to a value of the [EdgeWidths](ts-types.md#edgewidths9) type:<br>- **Top**: width of the top edge of the border image.<br>- **Bottom**: width of the bottom edge of the border image.<br>- **Left**: width of the left edge of the border image.<br>- **Right**: width of the right edge of the border image.<br>When the parameter type is [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>:<br>- **Top**: width of the top edge of the border image.<br>- **Bottom**: width of the bottom edge of the border image.<br>- **Start**: width of the left edge of the border image for left-to-right scripts;<br>width of the right edge of the border image for right-to-left scripts.<br>- **End**: width of the right edge of the border image for left-to-right scripts;<br>width of the left edge of the border image for right-to-left scripts.<br>If this parameter is set to a negative value, the value **1** is used.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
36| outset | [Length](ts-types.md#length) \| [EdgeWidths](ts-types.md#edgewidths9) \| [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup> | No| Amount by which the border image is extended beyond the border box.<br>Default value: **0**<br>**NOTE**<br>If this parameter is set to a negative value, the default value is used.<br>When this parameter is set to a value of the [Length](ts-types.md#length) type, the value applies to the four corners in a unified manner.<br>When this parameter is set to a value of the [EdgeWidths](ts-types.md#edgewidths9) type:<br>- **Top**: amount by which the top edge of the border image is extended beyond the border box.<br>- **Bottom**: amount by which the bottom edge of the border image is extended beyond the border box.<br>- **Left**: amount by which the left edge of the border image is extended beyond the border box.<br>- **Right**: amount by which the right edge of the border image is extended beyond the border box.<br>When the parameter type is [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>:<br>- **Top**: amount by which the top edge of the border image is extended beyond the border box.<br>- **Bottom**: amount by which the bottom edge of the border image is extended beyond the border box.<br>- **Start**: amount by which the left edge of the border image is extended beyond the border box for left-to-right scripts;<br>amount by which the right edge of the border image is extended beyond the border box for right-to-left scripts.<br>- **End**: amount by which the right edge of the border image is extended beyond the border box for left-to-right scripts;<br>amount by which the left edge of the border image is extended beyond the border box for right-to-left scripts.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
37| repeat | [RepeatMode](#repeatmode)                            | No| Repeat mode of the source image's slices on the border.<br>Default value: **RepeatMode.Stretch**<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
38| fill   | boolean                                                      | No| Whether to fill the center of the border image.<br>**true**: Fill the center of the border image.<br>**false**: Do not fill the center of the border image.<br>Default value: **false**<br>**Atomic service API**: This API can be used in atomic services since API version 11.                    |
39
40## RepeatMode
41
42**Widget capability**: Since API version 9, this feature is supported in ArkTS widgets.
43
44**Atomic service API**: This API can be used in atomic services since API version 11.
45
46| Name     | Description                                 |
47| ------- | ----------------------------------- |
48| Repeat  | The source image's slices are tiled. Tiles beyond the border box will be clipped.         |
49| Stretch | The source image's slices are stretched to fill the border box.               |
50| Round   | The source image's slices are tiled to fill the border box. Tiles may be compressed when needed.|
51| Space   | The source image's slices are tiled to fill the border box. Extra space will be distributed in between tiles.  |
52
53## Example
54
55### Example 1: Setting a Gradient Border
56
57This example demonstrates how to set a gradient border for a component using the **borderImage** API.
58
59```ts
60// xxx.ets
61@Entry
62@Component
63struct Index {
64  build() {
65    Row() {
66      Column() {
67        Text('This is gradient color.').textAlign(TextAlign.Center).height(50).width(200)
68          .borderImage({
69            source: {
70              angle: 90,
71              direction: GradientDirection.Left,
72              colors: [[0xAEE1E1, 0.0], [0xD3E0DC, 0.3], [0xFCD1D1, 1.0]]
73            },
74            slice: { top: 10, bottom: 10, left: 10, right: 10 },
75            width: { top: "10px", bottom: "10px", left: "10px", right: "10px" },
76            repeat: RepeatMode.Stretch,
77            fill: false
78          })
79      }
80      .width('100%')
81    }
82    .height('100%')
83  }
84}
85```
86
87![en-us_image_borderImageGradient](figures/borderImageGradient.png)
88
89### Example 2: Dynamically Adjusting Property Values
90
91This example demonstrates how to dynamically adjust the properties of the **borderImage** API using the [slider](../../apis-arkui/arkui-js/js-components-basic-slider.md) component.
92
93```ts
94// xxx.ets
95@Entry
96@Component
97struct BorderImage {
98  @State WidthValue: number = 0
99  @State SliceValue: number = 0
100  @State OutSetValue: number = 0
101  @State RepeatValue: RepeatMode[] = [RepeatMode.Repeat, RepeatMode.Stretch, RepeatMode.Round, RepeatMode.Space]
102  @State SelectIndex: number = 0
103  @State SelectText: string = 'Repeat'
104  @State FillValue: boolean = false
105
106  build() {
107    Row() {
108      Column({ space: 20 }) {
109        Row() {
110          Text('This is borderImage.').textAlign(TextAlign.Center).fontSize(50)
111        }
112        .borderImage({
113          source: $r('app.media.icon'),
114          slice: this.SliceValue,
115          width: this.WidthValue,
116          outset: this.OutSetValue,
117          repeat: this.RepeatValue[this.SelectIndex],
118          fill: this.FillValue
119        })
120
121        Column() {
122          Text(`borderImageSlice = ${this.SliceValue}px`)
123          Slider({
124            value: this.SliceValue,
125            min: 0,
126            max: 100,
127            style: SliderStyle.OutSet
128          })
129            .onChange((value: number, mode: SliderChangeMode) => {
130              this.SliceValue = value
131            })
132        }
133
134        Column() {
135          Text(`borderImageWidth = ${this.WidthValue}px`)
136          Slider({
137            value: this.WidthValue,
138            min: 0,
139            max: 100,
140            style: SliderStyle.OutSet
141          })
142            .onChange((value: number, mode: SliderChangeMode) => {
143              this.WidthValue = value
144            })
145        }
146
147        Column() {
148          Text(`borderImageOutSet = ${this.OutSetValue}px`)
149          Slider({
150            value: this.OutSetValue,
151            min: 0,
152            max: 100,
153            style: SliderStyle.OutSet
154          })
155            .onChange((value: number, mode: SliderChangeMode) => {
156              this.OutSetValue = value
157            })
158        }
159
160        Row() {
161          Text('borderImageRepeat: ')
162          Select([{ value: 'Repeat' }, { value: 'Stretch' }, { value: 'Round' }, { value: 'Space' }])
163            .value(this.SelectText)
164            .selected(this.SelectIndex)
165            .onSelect((index: number, value?: string) => {
166              this.SelectIndex = index
167              this.SelectText = value as string
168            })
169        }
170
171        Row() {
172          Text(`borderImageFill: ${this.FillValue} `)
173          Toggle({ type: ToggleType.Switch, isOn: this.FillValue })
174            .onChange((isOn: boolean) => {
175              this.FillValue = isOn
176            })
177        }
178
179      }
180      .width('100%')
181    }
182    .height('100%')
183  }
184}
185```
186
187![borderImage](figures/borderImage.gif)
188
189### Example 3: Using LocalizedEdgeWidths Type Values
190
191This example demonstrates how to use the [LocalizedEdgeWidths](ts-types.md#localizededgewidths12) type for the **slice**, **width**, and **outset** properties in the **borderImage** API.
192
193```ts
194// xxx.ets
195import { LengthMetrics } from '@kit.ArkUI'
196
197@Entry
198@Component
199struct BorderImage {
200  @State WidthStartValue: number = 0
201  @State WidthEndValue: number = 0
202  @State SliceStartValue: number = 0
203  @State SliceEndValue: number = 0
204  @State OutSetStartValue: number = 0
205  @State OutSetEndValue: number = 0
206  @State RepeatValue: RepeatMode[] = [RepeatMode.Repeat, RepeatMode.Stretch, RepeatMode.Round, RepeatMode.Space]
207  @State SelectIndex: number = 0
208  @State SelectText: string = 'Repeat'
209  @State FillValue: boolean = false
210
211  build() {
212    Row() {
213      Column({ space: 20 }) {
214        Row() {
215          Text('This is borderImage.').textAlign(TextAlign.Center).fontSize(50)
216        }
217        .borderImage({
218          source: $r('app.media.icon'),
219          slice: {
220            top: LengthMetrics.px(10),
221            bottom: LengthMetrics.px(10),
222            start: LengthMetrics.px(this.SliceStartValue),
223            end: LengthMetrics.px(this.SliceEndValue) },
224          width: {
225            top: LengthMetrics.px(10),
226            bottom: LengthMetrics.px(10),
227            start: LengthMetrics.px(this.WidthStartValue),
228            end: LengthMetrics.px(this.WidthEndValue)
229          },
230          outset: {
231            top: LengthMetrics.px(10),
232            bottom: LengthMetrics.px(10),
233            start: LengthMetrics.px(this.OutSetStartValue),
234            end: LengthMetrics.px(this.OutSetEndValue)
235          },
236          repeat: this.RepeatValue[this.SelectIndex],
237          fill: this.FillValue
238        })
239
240        Column() {
241          Text(`borderImageSliceStart = ${this.SliceStartValue}px`)
242          Slider({
243            value: this.SliceStartValue,
244            min: 0,
245            max: 100,
246            style: SliderStyle.OutSet
247          })
248            .onChange((value: number, mode: SliderChangeMode) => {
249              this.SliceStartValue = value
250            })
251        }
252
253        Column() {
254          Text(`borderImageEndSliceStart = ${this.SliceEndValue}px`)
255          Slider({
256            value: this.SliceEndValue,
257            min: 0,
258            max: 100,
259            style: SliderStyle.OutSet
260          })
261            .onChange((value: number, mode: SliderChangeMode) => {
262              this.SliceEndValue = value
263            })
264        }
265
266        Column() {
267          Text(`borderImageWidthStart = ${this.WidthStartValue}px`)
268          Slider({
269            value: this.WidthStartValue,
270            min: 0,
271            max: 100,
272            style: SliderStyle.OutSet
273          })
274            .onChange((value: number, mode: SliderChangeMode) => {
275              this.WidthStartValue = value
276            })
277        }
278
279        Column() {
280          Text(`borderImageWidthEnd = ${this.WidthEndValue}px`)
281          Slider({
282            value: this.WidthEndValue,
283            min: 0,
284            max: 100,
285            style: SliderStyle.OutSet
286          })
287            .onChange((value: number, mode: SliderChangeMode) => {
288              this.WidthEndValue = value
289            })
290        }
291
292        Column() {
293          Text(`borderImageOutSetStart = ${this.OutSetStartValue}px`)
294          Slider({
295            value: this.OutSetStartValue,
296            min: 0,
297            max: 100,
298            style: SliderStyle.OutSet
299          })
300            .onChange((value: number, mode: SliderChangeMode) => {
301              this.OutSetStartValue = value
302            })
303        }
304
305        Column() {
306          Text(`borderImageOutSetEnd = ${this.OutSetEndValue}px`)
307          Slider({
308            value: this.OutSetEndValue,
309            min: 0,
310            max: 100,
311            style: SliderStyle.OutSet
312          })
313            .onChange((value: number, mode: SliderChangeMode) => {
314              this.OutSetEndValue = value
315            })
316        }
317
318        Row() {
319          Text('borderImageRepeat: ')
320          Select([{ value: 'Repeat' }, { value: 'Stretch' }, { value: 'Round' }, { value: 'Space' }])
321            .value(this.SelectText)
322            .selected(this.SelectIndex)
323            .onSelect((index: number, value?: string) => {
324              this.SelectIndex = index
325              this.SelectText = value as string
326            })
327        }
328
329        Row() {
330          Text(`borderImageFill: ${this.FillValue} `)
331          Toggle({ type: ToggleType.Switch, isOn: this.FillValue })
332            .onChange((isOn: boolean) => {
333              this.FillValue = isOn
334            })
335        }
336
337      }
338      .width('100%')
339    }
340    .height('100%')
341  }
342}
343```
344
345The following shows how the example is represented with left-to-right scripts.
346
347![borderImage](figures/borderImage_ltr.png)
348
349The following shows how the example is represented with right-to-left scripts.
350
351![borderImage](figures/borderImage_rtl.png)
352