# @amoy/components

使用该插件，可以快速进行元素布局。

## Tips:

- 在 Sprite 中设置 border-radius 必然会有 overflow 的效果；
- backgroundFrame 无法修改 texture 宽高，只能更新定位；
- text标签内容不能为空；

## 使用姿势：

1. 模板语法糖形式：

```js
import { render, style } from '@amoy/components'

// 使用 PIXI 原生创建游戏
const game = new PIXI.Application()

game.loader.add('rect', rect).load((loader, resources) => {
    style({
        '.container': {
            width: '100%',
            height: '100%',
            centerX: 0,
            centerY: 0,
        },
    })

    render(`
        <container class="container">
            <sprite src="rect" style="width: 200; height: 200; left: 50; top: 50;">
        </container>
    `, game.stage)
})
```

2. 使用元素API直接创建:

```js
import { createComponent, Sprite, View, Rect, Text, Circle } from '@amoy/components'
import rect from './images/rect.jpg'

// 使用 PIXI 原生创建游戏
const game = new PIXI.Application()

// 创建容器
const parent = View({
    width: 600,
    height: 600,
    centerX: 0,
    centerY: 0,
    borderWidth: 5,
    borderColor: 'black',
})
parent.appendTo(game.stage)

// 创建精灵图
game.loader.add('rect', rect).load((loader, resources) => {
	const sprite = Sprite(resources.rect.texture, {
        width: 200,
        height: 200,
        left: 50, 
        top: 50,
    })
    sprite.appendTo(parent)
})

// 创建文字
const text = Text('我是一排文字~我会根据宽度自动换行~~', {
    width: 200,
    height: 200,
    right: 50,
    bottom: 50,
    fontSize: 30,
    color: '#a72461',
    lineHeight: 60,
})
text.appendTo(parent)

// 创建图形
const rect = Rect({
    backgroundColor: '#f9e090',
    borderWidth: 5,
    borderColor: '#dc5353',
    // borderRadius: 20,
    width: 200,
    height: 200,
    right: 50,
    top: 50,
})
rect.appendTo(parent)
```

## API

### configComponents

全局配置 Components

```js
configComponents({
	// UI稿宽度，用于计算缩放比进行不同屏幕的自适应
    uiDesignWidth: 1000,
    // 开启后，所有元素会有黑色边缘展示
    debug: boolean，
})
```

### 创建元素

#### 创建精灵

```js
Sprite(image: PIXI.Texture | HTMLCanvasElement | HTMLVideoElement | HTMLImageElement, Style)
```

#### 创建帧动画精灵

```js
// animatedFrames: 准备播放的 texture 资源数组
// 可以自行拼装，也可以通过 spritesheet 工具生成 
AnimatedSprite(animatedFrames: PIXI.Texture[], style)
```

#### 创建容器

```js
View(style)
```

#### 创建矩形

```js
Rect(style)
```

#### 创建圆形

```js
Circle(style)
```

#### 创建文字

```js
Text(content: string, style)
```

### style

布局参数

