papayaui 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  - 💪 Vue 3 Composition API
6
6
  - 🔥 Written in TypeScript
7
+ - 🧀 [Document](https://jiangwei58.github.io/papayaui)
7
8
 
8
9
  ## 准备工作
9
10
 
@@ -83,8 +84,6 @@ pnpm install async-validator dayjs
83
84
  // ...
84
85
  "types": ["papayaui/global"]
85
86
  },
86
- // 防止组件props类型识别错误
87
- "include": ["node_modules/papayaui/components/*/*.vue"]
88
87
  }
89
88
  ```
90
89
 
@@ -0,0 +1,19 @@
1
+ @import '../../styles/vars.scss';
2
+
3
+ .#{$prefix}-circle {
4
+ position: relative;
5
+ display: inline-block;
6
+ text-align: center;
7
+
8
+ &__text {
9
+ position: absolute;
10
+ top: 50%;
11
+ left: 0;
12
+ width: 100%;
13
+ color: _var(circle-text-color, _var(color-black));
14
+ font-weight: _var(circle-font-weight, 500);
15
+ font-size: _var(circle-font-size, 14px);
16
+ line-height: _var(circle-text-line-height, 20px);
17
+ transform: translateY(-50%);
18
+ }
19
+ }
@@ -0,0 +1,163 @@
1
+ <template>
2
+ <view :class="ns.b()">
3
+ <canvas
4
+ :id="id"
5
+ :canvas-id="id"
6
+ type="2d"
7
+ :style="{
8
+ width: getUnitValue(size, 'px'),
9
+ height: getUnitValue(size, 'px'),
10
+ }"
11
+ />
12
+ <view v-if="!text" :class="ns.e('text')">
13
+ <slot></slot>
14
+ </view>
15
+ <cover-view v-else :class="ns.e('text')">{{ text }}</cover-view>
16
+ </view>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { getCurrentInstance, onMounted, watch } from 'vue'
21
+ import { useNamespace } from '../../core'
22
+ import { getUnitValue } from '../../utils'
23
+ import { circleProps } from './props'
24
+
25
+ const ns = useNamespace('circle')
26
+
27
+ const props = defineProps(circleProps)
28
+
29
+ const instance = getCurrentInstance()
30
+ const id = ns.e('canvas') + Date.now()
31
+
32
+ const BEGIN_ANGLE = -Math.PI / 2
33
+ const PERIMETER = 2 * Math.PI
34
+ const STEP = 1
35
+
36
+ let context: CanvasRenderingContext2D | null = null
37
+ let currentValue = 0
38
+
39
+ onMounted(() => {
40
+ // #ifdef H5
41
+ initH5()
42
+ // #endif
43
+ // #ifndef H5
44
+ initMP()
45
+ // #endif
46
+ })
47
+
48
+ watch(
49
+ () => props.modelValue,
50
+ () => {
51
+ if (context) {
52
+ renderCircle(context)
53
+ }
54
+ },
55
+ )
56
+
57
+ const initMP = () => {
58
+ const ratio = uni.getSystemInfoSync().pixelRatio
59
+ const query = uni.createSelectorQuery()
60
+ query
61
+ .in(instance)
62
+ .select('#' + id)
63
+ .node(() => {})
64
+ .exec((res) => {
65
+ const canvas = res[0].node as HTMLCanvasElement
66
+ const canvasSize = props.size * ratio
67
+ canvas.width = canvasSize
68
+ canvas.height = canvasSize
69
+ context = canvas.getContext('2d')
70
+ if (!context) return
71
+
72
+ context.scale(ratio, ratio)
73
+ renderCircle(context)
74
+ })
75
+ }
76
+
77
+ const initH5 = () => {
78
+ const ratio = window.devicePixelRatio
79
+ const canvasSize = props.size * ratio
80
+ const canvas = document.querySelector(`#${id} canvas`) as HTMLCanvasElement
81
+ canvas.width = canvasSize
82
+ canvas.height = canvasSize
83
+ context = canvas.getContext('2d')
84
+ if (!context) return
85
+
86
+ context.scale(ratio, ratio)
87
+ renderCircle(context)
88
+ }
89
+
90
+ const renderCircle = (ctx: CanvasRenderingContext2D) => {
91
+ if (props.speed <= 0 || props.speed > 1000) {
92
+ drawCircle(ctx, props.modelValue)
93
+ return
94
+ }
95
+
96
+ let interval: number | null
97
+ currentValue = currentValue ?? 0
98
+ const run = () => {
99
+ interval = setTimeout(() => {
100
+ if (currentValue === props.modelValue) {
101
+ stop()
102
+ return
103
+ }
104
+ if (Math.abs(currentValue - props.modelValue) < STEP) {
105
+ currentValue = props.modelValue
106
+ } else if (currentValue < props.modelValue) {
107
+ currentValue += STEP
108
+ } else {
109
+ currentValue -= STEP
110
+ }
111
+ drawCircle(ctx, currentValue)
112
+ run()
113
+ }, 1000 / props.speed) as unknown as number | null
114
+ }
115
+
116
+ const stop = () => {
117
+ if (interval) {
118
+ clearTimeout(interval)
119
+ interval = null
120
+ }
121
+ }
122
+
123
+ stop()
124
+ run()
125
+ }
126
+
127
+ const drawLayerCircle = (ctx: CanvasRenderingContext2D) => {
128
+ drawCanvas(ctx, BEGIN_ANGLE, PERIMETER, props.layerColor)
129
+ }
130
+
131
+ const drawCircle = (ctx: CanvasRenderingContext2D, value: number) => {
132
+ const progress = PERIMETER * (value / 100)
133
+ const endAngle = props.clockwise ? BEGIN_ANGLE + progress : 3 * Math.PI - (BEGIN_ANGLE + progress)
134
+ ctx.clearRect(0, 0, props.size, props.size)
135
+ drawLayerCircle(ctx)
136
+ if (value !== 0) {
137
+ drawCanvas(ctx, BEGIN_ANGLE, endAngle, props.color, props.clockwise)
138
+ }
139
+ }
140
+
141
+ const drawCanvas = (
142
+ ctx: CanvasRenderingContext2D,
143
+ sRadian: number,
144
+ eRadian: number,
145
+ color: string,
146
+ clockwise = true,
147
+ ) => {
148
+ const position = props.size / 2
149
+ const lineWidth = Number(props.strokeWidth)
150
+ const radius = position - lineWidth / 2
151
+
152
+ ctx.beginPath()
153
+ ctx.lineCap = 'round'
154
+ ctx.strokeStyle = color
155
+ ctx.lineWidth = lineWidth
156
+ ctx.arc(position, position, radius, sRadian, eRadian, !clockwise)
157
+ ctx.stroke()
158
+ }
159
+ </script>
160
+
161
+ <style lang="scss" scoped>
162
+ @import './circle.scss';
163
+ </style>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <DocDemoBlock title="基础用法" card>
3
+ <Demo1 />
4
+ </DocDemoBlock>
5
+ <DocDemoBlock title="样式定制" card>
6
+ <Demo2 />
7
+ </DocDemoBlock>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import DocDemoBlock from '../../doc/doc-demo-block.vue'
12
+ import Demo1 from '../../demos/circle/demo-1.vue'
13
+ import Demo2 from '../../demos/circle/demo-2.vue'
14
+ </script>
15
+
16
+ <style lang="scss" scoped></style>
17
+ <style lang="scss">
18
+ page {
19
+ background-color: var(--pa-color-gray);
20
+ }
21
+ </style>
@@ -0,0 +1,4 @@
1
+ import type Circle from './circle.vue'
2
+
3
+ export type CircleInstance = InstanceType<typeof Circle>
4
+ export * from './props'
@@ -0,0 +1,59 @@
1
+ import type { ExtractPropTypes } from 'vue'
2
+
3
+ export const circleProps = {
4
+ /**
5
+ * 目标进度
6
+ */
7
+ modelValue: {
8
+ type: Number,
9
+ default: 0,
10
+ },
11
+ /**
12
+ * 圆环直径,单位px
13
+ */
14
+ size: {
15
+ type: Number,
16
+ default: 100,
17
+ },
18
+ /**
19
+ * 进度条颜色
20
+ */
21
+ color: {
22
+ type: String,
23
+ default: '#009c5d',
24
+ },
25
+ /**
26
+ * 轨道颜色
27
+ */
28
+ layerColor: {
29
+ type: String,
30
+ default: '#fff',
31
+ },
32
+ /**
33
+ * 文字
34
+ */
35
+ text: String,
36
+ /**
37
+ * 进度条宽度,单位px
38
+ */
39
+ strokeWidth: {
40
+ type: [Number, String],
41
+ default: 4,
42
+ },
43
+ /**
44
+ * 是否顺时针
45
+ */
46
+ clockwise: {
47
+ type: Boolean,
48
+ default: true,
49
+ },
50
+ /**
51
+ * 动画速度(单位为 value/s)
52
+ */
53
+ speed: {
54
+ type: Number,
55
+ default: 50,
56
+ },
57
+ }
58
+
59
+ export type CircleProps = ExtractPropTypes<typeof circleProps>
@@ -8,6 +8,7 @@ export * from './cell-group'
8
8
  export * from './checkbox'
