|
@@ -8,33 +8,31 @@
|
|
|
<div class="color-title">{{ $t('editorPanel.fontColor') }}</div>
|
|
|
<div class="colors-container">
|
|
|
<span class="cell-container">
|
|
|
- <span class="cell-outer" :class="{ active: property.color === 'rgb(255, 0, 0)' }" @click="setActiveToolColor({ R: 255, G: 0, B: 0})">
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(property.color, 'rgb(255, 0, 0)') }" @click="setActiveToolColor('rgb(255, 0, 0)')">
|
|
|
<span class="cell red"></span>
|
|
|
</span>
|
|
|
</span>
|
|
|
<span class="cell-container">
|
|
|
- <span class="cell-outer" :class="{ active: property.color === 'rgb(255, 236, 102)' }" @click="setActiveToolColor({ R: 255, G: 236, B: 102})">
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(property.color, 'rgb(255, 236, 102)') }" @click="setActiveToolColor('rgb(255, 236, 102)')">
|
|
|
<span class="cell yellow"></span>
|
|
|
</span>
|
|
|
</span>
|
|
|
<span class="cell-container">
|
|
|
- <span class="cell-outer" :class="{ active: property.color === 'rgb(45, 119, 250)' }" @click="setActiveToolColor({ R: 45, G: 119, B: 250})">
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(property.color, 'rgb(45, 119, 250)') }" @click="setActiveToolColor('rgb(45, 119, 250)')">
|
|
|
<span class="cell blue"></span>
|
|
|
</span>
|
|
|
</span>
|
|
|
<div class="color-picker">
|
|
|
+ <div class="preview" :style="{ backgroundColor: colorPickerValue }"></div>
|
|
|
<n-color-picker
|
|
|
to="#editorPanel"
|
|
|
@complete="onColorPickerComplete"
|
|
|
- @update:show="onColorPickerShow"
|
|
|
- @update:value="onColorPickerValue"
|
|
|
+ @update:value="onColorPickerUpdate"
|
|
|
:value="colorPickerValue"
|
|
|
:show-alpha="false"
|
|
|
- :class="{ active: isColorPickerShow || property.color === colorPickerValue }"
|
|
|
>
|
|
|
- <template #label></template>
|
|
|
+ <template #label><img src="../Icon/colorful.svg" alt="colorPicker"></template>
|
|
|
</n-color-picker>
|
|
|
- <Colorful />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -147,6 +145,7 @@
|
|
|
import { useViewerStore } from '@/stores/modules/viewer'
|
|
|
import { NSlider, NSelect, NColorPicker } from 'naive-ui'
|
|
|
import core from '@/core'
|
|
|
+ import { areColorsSimilar } from '@/helpers/utils'
|
|
|
|
|
|
const useViewer = useViewerStore()
|
|
|
const instance = getCurrentInstance().appContext.app.config.globalProperties
|
|
@@ -224,7 +223,6 @@
|
|
|
const rightPanelButtonDisabled = computed(() => useViewer.getRightPanelButtonDisabled)
|
|
|
|
|
|
const imageUrl = ref('')
|
|
|
- const isColorPickerShow = ref(false)
|
|
|
const colorPickerValue = ref('rgb(0, 0, 0)')
|
|
|
|
|
|
// 打开右侧属性面板时,关闭视图面板
|
|
@@ -258,7 +256,7 @@
|
|
|
})
|
|
|
|
|
|
const setActiveToolColor = (color) => {
|
|
|
- property.color = `rgb(${color.R}, ${color.G}, ${color.B})`
|
|
|
+ property.color = color
|
|
|
core.setContentEditorProperty(type.value, { color })
|
|
|
}
|
|
|
|
|
@@ -308,88 +306,14 @@
|
|
|
|
|
|
// 颜色选择器选中颜色事件
|
|
|
const onColorPickerComplete = (value) => {
|
|
|
- if (value === property.color) {
|
|
|
- colorPickerValue.value = value
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- const color = convertColor(value)
|
|
|
- if (color) {
|
|
|
- setActiveToolColor(color)
|
|
|
- colorPickerValue.value = `rgb(${color.R}, ${color.G}, ${color.B})`
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 颜色选择器打开或关闭事件
|
|
|
- const onColorPickerShow = (value) => {
|
|
|
- isColorPickerShow.value = value
|
|
|
+ if (areColorsSimilar(value, property.color)) return
|
|
|
+ setActiveToolColor(value)
|
|
|
}
|
|
|
|
|
|
// 颜色选择器颜色改变事件
|
|
|
- const onColorPickerValue = (value) => {
|
|
|
+ const onColorPickerUpdate = (value) => {
|
|
|
colorPickerValue.value = value
|
|
|
}
|
|
|
-
|
|
|
- const hslToRgb = (h, s, l) => {
|
|
|
- let R, G, B;
|
|
|
-
|
|
|
- if (s === 0) {
|
|
|
- R = G = B = l; // achromatic
|
|
|
- } else {
|
|
|
- const hue2rgb = function hue2rgb(p, q, t) {
|
|
|
- if (t < 0) t += 1;
|
|
|
- if (t > 1) t -= 1;
|
|
|
- if (t < 1 / 6) return p + (q - p) * 6 * t;
|
|
|
- if (t < 1 / 2) return q;
|
|
|
- if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
|
|
- return p;
|
|
|
- }
|
|
|
-
|
|
|
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
|
- const p = 2 * l - q;
|
|
|
- R = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
|
|
|
- G = Math.round(hue2rgb(p, q, h) * 255);
|
|
|
- B = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
|
|
|
- }
|
|
|
-
|
|
|
- return {R, G, B};
|
|
|
- }
|
|
|
-
|
|
|
- // 转换颜色 hsl / hex -> rgb
|
|
|
- const convertColor = (colorStr) => {
|
|
|
- if (colorStr.startsWith('#')) {
|
|
|
- const hexValues = colorStr.slice(1).match(/.{2}/g);
|
|
|
- if (hexValues) {
|
|
|
- return {
|
|
|
- R: parseInt(hexValues[0], 16),
|
|
|
- G: parseInt(hexValues[1], 16),
|
|
|
- B: parseInt(hexValues[2], 16)
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (colorStr.startsWith('rgb')) {
|
|
|
- const matches = colorStr.match(/\d+/g);
|
|
|
- if (matches && matches.length === 3) {
|
|
|
- return {
|
|
|
- R: matches[0],
|
|
|
- G: matches[1],
|
|
|
- B: matches[2]
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (colorStr.startsWith('hsl')) {
|
|
|
- const matches = colorStr.match(/(\d+),\s*(\d+%),\s*(\d+%)/);
|
|
|
- if (matches) {
|
|
|
- const [h, s, l] = [parseInt(matches[1]), parseInt(matches[2]) / 100, parseInt(matches[3]) / 100];
|
|
|
- const {R, G, B} = hslToRgb(h / 360, s, l);
|
|
|
- return {R, G, B};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -400,7 +324,6 @@
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
height: calc(100% - 88px);
|
|
|
- overflow: hidden;
|
|
|
transition: transform .3s ease-in-out;
|
|
|
background-color: var(--c-side-bg);
|
|
|
border-left: 1px solid var(--c-side-header-border);
|
|
@@ -469,18 +392,6 @@
|
|
|
.cell-container + .cell-container {
|
|
|
margin-left: 8px;
|
|
|
}
|
|
|
-
|
|
|
- .color-picker {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-left: 8px;
|
|
|
- border: 1px solid #0000001F;
|
|
|
- border-radius: 20px;
|
|
|
-
|
|
|
- svg {
|
|
|
- margin: 3px;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -741,10 +652,6 @@
|
|
|
@media screen and (min-width: 641px) {
|
|
|
.editor-panel {
|
|
|
width: 260px;
|
|
|
-
|
|
|
- ::v-deep(.v-binder-follower-content) {
|
|
|
- transform: translate(10px, 122px) !important;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
</style>
|
|
@@ -773,31 +680,68 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ .color-picker {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-left: 8px;
|
|
|
+ padding: 0 3px;
|
|
|
+ border: 1px solid #0000001F;
|
|
|
+ border-radius: 20px;
|
|
|
+
|
|
|
+ .preview {
|
|
|
+ margin-right: 8px;
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ background-color: #000000;
|
|
|
+ border-radius: 50%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.n-color-picker {
|
|
|
- margin-left: 1px;
|
|
|
- width: 28px;
|
|
|
- height: 28px;
|
|
|
- cursor: auto;
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
|
|
|
.n-color-picker-trigger {
|
|
|
border-radius: 50%;
|
|
|
- cursor: pointer;
|
|
|
border: none;
|
|
|
|
|
|
.n-color-picker-trigger__fill {
|
|
|
border-radius: 50%;
|
|
|
overflow: hidden;
|
|
|
- left: 3px;
|
|
|
- right: 3px;
|
|
|
- top: 3px;
|
|
|
- bottom: 3px;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+
|
|
|
+ div {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .n-color-picker-trigger__value {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ position: unset;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &.active {
|
|
|
- .n-color-picker-trigger {
|
|
|
- border: 1px solid #1460F3;
|
|
|
+ .n-input {
|
|
|
+
|
|
|
+ &:not(.n-input--disabled) {
|
|
|
+
|
|
|
+ &:hover .n-input__state-border {
|
|
|
+ border-color: var(--c-blue-1);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.n-input--focus .n-input__state-border {
|
|
|
+ border-color: var(--c-blue-1);
|
|
|
+ box-shadow: 0 0 0 2px var(--c-right-side-list-item-bg);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .n-input__input-el {
|
|
|
+ caret-color: var(--c-blue-1);
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|