daoji_h5/uni_modules/v-sign/components/v-sign-pen/v-sign-pen.vue

216 lines
4.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="v-sign-pen">
<view class="label" v-if="label">{{ label }}</view>
<view class="options">
<view
class="opt-item"
:style="{
minHeight: minWrapHeight,
marginRight: space + 'rpx'
}"
v-for="item in csizes"
:key="item.size"
@click="onItemClick(item)"
>
<view
:class="type"
:style="{
border:
border && currentSelect.size === item.size
? `${borderWidth}rpx solid ${activeColor}`
: ''
}"
>
<view class="inner" :style="[defaultInnerStyle(item)]"></view>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* v-sign-pen 画笔v-sign 子组件)
* @description 设置 v-sign 画笔的线宽
* @tutorial
* @property {String} type 选项样式 line / circle
* @property {String} label 标签
* @property {Array} sizes 画笔大小数组,单位 px
* @property {String} color 选项颜色
* @property {String} activeColor 选中项颜色
* @property {Boolean} border 选中项是否有边框
* @property {Number} borderWidth 边框大小,单位 rpx
* @property {String} space 选项间隙,单位 rpx
* @property {Number} bigger 圆点变大变粗倍数
* @property {Number} minSize 圆点最小大小,单位 px
* @event {Function} change 选择画笔大小时触发
* @example
**/
// v-sign 父组件提供的接口
let vSignInterface
// 选项样式
const type_style = {
CIRCLE: 'circle',
LINE: 'line'
}
export default {
name: 'v-sign-pen',
props: {
// 选项样式
type: {
type: String,
default: type_style.CIRCLE
},
label: {
type: String
},
// 画笔大小数组单位是px
sizes: {
type: Array,
default: () => [2, 4, 6, 8, 10]
},
// 选项颜色
color: {
type: String,
default: '#333'
},
// 选中项颜色
activeColor: {
type: String,
default: '#333'
},
// 选中项是否有边框
border: {
type: Boolean,
default: true
},
// 边框大小, 单位 rpx
borderWidth: {
type: Number,
default: 4
},
// 选项间隙, 单位 rpx
space: {
type: Number,
default: 20
},
// 圆点变大变粗倍数
bigger: {
type: Number,
default: 2
},
// 圆点最小大小,单位 px
minSize: {
type: Number,
default: 4
}
},
inject: ['getSignInterface'],
data() {
return {
type_style,
currentSelect: null,
csizes: [],
maxSize: 0,
maxCsize: 0
}
},
computed: {
minWrapHeight() {
let height
switch (this.type) {
case type_style.CIRCLE:
height = this.maxCsize + 10 + 'px'
break
case type_style.LINE:
height = this.maxSize + 4 + 'px'
break
}
return height
}
},
created() {
this.csizes = this.sizes.map((size, index) => {
const csize = (index + 1) * this.bigger + this.minSize
this.maxSize = csize > this.maxSize ? csize : this.maxSize
this.maxCsize = csize > this.maxCsize ? csize : this.maxCsize
return {
size,
csize
}
})
this.currentSelect = this.csizes[0]
},
mounted() {
vSignInterface = this.getSignInterface()
this.setLineWidth()
},
methods: {
onItemClick(opt) {
this.currentSelect = opt
this.setLineWidth()
this.$emit('change', opt.size)
},
setLineWidth() {
vSignInterface.setLineWidth(this.currentSelect.size)
},
defaultInnerStyle(item) {
let width
let height
switch (this.type) {
case type_style.CIRCLE:
width = `${item.csize}px`
height = `${item.csize}px`
break
case type_style.LINE:
width = '20px'
height = `${item.size}px`
break
}
const background = this.currentSelect.size === item.size ? this.activeColor : this.color
return {
width,
height,
background
}
}
}
}
</script>
<style lang="scss" scoped>
.v-sign-pen {
padding: 12rpx;
.label {
font-size: 28rpx;
color: #333;
}
.options {
display: flex;
align-items: flex-end;
.opt-item {
display: flex;
align-items: flex-end;
justify-content: center;
&:last-child {
margin-right: 0;
}
&:active {
transition: transform 0.3s;
transform: scale(1.1);
}
.circle {
border-radius: 50%;
padding: 4rpx;
.inner {
border-radius: 50%;
}
}
.line {
padding: 4rpx;
}
}
}
}
</style>