9
9
  export * from './checkbox-btns'
10
10
  export * from './checkbox-group'
11
+ export * from './circle'
11
12
  export * from './collapse'
12
13
  export * from './collapse-item'
13
14
  export * from './container'
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <pa-circle :model-value="80" />
3
+ </template>
@@ -0,0 +1,35 @@
1
+ <template>
2
+ <view>
3
+ <pa-circle :model-value="progress" stroke-width="8" text="设置宽度" />
4
+ <pa-circle :model-value="progress" color="#ff2b2b" text="设置颜色" />
5
+ <pa-circle :model-value="progress" :clockwise="false" text="逆时针" />
6
+ <pa-circle :model-value="progress" :size="150" text="设置大小" />
7
+ </view>
8
+ <view class="mt-15">
9
+ <pa-button type="primary" @click="add">增加</pa-button>
10
+ <pa-button type="danger" class="ml-15" @click="subtract">减少</pa-button>
11
+ </view>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { ref } from 'vue'
16
+
17
+ const STEP = 10
18
+ const progress = ref(80)
19
+
20
+ const add = () => {
21
+ if (progress.value >= 100) return
22
+ progress.value += STEP
23
+ }
24
+
25
+ const subtract = () => {
26
+ if (progress.value <= 0) return
27
+ progress.value -= STEP
28
+ }
29
+ </script>
30
+
31
+ <style lang="scss" scoped>
32
+ :deep(.pa-circle) {
33
+ margin-right: 15px;
34
+ }
35
+ </style>
package/global.d.ts CHANGED
@@ -10,6 +10,7 @@ declare module '@vue/runtime-core' {
10
10
  PaCheckbox: typeof import('papayaui/components/checkbox/checkbox.vue')['default']
11
11
  PaCheckboxBtns: typeof import('papayaui/components/checkbox-btns/checkbox-btns.vue')['default']
12
12
  PaCheckboxGroup: typeof import('papayaui/components/checkbox-group/checkbox-group.vue')['default']
13
+ PaCircle: typeof import('papayaui/components/circle/circle.vue')['default']
13
14
  PaCollapse: typeof import('papayaui/components/collapse/collapse.vue')['default']
14
15
  PaCollapseItem: typeof import('papayaui/components/collapse-item/collapse-item.vue')['default']
15
16
  PaContainer: typeof import('papayaui/components/container/container.vue')['default']
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "papayaui",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "适用于uniapp的ui扩展库",
5
5
  "packageManager": "pnpm@8.6.0",
6
6
  "dependencies": {
@@ -18,7 +18,7 @@
18
18
  "bugs": {
19
19
  "url": "https://github.com/jiangwei58/papayaui/issues"
20
20
  },
21
- "homepage": "https://github.com/jiangwei58/papayaui",
21
+ "homepage": "https://jiangwei58.github.io/papayaui",
22
22
  "author": "jiangw",
23
23
  "license": "MIT",
24
24
  "main": "index.ts",
@@ -60,9 +60,15 @@
60
60
  // 定义圆角
61
61
  @for $i from 3 through 35 {
62
62
  .rounded-#{$i} {
63
- border-radius: #{$i}rpx;
63
+ border-radius: $i + $pixelUnit;
64
64
  }
65
65
  }
66
+ .rounded-none {
67
+ border-radius: 0;
68
+ }
69
+ .rounded-full {
70
+ border-radius: 9999px;
71
+ }
66
72
 
67
73
  // 盒子模型
68
74
  .box-border {
@@ -1,14 +1,14 @@
1
- // 定义字体(rpx单位)
1
+ // 定义字体大小
2
2
  @for $i from 20 through 65 {
3
3
  .text-#{$i} {
4
- font-size: #{$i}rpx;
4
+ font-size: $i + $pixelUnit;
5
5
  }
6
6
  }
7
7
 
8
8
  // 定义字体行高
9
9
  @for $i from 10 through 65 {
10
10
  .leading-#{$i} {
11
- line-height: #{$i}rpx;
11
+ line-height: $i + $pixelUnit;
12
12
  }
13
13
  }
