mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 放映画笔工具添加形状和箭头标注
This commit is contained in:
parent
82dc18f1f1
commit
6c8ed6d5ef
@ -147,7 +147,7 @@ Browser access: http://127.0.0.1:5173/
|
|||||||
- Formula line thickness settings
|
- Formula line thickness settings
|
||||||
### Slide Show
|
### Slide Show
|
||||||
- Preview all slides
|
- Preview all slides
|
||||||
- Pen and blackboard tools
|
- Brush tools (pen/shape/arrow/highlighter annotation, eraser, blackboard mode)
|
||||||
- Timer tool
|
- Timer tool
|
||||||
- Laser pointer
|
- Laser pointer
|
||||||
- Auto play
|
- Auto play
|
||||||
|
@ -141,7 +141,7 @@ npm run dev
|
|||||||
- 公式线条粗细设置
|
- 公式线条粗细设置
|
||||||
### 幻灯片放映
|
### 幻灯片放映
|
||||||
- 全部幻灯片预览
|
- 全部幻灯片预览
|
||||||
- 画笔、黑板工具
|
- 画笔工具(画笔/形状/箭头/荧光笔标注、橡皮擦除、黑板模式)
|
||||||
- 计时器工具
|
- 计时器工具
|
||||||
- 激光笔
|
- 激光笔
|
||||||
- 自动放映
|
- 自动放映
|
||||||
|
@ -76,7 +76,7 @@ onMounted(() => {
|
|||||||
else x.value = document.body.clientWidth + props.left - props.width
|
else x.value = document.body.clientWidth + props.left - props.width
|
||||||
|
|
||||||
if (props.top >= 0) y.value = props.top
|
if (props.top >= 0) y.value = props.top
|
||||||
else y.value = document.body.clientHeight + props.top - realHeight.value
|
else y.value = document.body.clientHeight + props.top - (props.height || realHeight.value)
|
||||||
|
|
||||||
w.value = props.width
|
w.value = props.width
|
||||||
h.value = props.height
|
h.value = props.height
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
}"
|
}"
|
||||||
v-if="model === 'pen'"
|
v-if="model === 'pen'"
|
||||||
>
|
>
|
||||||
<IconWrite class="icon" :size="penSize * 6" v-if="model === 'pen'" />
|
<IconWrite class="icon" :size="penSize * 6" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="pen"
|
class="pen"
|
||||||
@ -48,7 +48,18 @@
|
|||||||
}"
|
}"
|
||||||
v-if="model === 'mark'"
|
v-if="model === 'mark'"
|
||||||
>
|
>
|
||||||
<IconHighLight class="icon" :size="markSize * 1.5" v-if="model === 'mark'" />
|
<IconHighLight class="icon" :size="markSize * 1.5" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="pen"
|
||||||
|
:style="{
|
||||||
|
left: mouse.x - 20 + 'px',
|
||||||
|
top: mouse.y - 20 + 'px',
|
||||||
|
color: color,
|
||||||
|
}"
|
||||||
|
v-if="model === 'shape'"
|
||||||
|
>
|
||||||
|
<IconPlus class="icon" :size="40" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -59,18 +70,22 @@ import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
color?: string
|
color?: string
|
||||||
model?: 'pen' | 'eraser' | 'mark'
|
model?: 'pen' | 'eraser' | 'mark' | 'shape'
|
||||||
|
shapeType?: 'rect' | 'circle' | 'arrow'
|
||||||
blackboard?: boolean
|
blackboard?: boolean
|
||||||
penSize?: number
|
penSize?: number
|
||||||
markSize?: number
|
markSize?: number
|
||||||
rubberSize?: number
|
rubberSize?: number
|
||||||
|
shapeSize?: number
|
||||||
}>(), {
|
}>(), {
|
||||||
color: '#ffcc00',
|
color: '#ffcc00',
|
||||||
model: 'pen',
|
model: 'pen',
|
||||||
|
shapeType: 'rect',
|
||||||
blackboard: false,
|
blackboard: false,
|
||||||
penSize: 6,
|
penSize: 6,
|
||||||
markSize: 24,
|
markSize: 24,
|
||||||
rubberSize: 80,
|
rubberSize: 80,
|
||||||
|
shapeSize: 4,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -89,6 +104,8 @@ let isMouseDown = false
|
|||||||
let lastTime = 0
|
let lastTime = 0
|
||||||
let lastLineWidth = -1
|
let lastLineWidth = -1
|
||||||
|
|
||||||
|
let initialImageData: ImageData | null = null
|
||||||
|
|
||||||
// 鼠标位置坐标:用于画笔或橡皮位置跟随
|
// 鼠标位置坐标:用于画笔或橡皮位置跟随
|
||||||
const mouse = ref({
|
const mouse = ref({
|
||||||
x: 0,
|
x: 0,
|
||||||
@ -140,7 +157,7 @@ const updateCtx = () => {
|
|||||||
ctx.globalCompositeOperation = 'xor'
|
ctx.globalCompositeOperation = 'xor'
|
||||||
ctx.globalAlpha = 0.5
|
ctx.globalAlpha = 0.5
|
||||||
}
|
}
|
||||||
else if (props.model === 'pen') {
|
else if (props.model === 'pen' || props.model === 'shape') {
|
||||||
ctx.globalCompositeOperation = 'source-over'
|
ctx.globalCompositeOperation = 'source-over'
|
||||||
ctx.globalAlpha = 1
|
ctx.globalAlpha = 1
|
||||||
}
|
}
|
||||||
@ -221,6 +238,92 @@ const getLineWidth = (s: number, t: number) => {
|
|||||||
return lineWidth * 1 / 3 + lastLineWidth * 2 / 3
|
return lineWidth * 1 / 3 + lastLineWidth * 2 / 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 形状绘制
|
||||||
|
const drawShape = (currentX: number, currentY: number) => {
|
||||||
|
if (!ctx || !initialImageData) return
|
||||||
|
|
||||||
|
ctx.putImageData(initialImageData, 0, 0)
|
||||||
|
|
||||||
|
const startX = lastPos.x
|
||||||
|
const startY = lastPos.y
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
ctx.lineCap = 'butt'
|
||||||
|
ctx.lineJoin = 'miter'
|
||||||
|
|
||||||
|
ctx.beginPath()
|
||||||
|
if (props.shapeType === 'rect') {
|
||||||
|
const width = currentX - startX
|
||||||
|
const height = currentY - startY
|
||||||
|
ctx.rect(startX, startY, width, height)
|
||||||
|
}
|
||||||
|
else if (props.shapeType === 'circle') {
|
||||||
|
const width = currentX - startX
|
||||||
|
const height = currentY - startY
|
||||||
|
const centerX = startX + width / 2
|
||||||
|
const centerY = startY + height / 2
|
||||||
|
const radiusX = Math.abs(width) / 2
|
||||||
|
const radiusY = Math.abs(height) / 2
|
||||||
|
|
||||||
|
ctx.ellipse(
|
||||||
|
centerX,
|
||||||
|
centerY,
|
||||||
|
Math.abs(radiusX),
|
||||||
|
Math.abs(radiusY),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
Math.PI * 2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (props.shapeType === 'arrow') {
|
||||||
|
const dx = currentX - startX
|
||||||
|
const dy = currentY - startY
|
||||||
|
const angle = Math.atan2(dy, dx)
|
||||||
|
const arrowLength = Math.max(props.shapeSize, 4) * 2
|
||||||
|
|
||||||
|
const endX = currentX - (Math.cos(angle) * arrowLength)
|
||||||
|
const endY = currentY - (Math.sin(angle) * arrowLength)
|
||||||
|
|
||||||
|
ctx.moveTo(startX, startY)
|
||||||
|
ctx.lineTo(endX, endY)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.strokeStyle = props.color
|
||||||
|
ctx.lineWidth = props.shapeSize
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
|
if (props.shapeType === 'arrow') {
|
||||||
|
const dx = currentX - startX
|
||||||
|
const dy = currentY - startY
|
||||||
|
const angle = Math.atan2(dy, dx)
|
||||||
|
|
||||||
|
const arrowLength = Math.max(props.shapeSize, 4) * 2.6
|
||||||
|
const arrowWidth = Math.max(props.shapeSize, 4) * 1.6
|
||||||
|
|
||||||
|
const arrowBaseX = currentX - (Math.cos(angle) * arrowLength)
|
||||||
|
const arrowBaseY = currentY - (Math.sin(angle) * arrowLength)
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
ctx.beginPath()
|
||||||
|
|
||||||
|
ctx.moveTo(currentX, currentY)
|
||||||
|
|
||||||
|
const leftX = arrowBaseX + arrowWidth * Math.cos(angle + Math.PI / 2)
|
||||||
|
const leftY = arrowBaseY + arrowWidth * Math.sin(angle + Math.PI / 2)
|
||||||
|
const rightX = arrowBaseX + arrowWidth * Math.cos(angle - Math.PI / 2)
|
||||||
|
const rightY = arrowBaseY + arrowWidth * Math.sin(angle - Math.PI / 2)
|
||||||
|
|
||||||
|
ctx.lineTo(leftX, leftY)
|
||||||
|
ctx.lineTo(rightX, rightY)
|
||||||
|
ctx.closePath()
|
||||||
|
|
||||||
|
ctx.fillStyle = props.color
|
||||||
|
ctx.fill()
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 路径操作
|
// 路径操作
|
||||||
const handleMove = (x: number, y: number) => {
|
const handleMove = (x: number, y: number) => {
|
||||||
const time = new Date().getTime()
|
const time = new Date().getTime()
|
||||||
@ -232,12 +335,21 @@ const handleMove = (x: number, y: number) => {
|
|||||||
|
|
||||||
draw(x, y, lineWidth)
|
draw(x, y, lineWidth)
|
||||||
lastLineWidth = lineWidth
|
lastLineWidth = lineWidth
|
||||||
}
|
|
||||||
else if (props.model === 'mark') draw(x, y, props.markSize)
|
|
||||||
else erase(x, y)
|
|
||||||
|
|
||||||
lastPos = { x, y }
|
lastPos = { x, y }
|
||||||
lastTime = new Date().getTime()
|
lastTime = new Date().getTime()
|
||||||
|
}
|
||||||
|
else if (props.model === 'mark') {
|
||||||
|
draw(x, y, props.markSize)
|
||||||
|
lastPos = { x, y }
|
||||||
|
}
|
||||||
|
else if (props.model ==='eraser') {
|
||||||
|
erase(x, y)
|
||||||
|
lastPos = { x, y }
|
||||||
|
}
|
||||||
|
else if (props.model === 'shape') {
|
||||||
|
drawShape(x, y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取鼠标在canvas中的相对位置
|
// 获取鼠标在canvas中的相对位置
|
||||||
@ -257,6 +369,9 @@ const handleMousedown = (e: MouseEvent | TouchEvent) => {
|
|||||||
const x = mouseX / widthScale.value
|
const x = mouseX / widthScale.value
|
||||||
const y = mouseY / heightScale.value
|
const y = mouseY / heightScale.value
|
||||||
|
|
||||||
|
if (props.model === 'shape') {
|
||||||
|
initialImageData = ctx!.getImageData(0, 0, canvasRef.value!.width, canvasRef.value!.height)
|
||||||
|
}
|
||||||
isMouseDown = true
|
isMouseDown = true
|
||||||
lastPos = { x, y }
|
lastPos = { x, y }
|
||||||
lastTime = new Date().getTime()
|
lastTime = new Date().getTime()
|
||||||
|
@ -78,6 +78,7 @@ import {
|
|||||||
Click,
|
Click,
|
||||||
Theme,
|
Theme,
|
||||||
ArrowCircleLeft,
|
ArrowCircleLeft,
|
||||||
|
ArrowRight,
|
||||||
GraphicDesign,
|
GraphicDesign,
|
||||||
Logout,
|
Logout,
|
||||||
Erase,
|
Erase,
|
||||||
@ -209,6 +210,7 @@ export const icons: Icons = {
|
|||||||
IconClick: Click,
|
IconClick: Click,
|
||||||
IconTheme: Theme,
|
IconTheme: Theme,
|
||||||
IconArrowCircleLeft: ArrowCircleLeft,
|
IconArrowCircleLeft: ArrowCircleLeft,
|
||||||
|
IconArrowRight: ArrowRight,
|
||||||
IconGraphicDesign: GraphicDesign,
|
IconGraphicDesign: GraphicDesign,
|
||||||
IconLogout: Logout,
|
IconLogout: Logout,
|
||||||
IconErase: Erase,
|
IconErase: Erase,
|
||||||
|
@ -14,23 +14,24 @@
|
|||||||
:penSize="penSize"
|
:penSize="penSize"
|
||||||
:markSize="markSize"
|
:markSize="markSize"
|
||||||
:rubberSize="rubberSize"
|
:rubberSize="rubberSize"
|
||||||
|
:shapeSize="shapeSize"
|
||||||
|
:shapeType="shapeType"
|
||||||
@end="hanldeWritingEnd()"
|
@end="hanldeWritingEnd()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MoveablePanel
|
<MoveablePanel
|
||||||
class="tools-panel"
|
class="tools-panel"
|
||||||
:width="520"
|
:width="510"
|
||||||
:height="50"
|
:height="50"
|
||||||
:left="left"
|
:left="left"
|
||||||
:top="top"
|
:top="top"
|
||||||
:moveable="sizePopoverType === ''"
|
|
||||||
>
|
>
|
||||||
<div class="tools" @mousedown.stop>
|
<div class="tools" @mousedown.stop>
|
||||||
<div class="tool-content">
|
<div class="tool-content">
|
||||||
<Popover trigger="manual" :value="sizePopoverType === 'pen'">
|
<Popover placement="top" trigger="manual" :value="sizePopoverType === 'pen'">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="size">
|
<div class="setting">
|
||||||
<div class="label">墨迹粗细:</div>
|
<div class="label">墨迹粗细:</div>
|
||||||
<Slider class="size-slider" :min="4" :max="10" :step="2" v-model:value="penSize" />
|
<Slider class="size-slider" :min="4" :max="10" :step="2" v-model:value="penSize" />
|
||||||
</div>
|
</div>
|
||||||
@ -39,9 +40,26 @@
|
|||||||
<IconWrite class="icon" />
|
<IconWrite class="icon" />
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
<Popover trigger="manual" :value="sizePopoverType === 'mark'">
|
<Popover placement="top" trigger="manual" :value="sizePopoverType === 'shape'">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="size">
|
<div class="setting shape">
|
||||||
|
<div class="shapes">
|
||||||
|
<IconSquare class="icon" :class="{ 'active': shapeType === 'rect' }" @click="shapeType = 'rect'" />
|
||||||
|
<IconRound class="icon" :class="{ 'active': shapeType === 'circle' }" @click="shapeType = 'circle'" />
|
||||||
|
<IconArrowRight class="icon" :class="{ 'active': shapeType === 'arrow' }" @click="shapeType = 'arrow'" />
|
||||||
|
</div>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<div class="label">墨迹粗细:</div>
|
||||||
|
<Slider class="size-slider" :min="2" :max="8" :step="2" v-model:value="shapeSize" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="btn" :class="{ 'active': writingBoardModel === 'shape' }" v-tooltip="'形状'" @click="changeModel('shape')">
|
||||||
|
<IconGraphicDesign class="icon" />
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
<Popover placement="top" trigger="manual" :value="sizePopoverType === 'mark'">
|
||||||
|
<template #content>
|
||||||
|
<div class="setting">
|
||||||
<div class="label">墨迹粗细:</div>
|
<div class="label">墨迹粗细:</div>
|
||||||
<Slider class="size-slider" :min="16" :max="40" :step="4" v-model:value="markSize" />
|
<Slider class="size-slider" :min="16" :max="40" :step="4" v-model:value="markSize" />
|
||||||
</div>
|
</div>
|
||||||
@ -50,9 +68,9 @@
|
|||||||
<IconHighLight class="icon" />
|
<IconHighLight class="icon" />
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
<Popover trigger="manual" :value="sizePopoverType === 'eraser'">
|
<Popover placement="top" trigger="manual" :value="sizePopoverType === 'eraser'">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="size">
|
<div class="setting">
|
||||||
<div class="label">橡皮大小:</div>
|
<div class="label">橡皮大小:</div>
|
||||||
<Slider class="size-slider" :min="20" :max="200" :step="20" v-model:value="rubberSize" />
|
<Slider class="size-slider" :min="20" :max="200" :step="20" v-model:value="rubberSize" />
|
||||||
</div>
|
</div>
|
||||||
@ -70,7 +88,7 @@
|
|||||||
<div class="colors">
|
<div class="colors">
|
||||||
<div
|
<div
|
||||||
class="color"
|
class="color"
|
||||||
:class="{ 'active': color === writingBoardColor }"
|
:class="{ 'active': color === writingBoardColor, 'white': color === '#ffffff' }"
|
||||||
v-for="color in writingBoardColors"
|
v-for="color in writingBoardColors"
|
||||||
:key="color"
|
:key="color"
|
||||||
:style="{ backgroundColor: color }"
|
:style="{ backgroundColor: color }"
|
||||||
@ -78,7 +96,7 @@
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn" v-tooltip="'关闭画笔'" @click="closeWritingBoard()">
|
<div class="btn close" v-tooltip="'关闭画笔'" @click="closeWritingBoard()">
|
||||||
<IconClose class="icon" />
|
<IconClose class="icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -96,10 +114,11 @@ import WritingBoard from '@/components/WritingBoard.vue'
|
|||||||
import MoveablePanel from '@/components/MoveablePanel.vue'
|
import MoveablePanel from '@/components/MoveablePanel.vue'
|
||||||
import Slider from '@/components/Slider.vue'
|
import Slider from '@/components/Slider.vue'
|
||||||
import Popover from '@/components/Popover.vue'
|
import Popover from '@/components/Popover.vue'
|
||||||
|
import Divider from '@/components//Divider.vue'
|
||||||
|
|
||||||
const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c', '#ffff3a']
|
const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c', '#ffff3a']
|
||||||
|
|
||||||
type WritingBoardModel = 'pen' | 'mark' | 'eraser'
|
type WritingBoardModel = 'pen' | 'mark' | 'eraser' | 'shape'
|
||||||
|
|
||||||
withDefaults(defineProps<{
|
withDefaults(defineProps<{
|
||||||
slideWidth: number
|
slideWidth: number
|
||||||
@ -122,10 +141,12 @@ const writingBoardColor = ref('#e2534d')
|
|||||||
const writingBoardModel = ref<WritingBoardModel>('pen')
|
const writingBoardModel = ref<WritingBoardModel>('pen')
|
||||||
const blackboard = ref(false)
|
const blackboard = ref(false)
|
||||||
const sizePopoverType = ref<'' | WritingBoardModel>('')
|
const sizePopoverType = ref<'' | WritingBoardModel>('')
|
||||||
|
const shapeType = ref<'rect' | 'circle' | 'arrow'>('rect')
|
||||||
|
|
||||||
const penSize = ref(6)
|
const penSize = ref(6)
|
||||||
const markSize = ref(24)
|
const markSize = ref(24)
|
||||||
const rubberSize = ref(80)
|
const rubberSize = ref(80)
|
||||||
|
const shapeSize = ref(4)
|
||||||
|
|
||||||
const changeModel = (model: WritingBoardModel) => {
|
const changeModel = (model: WritingBoardModel) => {
|
||||||
if (writingBoardModel.value === model) {
|
if (writingBoardModel.value === model) {
|
||||||
@ -199,7 +220,9 @@ const hanldeWritingEnd = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
padding: 5px 10px;
|
padding: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: $borderRadius;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -209,13 +232,17 @@ const hanldeWritingEnd = () => {
|
|||||||
background-color: rgba($color: $themeColor, $alpha: .5);
|
background-color: rgba($color: $themeColor, $alpha: .5);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
&.close {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
.colors {
|
.colors {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0 10px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
.color {
|
.color {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
@ -229,19 +256,44 @@ const hanldeWritingEnd = () => {
|
|||||||
&.active {
|
&.active {
|
||||||
transform: scale(1.3);
|
transform: scale(1.3);
|
||||||
}
|
}
|
||||||
|
&.white {
|
||||||
|
border: 1px solid #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
& + .color {
|
& + .color {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.size {
|
.setting {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|
||||||
|
&.shape {
|
||||||
|
width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shapes {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
& + .icon {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $themeColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user