```js
interface style {

	 // 元素宽度， 选填
	 // 不填时根据默认尺寸
	 // 	sprite 根据原图尺寸
	 // 	text 根据父级容器宽度
	 // 参数: 500 | '500px' | '50%'
	 // 当参数包含 px 时， 则为实际像素，不会进行UI比缩放；
    width?: string | number,
    
    // 元素高度， 选填
    // 不填时， 
    // 	sprite 根据原图比例进行计算，
    // 	text 根据 fontSize 和 lineHeight 自适应，其余为 1
    height?: string | number,
    
    // 定位坐标，选填， 默认值为 0
    // 可配置多种参数形式:
	    // 100 | '100px' | '100%'     
	    // 当有 ’px‘ 单位时，该值不会基于 UI缩放比 进行缩放
	left?: string | number,
	right?: string | number,
	top?: string | number,
	bottom?: string | number,
	centerX?: string | number,
    centerY?: string | number,
    
    // 旋转角度，选填， 默认值为 0
    // 参数形式: 
	    // 当为 number 时， 表示弧度， rotation: 1
	    // 当为 string 时， 则表示角度, rotation: '45' | '45deg'
	rotation?: number | string,
	
	// 缩放值，默认状态为 1
	scale?: number
    
    // 透明度， 默认状态为 1
    opacity?: number,
    
	// 设置背景颜色
		// 支持写法: 'red' | '#ffffff' | 0xffffff
		// 支持标签: rect / container / circle 
    backgroundColor?: number | string,
    
    // 设置精灵图显示区域
        // 支持标签: sprite
        // eg: [x, y, width, height]
    backgroundFrame?: number[],
    
    // 设置边框
    	// 支持标签: rect / container / circle 
	borderWidth?: number | string,
	// 设置边框颜色
		// 支持写法: 'red' | '#ffffff' | 0xffffff
   	borderColor?: number | string,
	
	// 设置圆角
	borderRadius?: number | string,

    // 超出的部分是否显示
    overflow?: 'hidden',
    
    // 设置锚点，默认值为 { x: .5, y: .5 }
    anchor?: { x: number, y: number },
    
    // 层级
    zIndex?: number
    
    // 文字属性，专属于 text 标签
    // 会继承于父级
	// 文字颜色
		// 支持写法: 'red' | '#ffffff' | 0xffffff
    color?: string,
    // 元素中的文字定位
    textAlign?: 'left' | 'center' | 'right'

    // 文字垂直定位
    textJustify?: 'top' | 'center' | 'bottom'
	// 文字大小
	fontSize?: number | string,
	fontWeight?: 'normal'| 'bold'| 'bolder'| 'lighter' | '100' | '200' ...
	fontStyle?: 'normal' | 'italic' | 'oblique'
	fontFamily?: string | string[]
	lineHeight?: number,
        
   // 更多属性可以参考 http://pixijs.download/release/docs/PIXI.TextStyle.html

    // AnimatedSprite 专属
    // 帧动画资源
    animatedFrames?: PIXI.Texture[]
    // 是否循环播放
    animatedLoop?: boolean
    // 播放速度: 1 ~ 60 帧 / s
    animatedSpeed?: number
 }
```

### 模板API

#### render(template, mountNode, extra)

- template: 标签模板, 例如:
    
    ```js
    <container>
    	<sprite>Sprite</sprite>
    	<text>TEXT</text>
    	<rect>
    		<circle />		
    	</rect>
    	<animatedsprite />
    </container>
    	
    ```
    
    - 标签上可以使用 `id` / `class` 匹配对应的样式
    
- mountNode: 挂载到的元素。
- extra: 数据，可在 template 的属性中获取，例如:

```js
render(`
	<sprite src="data.texture" />
`, game.stage, {
	texture: texture,
})
```

#### style(css) 

```js
style({
	'.class': `width: 300; height: 300;`,
	'#id': {
		width: 300,
		height: 300,
	},
	tag: `font-size: 30`
})
```

### 元素操作

#### 更新布局

```js
// style 中的属性均可通过该方法直接更新
el.setStyle({
    width: 500,
    height: 500,
})

// 单独设置 scale
el.layout.setScale(scale: number)
```

#### 添加与删除

```js
// 将自身添加到某容器中
child.appendTo(parent)

// 添加子元素
parent.append(child1)

// 在 child1 前面添加元素 child2
child1.before(child2)

// 在 child1 后面添加元素 child2
child1.after(child2)

// 将 child2 添加到 child1 前面
child2.insertBefore(child1)
// 将 child2 添加到 child1 后面
child2.insertAfter(child1)

// 移除 child2
child2.remove()
parent.removeChild(child2)
```


#### 获取定位

```js
// { width: number, height: number, x: number, y: number }
// 获取相对于父级的定位
el.getRelativeBounds()

// 获取相对于全局的定位
el.getGlobalBounds()
```

#### 工具函数

- el.transformStyle(style): 用于将 style 类型转换成便于外部使用的定位参数；
    - return { x: number, y: number, width: number, height: number, rotation: number }

#### 标签专属API

- AnimatedSprite.replay()
    - 当 AnimatedSprite.loop = false 时，该方法能使动画重新播放一遍；