14
14
 
@@ -62,13 +62,13 @@
62
62
  // 只要双数和能被5除尽的数
63
63
  @if $i % 2 == 0 or $i % 5 == 0 {
64
64
  .gap-#{$i} {
65
- gap: $i + rpx;
65
+ gap: $i + $pixelUnit;
66
66
  }
67
67
  .gap-x-#{$i} {
68
- column-gap: $i + rpx;
68
+ column-gap: $i + $pixelUnit;
69
69
  }
70
70
  .gap-y-#{$i} {
71
- row-gap: $i + rpx;
71
+ row-gap: $i + $pixelUnit;
72
72
  }
73
73
  }
74
74
  }
@@ -3,37 +3,37 @@
3
3
  // 只要双数和能被5除尽的数
4
4
  @if $i % 2 == 0 or $i % 5 == 0 {
5
5
  .m-#{$i} {
6
- margin: $i + rpx !important;
6
+ margin: $i + $pixelUnit !important;
7
7
  }
8
8
 
9
9
  .p-#{$i} {
10
- padding: $i + rpx !important;
10
+ padding: $i + $pixelUnit !important;
11
11
  }
12
12
 
13
13
  .mx-#{$i} {
14
- margin-left: $i + rpx;
15
- margin-right: $i + rpx;
14
+ margin-left: $i + $pixelUnit;
15
+ margin-right: $i + $pixelUnit;
16
16
  }
