666 lines
19 KiB
Vue
666 lines
19 KiB
Vue
<template>
|
|
<div class="pallet" ref="palletRef">
|
|
<div class="palletColo" @click="openPallet">
|
|
<div v-show="!selectColor.gradient" class="palletBackColor" :title="selectColor.name" :style="{'background-color':selectColor.hex}">
|
|
{{ selectColor.hex }}
|
|
</div>
|
|
<div v-show="selectColor.gradient" class="palletBackColor" :style="{'background-image':`linear-gradient(${selectColor.gradient?.angle}deg,${setGradient(selectColor.gradient)})`}">
|
|
</div>
|
|
</div>
|
|
<div class="palletBox">
|
|
<div class="color_setting_block" @click.stop>
|
|
<Chrome class="chrome_color" v-model="color_"></Chrome>
|
|
<div class="color_setting_operateSingle">
|
|
<div class="color_setting_btn" :class="{active:!color?.gradient?.gradientShow}">{{ $t('ColorboardUpload.Single') }}</div>
|
|
<a-switch :checked="color?.gradient?.gradientShow" @click="setOperate"/>
|
|
<div class="color_setting_btn" :class="{active:color?.gradient?.gradientShow}">{{ $t('ColorboardUpload.Gradual') }}</div>
|
|
</div>
|
|
<div class="color_setting_operate" v-if="color?.gradient?.gradientShow">
|
|
<div class="color_setting_operate_item color_setting_operate_control">
|
|
<div class="operate_item_box">
|
|
<div>{{ $t('ColorboardUpload.Alignment') }}</div>
|
|
</div>
|
|
<div class="operate_item_box operate_item_angle">
|
|
<div class="operate_item_angle_box" @mousedown="mousedownGradientAngle(getMousePosition($event,false))" @touchstart="mousedownGradientAngle(getMousePosition($event,true))">
|
|
<div :style="{'transform':`rotate(${color.gradient.angle}deg)`}"></div>
|
|
</div>
|
|
</div>
|
|
<div class="operate_item_box operate_item_delete">
|
|
<i class="fi fi-rr-trash" @click="deleteGradientItem"></i>
|
|
</div>
|
|
</div>
|
|
<div class="color_setting_operate_item color_setting_operate_input">
|
|
<div class="color_setting_operate_bg" @click="addGradient($event)" :style="{'background-image':color?.gradient?`linear-gradient(90deg,${setGradient(color.gradient)})`:'none'}">
|
|
</div>
|
|
<div v-for="item,index in color.gradient.gradientList" :key="item" class="color_setting_operate_btn" :class="{'active':index == color.gradient.selectIndex}" :style="{'left':item.left,'background-color':`rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`}" @mousedown="mousedownGradient(getMousePosition($event,false),item,index,)" @touchstart="mousedownGradient(getMousePosition($event,true),item,index,)"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
<script lang="ts">
|
|
import { defineComponent,computed,ref,watch,nextTick,onMounted,onUnmounted,toRefs, reactive} from 'vue'
|
|
import { useStore } from "vuex";
|
|
import { useI18n } from 'vue-i18n'
|
|
import { message,Upload} from 'ant-design-vue';
|
|
import { Sketch, Chrome} from '@ans1998/vue3-color'
|
|
import { getMousePosition } from "@/tool/mdEvent";
|
|
import { rgbaToHex } from "@/tool/util"
|
|
import { color } from 'echarts/core';
|
|
export default defineComponent({
|
|
components:{
|
|
Chrome,
|
|
},
|
|
props:{
|
|
selectColor:{
|
|
type:Object,
|
|
default:()=>{}
|
|
},
|
|
},
|
|
emits:['selectUplpadColor'],
|
|
setup(props,{emit}) {
|
|
const {t} = useI18n()
|
|
const store = useStore();
|
|
const palletData = reactive({
|
|
palletShow: true,
|
|
palletList:[],
|
|
color_:{} as any,
|
|
color:{} as any,
|
|
updataSelectColorTime:null as any,
|
|
gradient:{
|
|
gradientList:[
|
|
{
|
|
rgba:{
|
|
r:117,
|
|
g:119,
|
|
b:255,
|
|
a:1,
|
|
},
|
|
left:'0%'
|
|
},{
|
|
rgba:{
|
|
r:0,
|
|
g:222,
|
|
b:152,
|
|
a:1,
|
|
},
|
|
left:'100%'
|
|
},
|
|
],
|
|
angle:45,
|
|
selectIndex:-1,
|
|
gradientShow:false,
|
|
},
|
|
setGradient:computed(()=>{
|
|
return (gradient:any)=>{
|
|
let gradientStr = ''
|
|
if(!gradient?.gradientList)return
|
|
gradient.gradientList.sort((a:any, b:any) => {
|
|
let aArr = a.left.split('%')[0]
|
|
let bArr = b.left.split('%')[0]
|
|
return aArr - bArr;
|
|
});
|
|
gradient.gradientList.forEach((item:any,index:any)=>{
|
|
let str = ','
|
|
if(gradient.gradientList.length == index+1)str = ''
|
|
let rgba = item.rgba?item.rgba:{r:255,g:255,b:255}
|
|
gradientStr += `rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a}) ${item.left}${str}`
|
|
|
|
})
|
|
return `${gradientStr}`
|
|
}
|
|
})
|
|
|
|
})
|
|
const getpalletListDom = reactive({
|
|
})
|
|
const palletRef = ref(null)
|
|
watch(()=>palletData.color_,(newVal:any)=>{
|
|
if(!newVal?.rgba?.r)return
|
|
if(palletData.color?.gradient?.gradientShow){
|
|
palletData.color.gradient.gradientList[palletData.color.gradient.selectIndex].rgba = {
|
|
r:newVal.rgba.r,
|
|
g:newVal.rgba.g,
|
|
b:newVal.rgba.b,
|
|
a:newVal.rgba.a,
|
|
}
|
|
}else{
|
|
palletData.color = newVal
|
|
}
|
|
})
|
|
watch(()=>palletData.color,(newVal:any)=>{
|
|
if(JSON.stringify(props.selectColor) != JSON.stringify(newVal)){
|
|
newVal.name = ''
|
|
newVal.tcx = ''
|
|
let rgba = [newVal.rgba.r,newVal.rgba.g,newVal.rgba.b]
|
|
let hex = rgbaToHex(rgba)
|
|
newVal.hex = hex
|
|
emit('selectUplpadColor',newVal)
|
|
}
|
|
},{deep: true })
|
|
const setOperate = ()=>{
|
|
if(!palletData.color.rgba)return message.info(t('DesignDetailAlter.jsContent7'))
|
|
palletData.color.rgba = palletData.color?.rgba?.r?palletData.color.rgba:{r:0,g:0,b:0,a:1}
|
|
palletData.gradient.selectIndex = 0
|
|
palletData.gradient.gradientShow = true
|
|
if(!palletData.color.gradient){
|
|
if(palletData.color.rgba.r){
|
|
palletData.gradient.gradientList[palletData.gradient.selectIndex].rgba = {
|
|
r:palletData.color.rgba.r,
|
|
g:palletData.color.rgba.g,
|
|
b:palletData.color.rgba.b,
|
|
a:1,
|
|
}
|
|
}
|
|
palletData.color.gradient = JSON.parse(JSON.stringify(palletData.gradient))
|
|
}else{
|
|
palletData.color.rgba = palletData.color.gradient.gradientList[0].rgba
|
|
palletData.color.gradient = null
|
|
}
|
|
}
|
|
const deleteGradientItem = ()=>{
|
|
if(palletData.color.gradient.gradientList.length <= 2)return
|
|
palletData.color.gradient.gradientList.splice(palletData.color.gradient.selectIndex,1)
|
|
}
|
|
const addGradient = (event:any)=>{
|
|
let gradientWidth = event.target.clientWidth
|
|
let left:any = event.offsetX/gradientWidth
|
|
palletData.color.gradient.gradientList.push({
|
|
rgba:palletData.color_.rgba,
|
|
left:left.toFixed(2)*100+'%'
|
|
})
|
|
}
|
|
const mousedownGradientAngle = (event:any)=>{
|
|
// isMoible() true为移动端
|
|
let domPosition = event.target.getBoundingClientRect()
|
|
let position = {
|
|
x:domPosition.x+domPosition.width/2,
|
|
y:domPosition.y+domPosition.height/2,
|
|
}
|
|
let angle
|
|
let mousedown = function(event:any){
|
|
let e = getMousePosition(event,false)
|
|
mouseDownOperation(e)
|
|
}
|
|
|
|
let touchstart = function(event:any){
|
|
let e = getMousePosition(event,true)
|
|
mouseDownOperation(e)
|
|
}
|
|
let mouseDownOperation = (e:any)=>{
|
|
let X = position.x
|
|
let Y = position.y
|
|
let x = (e.clientX) - X
|
|
let y = Y -( e.clientY)
|
|
angle = Math.atan2(x,y)*(180 / Math.PI)
|
|
// this.colorList[this.selectIndex].gradient = JSON.parse(JSON.stringify(this.gradient))
|
|
palletData.color.gradient.angle = angle
|
|
|
|
}
|
|
let mouseupGradientAngle = ()=>{
|
|
window.removeEventListener('touchmove',touchstart)
|
|
window.removeEventListener('touchend',mouseupGradientAngle)
|
|
|
|
window.removeEventListener('mousemove',mousedown)
|
|
window.removeEventListener('mouseup',mouseupGradientAngle)
|
|
}
|
|
window.addEventListener('touchmove',touchstart)
|
|
window.addEventListener('touchend',mouseupGradientAngle)
|
|
|
|
window.addEventListener('mousemove',mousedown)
|
|
window.addEventListener('mouseup',mouseupGradientAngle)
|
|
}
|
|
|
|
const mousedownGradient = (event:any,item:any,index:number)=>{
|
|
palletData.color.gradient.selectIndex = index
|
|
|
|
|
|
// this.selectColor = {rgba:gradientRgba,hex:hex} //顔色选择器默认颜色
|
|
let gradientWidth = (palletRef.value.querySelector('.color_setting_operate_bg') as any).clientWidth
|
|
let position = {
|
|
x:event.clientX,
|
|
left:event.target.style.left?event.target.style.left.split('%')[0]:0
|
|
}
|
|
let mousedown = function(event:any){
|
|
let e = getMousePosition(event,false)
|
|
mousedownGradient(e)
|
|
}
|
|
|
|
let touchstart = function(event:any){
|
|
let e = getMousePosition(event,true)
|
|
mousedownGradient(e)
|
|
}
|
|
let mousedownGradient = (e:any)=>{
|
|
let left = ((e.clientX) - position.x)/gradientWidth*100+Number(position.left)
|
|
left = (left<0?0:left>100?100:left)
|
|
item.left = left+'%'
|
|
}
|
|
|
|
let mouseupGradientAngle = ()=>{
|
|
window.removeEventListener('touchmove',touchstart)
|
|
window.removeEventListener('touchend',mouseupGradientAngle)
|
|
window.removeEventListener('mousemove',mousedown)
|
|
window.removeEventListener('mouseup',mouseupGradientAngle)
|
|
}
|
|
window.addEventListener('touchmove',touchstart)
|
|
window.addEventListener('touchend',mouseupGradientAngle)
|
|
|
|
window.addEventListener('mousemove',mousedown)
|
|
window.addEventListener('mouseup',mouseupGradientAngle)
|
|
|
|
|
|
}
|
|
const selectImgItem = ()=>{
|
|
|
|
}
|
|
const openPallet = ()=>{
|
|
if(palletData.palletShow && props.selectColor?.rgba?.r){
|
|
if(props.selectColor.gradient){
|
|
palletData.color_.rgba = props.selectColor.gradient.gradientList[0].rgba
|
|
}else{
|
|
palletData.color_ = JSON.parse(JSON.stringify(props.selectColor))
|
|
palletData.gradient.gradientShow = false
|
|
}
|
|
|
|
palletData.color = JSON.parse(JSON.stringify(props.selectColor))
|
|
}else{
|
|
}
|
|
}
|
|
// 点击外部区域关闭颜色选择器
|
|
const handleClickOutside = (event: Event) => {
|
|
const target = event.target as HTMLElement;
|
|
const colorSettingBlock = palletRef.value.querySelector('.color_setting_block');
|
|
const palletColo = palletRef.value.querySelector('.palletColo');
|
|
|
|
// 如果点击的是 .palletColo 或 .color_setting_block 内部,则不关闭
|
|
if (palletData.palletShow && colorSettingBlock &&
|
|
!colorSettingBlock.contains(target) &&
|
|
!palletColo?.contains(target)) {
|
|
palletData.palletShow = false;
|
|
}
|
|
}
|
|
|
|
onMounted(()=>{
|
|
// 添加点击外部区域监听器
|
|
// document.addEventListener('click', handleClickOutside);
|
|
|
|
nextTick().then(()=>{
|
|
const backIcon = document.createElement('div');
|
|
backIcon.classList.add('vc-sketch-color-wrap')
|
|
let dropperDom = palletRef.value.getElementsByClassName('vc-chrome-fields-wrap')[0]
|
|
dropperDom.appendChild(backIcon);
|
|
backIcon.addEventListener('click',async ()=>{
|
|
try {
|
|
const dropper = new EyeDropper();
|
|
const result = await dropper.open();
|
|
let hex = result.sRGBHex.replace("#", "");
|
|
// 将十六进制颜色码拆分成红、绿、蓝三个部分
|
|
const r = parseInt(hex.substring(0, 2), 16);
|
|
const g = parseInt(hex.substring(2, 4), 16);
|
|
const b = parseInt(hex.substring(4, 6), 16);
|
|
palletData.color = {rgba:{r:r,g:g,b:b,a:1},hex:result.sRGBHex}
|
|
// return `rgb(${r}, ${g}, ${b})`;
|
|
// box.style.backgroundColor = label.textContent = result.sRGBHex;
|
|
} catch (e) {
|
|
message.info(t('DesignDetailAlter.jsContent1'))
|
|
}
|
|
})
|
|
openPallet();
|
|
})
|
|
})
|
|
|
|
onUnmounted(()=>{
|
|
// 清理事件监听器
|
|
// document.removeEventListener('click', handleClickOutside);
|
|
})
|
|
return{
|
|
...toRefs(palletData),
|
|
...toRefs(getpalletListDom),
|
|
palletRef,
|
|
openPallet,
|
|
selectImgItem,
|
|
setOperate,
|
|
deleteGradientItem,
|
|
addGradient,
|
|
mousedownGradientAngle,
|
|
mousedownGradient,
|
|
getMousePosition,
|
|
}
|
|
},
|
|
|
|
provide() {
|
|
return {
|
|
}
|
|
},
|
|
|
|
})
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.pallet{
|
|
// position: absolute;
|
|
width: 100%;
|
|
user-select: none;
|
|
> .palletColo{
|
|
width: 100%;
|
|
height: 7rem;
|
|
border-radius: .5rem;
|
|
border: 1px solid #000;
|
|
padding: .5rem .6rem;
|
|
cursor: pointer;
|
|
> .palletBackColor{
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
}
|
|
> .palletBox{
|
|
margin-top: 1.5rem;
|
|
width: 100%;
|
|
z-index: 2;
|
|
> .color_setting_block{
|
|
margin: auto;
|
|
background: linear-gradient(70deg, #eee4f3, #f3f4e6);
|
|
width: 100%;
|
|
// border-radius: calc(1rem*1.2);
|
|
overflow: hidden;
|
|
box-shadow: 2px 2px 8px rgba(0,0,0,.3);
|
|
.vc-chrome{
|
|
background: rgba(0,0,0,0);
|
|
box-shadow:none;
|
|
}
|
|
:deep(.chrome_color){
|
|
width: 100%;
|
|
overflow: hidden;
|
|
|
|
.vc-chrome-saturation-wrap{
|
|
width: 30rem;
|
|
height: 30rem;
|
|
margin: 2rem auto;
|
|
padding-bottom: 0;
|
|
}
|
|
.vc-saturation-pointer{
|
|
pointer-events: none;
|
|
}
|
|
.vc-chrome-body{
|
|
padding: 0;
|
|
width: 90%;
|
|
margin: 2 auto;
|
|
margin: 0 auto;
|
|
background: rgba(0,0,0,0);
|
|
margin-bottom: 3rem;
|
|
// display: none;
|
|
.vc-chrome-fields-wrap{
|
|
margin-top: 5%;
|
|
padding: 0;
|
|
position: relative;
|
|
.vc-chrome-toggle-btn{
|
|
width: calc(3.2rem*1.2);
|
|
.vc-chrome-toggle-icon{
|
|
height: auto;
|
|
margin-right: calc(-0.4rem*1.2);
|
|
margin-top: calc(0rem*1.2);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
svg{
|
|
width: calc(2.4rem*1.2) !important;
|
|
height: calc(2.4rem*1.2) !important;
|
|
}
|
|
}
|
|
}
|
|
.vc-chrome-fields{
|
|
.vc-chrome-field{
|
|
padding-left: calc(.6rem*1.2);
|
|
}
|
|
.vc-input__label{
|
|
font-size: calc(1.6rem*1.2);
|
|
}
|
|
.vc-input__input{
|
|
font-size: 2rem;
|
|
height: 4rem;
|
|
}
|
|
}
|
|
.ant-upload-list{
|
|
|
|
}
|
|
.vc-sketch-color-wrap{
|
|
background-image: url(@/assets/images/homePage/dropper.png);
|
|
background-size: 3rem;
|
|
background-repeat: no-repeat;
|
|
background-position: 50%;
|
|
cursor: pointer;
|
|
margin: 0;
|
|
width: 4rem;
|
|
height: 4rem;
|
|
padding: calc(.7rem*1.2);
|
|
border: 1px solid;
|
|
position: absolute;
|
|
bottom: -2rem;
|
|
right: 0rem;
|
|
border-radius: calc(.5rem*1.2);
|
|
|
|
}
|
|
.vc-chrome-fields{
|
|
.vc-input__label{
|
|
margin-top: calc(1rem*1.2);
|
|
}
|
|
}
|
|
.vc-chrome-fields:nth-child(2){
|
|
>:last-of-type {
|
|
display: none;
|
|
}
|
|
}
|
|
.vc-chrome-fields:nth-child(3){
|
|
>:last-of-type {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
.vc-chrome-controls{
|
|
align-items: center;
|
|
flex-direction: row-reverse;
|
|
.vc-chrome-color-wrap{
|
|
// width: 3.6rem*1.2);
|
|
margin-left: calc(2rem*1.2);
|
|
width: auto;
|
|
.vc-chrome-active-color{
|
|
border-radius: 50%;
|
|
}
|
|
.vc-chrome-active-color,.vc-checkerboard{
|
|
width: calc(3rem*1.2);
|
|
height: calc(3rem*1.2);
|
|
}
|
|
}
|
|
.vc-chrome-hue-wrap,.vc-chrome-alpha-wrap{
|
|
.vc-hue{
|
|
border-radius: 15px;
|
|
}
|
|
.vc-alpha{
|
|
border-radius: 15px;
|
|
overflow: hidden;
|
|
}
|
|
height: 2rem;
|
|
margin: 0;
|
|
.vc-hue-pointer{
|
|
transform: translateX(-1.25rem);
|
|
}
|
|
.vc-hue-picker{
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
border-radius: 50%;
|
|
transform: translate(0px,-3px);
|
|
}
|
|
}
|
|
.vc-chrome-alpha-wrap{
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
.vc-chrome-saturation-wrap .vc-saturation-circle{
|
|
width: calc(1rem*1.2);
|
|
height: calc(1rem*1.2);
|
|
}
|
|
}
|
|
.color_block{
|
|
// margin-top: calc(1rem;
|
|
// display: flex;
|
|
// justify-content: space-between;
|
|
// font-size: calc(1.6rem;
|
|
width: 100%;
|
|
padding: 0 5%;
|
|
padding-bottom: 5%;
|
|
margin: calc(0.5rem*1.2) auto;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
.color_right{
|
|
width: 13rem;
|
|
font-size: calc(1.2rem*1.2);
|
|
color: #666666;
|
|
.color_rgb_block{
|
|
display: flex;
|
|
.rgb_item{
|
|
margin-left: calc(.2rem*1.2);
|
|
}
|
|
}
|
|
}
|
|
.color_left{
|
|
cursor: pointer;
|
|
color: rgb(153, 153, 153);
|
|
}
|
|
.color_right,.color_left{
|
|
>div{
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.color_HEX_block,.color_rgb_block{
|
|
padding: .25rem .6rem;
|
|
box-shadow: inset 0 0 0 1px #ccc;
|
|
border-radius: .5rem;
|
|
justify-content: space-around;
|
|
text-transform:uppercase;
|
|
.color_block_bg{
|
|
width: 1.8rem;
|
|
height: 2.5rem;
|
|
// margin-right: .5rem;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
.color_block_bg{
|
|
}
|
|
}
|
|
|
|
}
|
|
.color_setting_operateSingle{
|
|
text-align: center;
|
|
margin: 1rem 0;
|
|
display: flex;
|
|
justify-content: center;
|
|
.color_setting_btn{
|
|
margin: 0 1rem;
|
|
color: rgba(0, 0, 0, 0.5);
|
|
&.active{
|
|
color: rgba(0, 0, 0, 0.7);
|
|
font-weight: 900;
|
|
}
|
|
}
|
|
}
|
|
.color_setting_operate{
|
|
*{
|
|
-webkit-touch-callout: none; /* iOS Safari */
|
|
-webkit-user-select: none; /* Safari */
|
|
-moz-user-select: none; /* Firefox */
|
|
-ms-user-select: none; /* Internet Explorer/Edge */
|
|
user-select: none;
|
|
}
|
|
.color_setting_operate_item{
|
|
display: flex;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
.operate_item_box{
|
|
}
|
|
}
|
|
.color_setting_operate_control{
|
|
.operate_item_delete,.operate_item_angle{
|
|
cursor: pointer;
|
|
}
|
|
.operate_item_delete{
|
|
i{
|
|
display: flex;
|
|
font-size: 3rem;
|
|
}
|
|
}
|
|
.operate_item_angle{
|
|
.operate_item_angle_box{
|
|
border-radius: 50%;
|
|
width: 4rem;
|
|
height: 4rem;
|
|
border: solid 2px #000;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
>div{
|
|
height: 100%;
|
|
width: 1rem;
|
|
position: relative;
|
|
pointer-events:none;
|
|
}
|
|
>div::before{
|
|
position: absolute;
|
|
content: "";
|
|
top: 0.2rem;
|
|
left: 0;
|
|
width: 1rem;
|
|
height: 1rem;
|
|
border-radius: 50%;
|
|
background: #000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.color_setting_operate_input{
|
|
width: 80%;
|
|
// padding: 0 10%;
|
|
margin: 1.2rem 10%;
|
|
border-radius: 10%;
|
|
position: relative;
|
|
height: 2.5rem;
|
|
.color_setting_operate_bg{
|
|
border-radius: .5rem;
|
|
width: 100%;
|
|
height: 2.5rem;
|
|
background: #fff;
|
|
position: absolute;
|
|
}
|
|
}
|
|
.color_setting_operate_btn{
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translate(-50%,-50%);
|
|
left: 0;
|
|
width: 1rem;
|
|
height: 110%;
|
|
border: .2rem solid;
|
|
border-radius: .5rem;
|
|
cursor: pointer;
|
|
box-sizing: content-box;
|
|
z-index: 2;
|
|
&.active{
|
|
border: .3rem solid;
|
|
}
|
|
}
|
|
.color_setting_operate_btn:hover{
|
|
border: .3rem solid;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |