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.<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>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 56 57 58```ts 59// xxx.ets 60@Entry 61@Component 62struct Index { 63 build() { 64 Row() { 65 Column() { 66 Text('This is gradient color.').textAlign(TextAlign.Center).height(50).width(200) 67 .borderImage({ 68 source: { 69 angle: 90, 70 direction: GradientDirection.Left, 71 colors: [[0xAEE1E1, 0.0], [0xD3E0DC, 0.3], [0xFCD1D1, 1.0]] 72 }, 73 slice: { top: 10, bottom: 10, left: 10, right: 10 }, 74 width: { top: "10px", bottom: "10px", left: "10px", right: "10px" }, 75 repeat: RepeatMode.Stretch, 76 fill: false 77 }) 78 } 79 .width('100%') 80 } 81 .height('100%') 82 } 83} 84``` 85 86 87 88### Example 2 89 90```ts 91// xxx.ets 92@Entry 93@Component 94struct BorderImage { 95 @State WidthValue: number = 0 96 @State SliceValue: number = 0 97 @State OutSetValue: number = 0 98 @State RepeatValue: RepeatMode[] = [RepeatMode.Repeat, RepeatMode.Stretch, RepeatMode.Round, RepeatMode.Space] 99 @State SelectIndex: number = 0 100 @State SelectText: string = 'Repeat' 101 @State FillValue: boolean = false 102 103 build() { 104 Row() { 105 Column({ space: 20 }) { 106 Row() { 107 Text('This is borderImage.').textAlign(TextAlign.Center).fontSize(50) 108 } 109 .borderImage({ 110 source: $r('app.media.icon'), 111 slice: this.SliceValue, 112 width: this.WidthValue, 113 outset: this.OutSetValue, 114 repeat: this.RepeatValue[this.SelectIndex], 115 fill: this.FillValue 116 }) 117 118 Column() { 119 Text(`borderImageSlice = ${this.SliceValue}px`) 120 Slider({ 121 value: this.SliceValue, 122 min: 0, 123 max: 100, 124 style: SliderStyle.OutSet 125 }) 126 .onChange((value: number, mode: SliderChangeMode) => { 127 this.SliceValue = value 128 }) 129 } 130 131 Column() { 132 Text(`borderImageWidth = ${this.WidthValue}px`) 133 Slider({ 134 value: this.WidthValue, 135 min: 0, 136 max: 100, 137 style: SliderStyle.OutSet 138 }) 139 .onChange((value: number, mode: SliderChangeMode) => { 140 this.WidthValue = value 141 }) 142 } 143 144 Column() { 145 Text(`borderImageOutSet = ${this.OutSetValue}px`) 146 Slider({ 147 value: this.OutSetValue, 148 min: 0, 149 max: 100, 150 style: SliderStyle.OutSet 151 }) 152 .onChange((value: number, mode: SliderChangeMode) => { 153 this.OutSetValue = value 154 }) 155 } 156 157 Row() { 158 Text('borderImageRepeat: ') 159 Select([{ value: 'Repeat' }, { value: 'Stretch' }, { value: 'Round' }, { value: 'Space' }]) 160 .value(this.SelectText) 161 .selected(this.SelectIndex) 162 .onSelect((index: number, value?: string) => { 163 this.SelectIndex = index 164 this.SelectText = value as string 165 }) 166 } 167 168 Row() { 169 Text(`borderImageFill: ${this.FillValue} `) 170 Toggle({ type: ToggleType.Switch, isOn: this.FillValue }) 171 .onChange((isOn: boolean) => { 172 this.FillValue = isOn 173 }) 174 } 175 176 } 177 .width('100%') 178 } 179 .height('100%') 180 } 181} 182``` 183 184 185 186### Example 3 187 188```ts 189// xxx.ets 190// The slice, width, and outset attributes of borderImage use the LocalizedEdgeWidths type. 191 192import { LengthMetrics } from '@kit.ArkUI' 193 194@Entry 195@Component 196struct BorderImage { 197 @State WidthStartValue: number = 0 198 @State WidthEndValue: number = 0 199 @State SliceStartValue: number = 0 200 @State SliceEndValue: number = 0 201 @State OutSetStartValue: number = 0 202 @State OutSetEndValue: number = 0 203 @State RepeatValue: RepeatMode[] = [RepeatMode.Repeat, RepeatMode.Stretch, RepeatMode.Round, RepeatMode.Space] 204 @State SelectIndex: number = 0 205 @State SelectText: string = 'Repeat' 206 @State FillValue: boolean = false 207 208 build() { 209 Row() { 210 Column({ space: 20 }) { 211 Row() { 212 Text('This is borderImage.').textAlign(TextAlign.Center).fontSize(50) 213 } 214 .borderImage({ 215 source: $r('app.media.icon'), 216 slice: { 217 top: LengthMetrics.px(10), 218 bottom: LengthMetrics.px(10), 219 start: LengthMetrics.px(this.SliceStartValue), 220 end: LengthMetrics.px(this.SliceEndValue) }, 221 width: { 222 top: LengthMetrics.px(10), 223 bottom: LengthMetrics.px(10), 224 start: LengthMetrics.px(this.WidthStartValue), 225 end: LengthMetrics.px(this.WidthEndValue) 226 }, 227 outset: { 228 top: LengthMetrics.px(10), 229 bottom: LengthMetrics.px(10), 230 start: LengthMetrics.px(this.OutSetStartValue), 231 end: LengthMetrics.px(this.OutSetEndValue) 232 }, 233 repeat: this.RepeatValue[this.SelectIndex], 234 fill: this.FillValue 235 }) 236 237 Column() { 238 Text(`borderImageSliceStart = ${this.SliceStartValue}px`) 239 Slider({ 240 value: this.SliceStartValue, 241 min: 0, 242 max: 100, 243 style: SliderStyle.OutSet 244 }) 245 .onChange((value: number, mode: SliderChangeMode) => { 246 this.SliceStartValue = value 247 }) 248 } 249 250 Column() { 251 Text(`borderImageEndSliceStart = ${this.SliceEndValue}px`) 252 Slider({ 253 value: this.SliceEndValue, 254 min: 0, 255 max: 100, 256 style: SliderStyle.OutSet 257 }) 258 .onChange((value: number, mode: SliderChangeMode) => { 259 this.SliceEndValue = value 260 }) 261 } 262 263 Column() { 264 Text(`borderImageWidthStart = ${this.WidthStartValue}px`) 265 Slider({ 266 value: this.WidthStartValue, 267 min: 0, 268 max: 100, 269 style: SliderStyle.OutSet 270 }) 271 .onChange((value: number, mode: SliderChangeMode) => { 272 this.WidthStartValue = value 273 }) 274 } 275 276 Column() { 277 Text(`borderImageWidthEnd = ${this.WidthEndValue}px`) 278 Slider({ 279 value: this.WidthEndValue, 280 min: 0, 281 max: 100, 282 style: SliderStyle.OutSet 283 }) 284 .onChange((value: number, mode: SliderChangeMode) => { 285 this.WidthEndValue = value 286 }) 287 } 288 289 Column() { 290 Text(`borderImageOutSetStart = ${this.OutSetStartValue}px`) 291 Slider({ 292 value: this.OutSetStartValue, 293 min: 0, 294 max: 100, 295 style: SliderStyle.OutSet 296 }) 297 .onChange((value: number, mode: SliderChangeMode) => { 298 this.OutSetStartValue = value 299 }) 300 } 301 302 Column() { 303 Text(`borderImageOutSetEnd = ${this.OutSetEndValue}px`) 304 Slider({ 305 value: this.OutSetEndValue, 306 min: 0, 307 max: 100, 308 style: SliderStyle.OutSet 309 }) 310 .onChange((value: number, mode: SliderChangeMode) => { 311 this.OutSetEndValue = value 312 }) 313 } 314 315 Row() { 316 Text('borderImageRepeat: ') 317 Select([{ value: 'Repeat' }, { value: 'Stretch' }, { value: 'Round' }, { value: 'Space' }]) 318 .value(this.SelectText) 319 .selected(this.SelectIndex) 320 .onSelect((index: number, value?: string) => { 321 this.SelectIndex = index 322 this.SelectText = value as string 323 }) 324 } 325 326 Row() { 327 Text(`borderImageFill: ${this.FillValue} `) 328 Toggle({ type: ToggleType.Switch, isOn: this.FillValue }) 329 .onChange((isOn: boolean) => { 330 this.FillValue = isOn 331 }) 332 } 333 334 } 335 .width('100%') 336 } 337 .height('100%') 338 } 339} 340``` 341 342The following shows how the example is represented with left-to-right scripts. 343 344 345 346The following shows how the example is represented with right-to-left scripts. 347 348 349