| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- import { View, Text } from '@tarojs/components'
- import './new_button.scss'
- import { rpxToPx, vibrate } from '@/utils/tools';
- import { useState } from 'react';
- import { IconMore } from '@/components/basic/Icons';
- import { MainColorType } from '@/context/themes/color';
- import Taro from '@tarojs/taro';
- export enum NewButtonType {
- fill = 'fill', //主题实色
- alpha = 'alpha', //主题半透明
- alpha2 = 'alpha2',
- border = 'border', //主题边框
- gray = 'gray', //灰色半透明
- text = 'text', //纯文本
- link = 'link', //超链接(有可能带icon)
- label = 'label',
- more = 'more',
- img = 'image'
- }
- function hexToHSL(hex) {
- // 去掉井号,处理3位和6位16进制
- hex = hex.replace(/^#/, '');
- if (hex.length === 3) {
- hex = hex.split('').map(char => char + char).join('');
- }
- // 解析RGB
- const r = parseInt(hex.slice(0, 2), 16) / 255;
- const g = parseInt(hex.slice(2, 4), 16) / 255;
- const b = parseInt(hex.slice(4, 6), 16) / 255;
- // 计算最大和最小值
- const max = Math.max(r, g, b);
- const min = Math.min(r, g, b);
- let h, s, l = (max + min) / 2;
- // 计算亮度
- if (max === min) {
- h = s = 0; // achromatic
- } else {
- const d = max - min;
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
- switch (max) {
- case r:
- h = (g - b) / d + (g < b ? 6 : 0);
- break;
- case g:
- h = (b - r) / d + 2;
- break;
- case b:
- h = (r - g) / d + 4;
- break;
- }
- h /= 6;
- }
- // 转换为度和百分比
- h = Math.round(h * 360);
- s = Math.round(s * 100);
- l = Math.round(l * 100);
- return `hsl(${h}, ${s}%, ${l - 10}%)`;
- }
- export default function NewButton(props: {
- type: NewButtonType,
- color?: string,
- title?: string,
- children?: any,
- disable?: boolean,
- loading?: boolean,
- onClick?: any,
- width?: number,
- height?: number,
- fontSize?: number,
- bold?: boolean,
- fontNormal?: boolean,
- labelBorder?: boolean,
- btnStyle?: any,
- postBtn?: boolean
- }) {
- const [isTouched, setIsTouched] = useState(false)
- const [noTouch, setNoTouch] = useState(false)
- let style = {}
- switch (props.type) {
- case NewButtonType.fill:
- style = {
- height: props.height ?? rpxToPx(72),
- width: props.width ?? rpxToPx(198),
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: isTouched ? hexToHSL(props.color) : props.disable ? '#B2B2B2' : props.color,
- color: '#fff',
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',//props.bold ? 'bold' : 'normal',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- opacity: props.disable ? 0.6 : 1,
- }
- break
- case NewButtonType.alpha:
- style = {
- height: props.height ?? rpxToPx(72),
- width: props.width ?? rpxToPx(198),
- // paddingLeft:rpxToPx(24),
- // paddingRight:rpxToPx(24),
- // boxSizing:'border-box',
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: isTouched ? props.color + '40' : props.disable ? '#B2B2B240' : props.color + '1A',
- color: props.disable ? '#b2b2b2' : props.color,
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',//props.bold ? 'bold' : 'normal',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- opacity: props.disable ? 0.6 : 1,
- }
- break;
- case NewButtonType.alpha2:
- style = {
- height: props.height ?? rpxToPx(72),
- width: props.width ?? rpxToPx(198),
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: isTouched ? MainColorType.g02 + '4d' : MainColorType.g02 + '1a',
- color: props.disable ? '#b2b2b2' : props.color,
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',//props.bold ? 'bold' : 'normal',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- opacity: props.disable ? 0.6 : 1,
- }
- break;
- case NewButtonType.border:
- style = {
- height: props.height ?? rpxToPx(72),
- width: props.width ?? rpxToPx(198),
- borderWidth: rpxToPx(2),
- borderColor: props.disable ? '#B2B2B2' : props.color,
- borderStyle: 'solid',
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: isTouched ? props.color + '26' : 'transparent',
- color: props.disable ? '#b2b2b2' : props.color,
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',//props.bold ? 'bold' : 'normal',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- opacity: props.disable ? 0.6 : 1,
- boxSizing: 'border-box'
- }
- break;
- case NewButtonType.gray:
- style = {
- height: props.height ?? rpxToPx(72),
- minWidth: props.width ?? rpxToPx(198),
- paddingLeft: props.width ? 0 : 15,
- paddingRight: props.width ? 0 : 15,
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: isTouched ? '#99999940' : '#9999991A',
- color: props.disable ? '#b2b2b2' : '#000000',
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',//props.bold ? 'bold' : 'normal',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- boxSizing: 'border-box',
- // opacity: props.disable ? 0.6 : 1,
- }
- // style = {
- // height: props.height ?? rpxToPx(72),
- // width: props.width ?? rpxToPx(198),
- // borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- // backgroundColor: isTouched ? '#9999991A' : 'transparent',
- // color: props.disable ? '#999999' : '#999999',
- // fontSize: props.fontSize ?? rpxToPx(30),
- // display: 'flex',
- // alignItems: 'center',
- // justifyContent: 'center',
- // // opacity: props.disable ? 0.6 : 1,
- // }
- break
- case NewButtonType.text:
- style = {
- height: props.height ?? rpxToPx(72),
- width: props.width ?? rpxToPx(198),
- borderRadius: props.height ? props.height / 4 : rpxToPx(72 / 4),
- backgroundColor: props.disable ? '#B2B2B240' : isTouched ? '#B2B2B240' : '#B2B2B21A',
- color: props.disable ? '#b2b2b2' : '#000',
- fontSize: props.fontSize ?? rpxToPx(30),
- fontWeight: props.fontNormal ? 'normal' : 'bold',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- }
- break;
- case NewButtonType.link:
- style = {
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- flexDirection: 'row',
- flex: 1,
- width: '100%',
- height: '100%',
- color: props.color ? props.color : '#5C7099',
- fontSize: props.fontSize ? props.fontSize : rpxToPx(26),
- opacity: isTouched ? 0.4 : 1,
- }
- break
- case NewButtonType.label:
- style = {
- ...props.btnStyle,
- height: rpxToPx(64),
- borderRadius: rpxToPx(32),
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- fontSize: rpxToPx(28),
- fontWeight: props.fontNormal ? 'normal' : 'bold',
- paddingLeft: rpxToPx(24),
- paddingRight: rpxToPx(24),
- boxSizing: 'border-box',
- backgroundColor: isTouched ? '#5C709940' : props.labelBorder ? 'transparent' : '#5C70991A',
- borderWidth: rpxToPx(2),
- borderColor: props.labelBorder ? '#5C709940' : 'transparent',
- borderStyle: 'solid',
- color: '#5C7099'
- }
- break
- case NewButtonType.more:
- return <View style={{
- ...props.btnStyle,
- width: rpxToPx(74),
- height: rpxToPx(44),
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- borderRadius: rpxToPx(11),
- backgroundColor: isTouched ? MainColorType.g02 + '4d' : MainColorType.g02 + '1a'
- }}
- catchMove
- onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) {
- vibrate();
- return;
- }
- if (noTouch && props.postBtn) return;
- props.onClick()
- setNoTouch(true)
- setTimeout(() => {
- setNoTouch(false)
- }, 1000)
- }}
- onTouchStart={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) return
- setIsTouched(true)
- }}
- onTouchEnd={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- setIsTouched(false)
- }}
- >
- <IconMore color={MainColorType.link} width={rpxToPx(34)} />
- </View>
- case NewButtonType.img:
- return <View style={{ opacity: isTouched ? 0.6 : 1, ...props.btnStyle, display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) {
- vibrate();
- return;
- }
- if (noTouch && props.postBtn) return;
- props.onClick()
- setNoTouch(true)
- setTimeout(() => {
- setNoTouch(false)
- }, 1000)
- }}
- onTouchStart={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) {
- return;
- }
- setIsTouched(true)
- }}
- onTouchEnd={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- setIsTouched(false)
- }}>
- {props.children}
- </View>
- }
- return <View
- style={{ ...style, ...props.btnStyle, display: 'flex', flexDirection: 'row', alignItems: 'center' }}
- // catchMove
- onClick={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) {
- vibrate();
- return;
- }
- if (noTouch && props.postBtn) return;
- props.onClick()
- if (props.type == NewButtonType.link) {
- return
- }
- var platform = ''
- if (Taro.getDeviceInfo) {
- platform = Taro.getDeviceInfo().platform
- }
- else {
- platform = Taro.getSystemInfoSync().platform
- }
- if (platform == 'windows' || platform == 'mac') {
- return
- }
- setNoTouch(true)
- setTimeout(() => {
- setNoTouch(false)
- }, 1000)
- }}
- onTouchStart={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- if (props.disable) return
- setIsTouched(true)
- }}
- onTouchEnd={(e) => {
- if (process.env.TARO_ENV == 'weapp') {
- e.stopPropagation()
- }
- setIsTouched(false)
- }}
- >{props.children}{props.title}</View>
- }
|