17
17
  .my-#{$i} {
18
- margin-top: $i + rpx;
19
- margin-bottom: $i + rpx;
18
+ margin-top: $i + $pixelUnit;
19
+ margin-bottom: $i + $pixelUnit;
20
20
  }
21
21
  .px-#{$i} {
22
- padding-left: $i + rpx;
23
- padding-right: $i + rpx;
22
+ padding-left: $i + $pixelUnit;
23
+ padding-right: $i + $pixelUnit;
24
24
  }
25
25
  .py-#{$i} {
26
- padding-top: $i + rpx;
27
- padding-bottom: $i + rpx;
26
+ padding-top: $i + $pixelUnit;
27
+ padding-bottom: $i + $pixelUnit;
28
28
  }
29
29
 
30
30
  @each $short, $long in l left, t top, r right, b bottom {
31
31
  .m#{$short}-#{$i} {
32
- margin-#{$long}: $i + rpx !important;
32
+ margin-#{$long}: $i + $pixelUnit !important;
33
33
  }
34
34
 
35
35
  .p#{$short}-#{$i} {
36
- padding-#{$long}: $i + rpx !important;
36
+ padding-#{$long}: $i + $pixelUnit !important;
37
37
  }
38
38
  }
39
39
  }
package/styles/vars.scss CHANGED
@@ -1,4 +1,5 @@
1
- $prefix: pa;
1
+ $prefix: pa !default;
2
+ $pixelUnit: rpx !default;
2
3
 
3
4
  @function _var($varName, $default: null) {
4
5
  @if ($default == null) {
package/.DS_Store DELETED
Binary file