Compare commits
No commits in common. "430e1999bb00e010fad50e324a6c02fcd40e815f" and "71320e2656f393b4e452825aba8d66de4d6a3bbb" have entirely different histories.
430e1999bb
...
71320e2656
|
|
@ -32,7 +32,6 @@
|
||||||
"v-viewer": "^3.0.13",
|
"v-viewer": "^3.0.13",
|
||||||
"viewerjs": "^1.11.6",
|
"viewerjs": "^1.11.6",
|
||||||
"vue": "^3.4.29",
|
"vue": "^3.4.29",
|
||||||
"vue-cropper": "^1.1.4",
|
|
||||||
"vue-toastification": "^2.0.0-rc.5",
|
"vue-toastification": "^2.0.0-rc.5",
|
||||||
"vue3-colorpicker": "^2.3.0"
|
"vue3-colorpicker": "^2.3.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import type { Block } from '../layout.types'
|
||||||
import { ColorPicker } from 'vue3-colorpicker'
|
import { ColorPicker } from 'vue3-colorpicker'
|
||||||
import 'vue3-colorpicker/style.css'
|
import 'vue3-colorpicker/style.css'
|
||||||
import { globalToast } from '@/main'
|
import { globalToast } from '@/main'
|
||||||
import UploadAndCut from '@/utils/UploadAndCut'
|
|
||||||
import { AddToToken } from './AdderPage'
|
import { AddToToken } from './AdderPage'
|
||||||
|
|
||||||
addIcons(MdUpload, MdImage, MdCheck)
|
addIcons(MdUpload, MdImage, MdCheck)
|
||||||
|
|
@ -78,7 +77,7 @@ const TypeSelector = defineComponent({
|
||||||
<div
|
<div
|
||||||
class="w-[44px] relative h-[44px] bg-center bg-no-repeat bg-cover rounded-lg overflow-hidden flex justify-center items-center cursor-pointer hover:scale-105 transition-all"
|
class="w-[44px] relative h-[44px] bg-center bg-no-repeat bg-cover rounded-lg overflow-hidden flex justify-center items-center cursor-pointer hover:scale-105 transition-all"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: props.background || 'transparent'
|
backgroundColor: props.background
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
ctx.emit('update:value', 1)
|
ctx.emit('update:value', 1)
|
||||||
|
|
@ -107,17 +106,13 @@ const TypeSelector = defineComponent({
|
||||||
<span class={'text-[12px]'}>文字</span>
|
<span class={'text-[12px]'}>文字</span>
|
||||||
</div>
|
</div>
|
||||||
<div class={'flex justify-center flex-col items-center gap-y-1'}>
|
<div class={'flex justify-center flex-col items-center gap-y-1'}>
|
||||||
<div class="w-[44px] h-[44px] rounded-lg flex overflow-hidden justify-center items-center bg-white shadow cursor-pointer hover:scale-105 transition-all">
|
<div class="w-[44px] h-[44px] rounded-lg flex justify-center items-center bg-white shadow cursor-pointer hover:scale-105 transition-all">
|
||||||
{/* <ImageUploader
|
<ImageUploader
|
||||||
width={44}
|
width={44}
|
||||||
onUpdate:value={(e) => {
|
onUpdate:value={(e) => {
|
||||||
ctx.emit('update:icon', e)
|
ctx.emit('update:icon', e)
|
||||||
}}
|
}}
|
||||||
></ImageUploader> */}
|
></ImageUploader>
|
||||||
<UploadAndCut onUpdate:value={(e)=> {
|
|
||||||
ctx.emit('update:icon', e)
|
|
||||||
|
|
||||||
}}></UploadAndCut>
|
|
||||||
</div>
|
</div>
|
||||||
<span class={'text-[12px]'}>自定义</span>
|
<span class={'text-[12px]'}>自定义</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
import clsx from "clsx";
|
|
||||||
import { computed } from "vue";
|
|
||||||
import { defineComponent } from "vue";
|
|
||||||
import { MdCheck } from "oh-vue-icons/icons";
|
|
||||||
import { addIcons, OhVueIcon } from "oh-vue-icons";
|
|
||||||
addIcons(MdCheck)
|
|
||||||
export default defineComponent({
|
|
||||||
name: "NativeColorPicker",
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
colorList: {
|
|
||||||
type: Array<string>
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
transparent: {
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
firstColor: {
|
|
||||||
type: String,
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
"update:value": (_value: string) => true,
|
|
||||||
},
|
|
||||||
setup(props, context) {
|
|
||||||
const firstColor = props.value
|
|
||||||
const colorList = computed(() => {
|
|
||||||
let list = [
|
|
||||||
'#ffffff',
|
|
||||||
'#000000',
|
|
||||||
'#FA9B3F',
|
|
||||||
'#333333',
|
|
||||||
'#6D7278',
|
|
||||||
'#D8D8D8',
|
|
||||||
'#0091FF',
|
|
||||||
'#B620E0',
|
|
||||||
'#F31260'
|
|
||||||
]
|
|
||||||
if (props.colorList) {
|
|
||||||
list = props.colorList
|
|
||||||
}
|
|
||||||
if (props.transparent) {
|
|
||||||
list.push('transparent')
|
|
||||||
}
|
|
||||||
if (!list.includes(firstColor)) {
|
|
||||||
list.unshift(firstColor)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
})
|
|
||||||
return () => <div class={clsx("flex items-center gap-x-2 ", props.class)}>
|
|
||||||
{
|
|
||||||
colorList.value.map((item, index) => < div
|
|
||||||
key={index}
|
|
||||||
onClick={() => context.emit('update:value', item)}
|
|
||||||
class="text-[12px] cursor-pointer w-[20px] h-[20px] shadow-[0_0_2px_#999] rounded-full"
|
|
||||||
style={{
|
|
||||||
backgroundColor: item === 'transparent' ? '' : item,
|
|
||||||
backgroundImage:
|
|
||||||
item === 'transparent'
|
|
||||||
? `linear-gradient(45deg, rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%,rgba(0, 0, 0, 0.4) 75%),
|
|
||||||
linear-gradient(45deg,rgba(0, 0, 0, 0.4) 25%, white 25%, transparent 75%, rgba(0, 0, 0, 0.4) 75%)`
|
|
||||||
: '',
|
|
||||||
backgroundPosition: item === 'transparent' ? '0 0, 2px 2px' : '',
|
|
||||||
backgroundSize: item === 'transparent' ? '4px 4px' : ''
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* <Checkmark16Filled
|
|
||||||
class="text-[#888]"
|
|
||||||
: class="props.modelValue === item ? '' : 'hidden'"
|
|
||||||
: style="{
|
|
||||||
color: selectColor
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</Checkmark16Filled> */}
|
|
||||||
{
|
|
||||||
props.value === item &&
|
|
||||||
<OhVueIcon class="text-[#888]" name={MdCheck.name} ></OhVueIcon>
|
|
||||||
|
|
||||||
}
|
|
||||||
</div >)
|
|
||||||
}
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="text-[12px] cursor-pointer w-[20px] h-[20px] shadow-[0_0_2px_#999] rounded-full relative"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="w-full h-full rounded-full cursor-pointer"
|
|
||||||
style="background: conic-gradient(#dd0010, yellow, green, #0091ff, red)"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
|
|
||||||
onInput={(e: any)=> {
|
|
||||||
context.emit('update:value', e?.target.value)
|
|
||||||
}}
|
|
||||||
ref="inputRef"
|
|
||||||
type="color"
|
|
||||||
style="opacity: 0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div >
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
import { Modal } from 'ant-design-vue'
|
|
||||||
import { defineComponent, ref, watch } from 'vue'
|
|
||||||
import { VueCropper } from 'vue-cropper'
|
|
||||||
import 'vue-cropper/dist/index.css'
|
|
||||||
import upload from './upload'
|
|
||||||
import { v4 as uuid } from "uuid"
|
|
||||||
import { MdCroprotateRound, BiPlusLg } from "oh-vue-icons/icons";
|
|
||||||
import { OhVueIcon, addIcons, } from 'oh-vue-icons'
|
|
||||||
import NativeColorPicker from './NativeColorPicker'
|
|
||||||
addIcons(MdCroprotateRound, BiPlusLg)
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
|
|
||||||
emits: {
|
|
||||||
'update:value': (() => true) as (val: string) => boolean
|
|
||||||
},
|
|
||||||
setup(props, ctx) {
|
|
||||||
const inputRef = ref<HTMLInputElement | null>(null)
|
|
||||||
const showCutModel = ref(false)
|
|
||||||
const originFile = ref('')
|
|
||||||
const fillColor = ref('transparent')
|
|
||||||
const cropper = ref<any>(null)
|
|
||||||
const handleFile = (e: any) => {
|
|
||||||
const target = e.target as HTMLInputElement
|
|
||||||
|
|
||||||
const file = target.files?.[0]
|
|
||||||
target.value = ''
|
|
||||||
console.log(file?.name);
|
|
||||||
|
|
||||||
if (!file) return
|
|
||||||
// upload(file).then(res => {
|
|
||||||
const reader = new FileReader()
|
|
||||||
reader.readAsDataURL(file)
|
|
||||||
reader.onload = (e: any) => {
|
|
||||||
originFile.value = e?.target.result // 显示原始图片
|
|
||||||
showCutModel.value = true
|
|
||||||
}
|
|
||||||
// emit('update:icon', res || '')
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
const handleFinish = (blob: any) => {
|
|
||||||
// 根据前几个字节推测文件类型(这里只考虑常见的图片类型)
|
|
||||||
|
|
||||||
// 使用 FileReader 对象读取 Blob 的前几个字节
|
|
||||||
const reader = new FileReader()
|
|
||||||
reader.onloadend = function () {
|
|
||||||
// 打印 File 对象以验证
|
|
||||||
|
|
||||||
const fileData = new File([blob], `${uuid()}.png`, {
|
|
||||||
type: 'image/jpg',
|
|
||||||
lastModified: Date.now()
|
|
||||||
})
|
|
||||||
upload(fileData, 'customIcon').then((res) => {
|
|
||||||
showCutModel.value = false
|
|
||||||
|
|
||||||
ctx.emit('update:value', res || '')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
reader.readAsArrayBuffer(blob)
|
|
||||||
}
|
|
||||||
watch(
|
|
||||||
fillColor,
|
|
||||||
(e: string) => {
|
|
||||||
const elements = document.querySelectorAll('.cropper-crop-box')
|
|
||||||
elements.forEach((element: any) => {
|
|
||||||
element.style.backgroundColor = e // 修改颜色为蓝色
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return () => (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
open={showCutModel.value}
|
|
||||||
onCancel={() => showCutModel.value = false}
|
|
||||||
onOk={() => {
|
|
||||||
cropper.value.getCropBlob((blob: any) => {
|
|
||||||
handleFinish(blob)
|
|
||||||
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div class="w-full flex flex-col items-center gap-y-2">
|
|
||||||
<div class="w-[250px] h-[250px]" style={{
|
|
||||||
backgroundColor: fillColor.value || 'transparent',
|
|
||||||
}}>
|
|
||||||
<VueCropper
|
|
||||||
ref={cropper}
|
|
||||||
autoCropWidth="250px"
|
|
||||||
autoCropHeight="250px"
|
|
||||||
mode="contain"
|
|
||||||
outputType="png"
|
|
||||||
img={originFile.value}
|
|
||||||
autoCrop={true}
|
|
||||||
fillColor={fillColor.value}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between w-[250px]">
|
|
||||||
{/* <ArrowRotateClockwise24Regular
|
|
||||||
class="text-[10px] w-8 h-8 cursor-pointer"
|
|
||||||
onClick={() => ($refs.cropper as any).rotateRight()}
|
|
||||||
/> */}
|
|
||||||
<span class="flex items-center cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
cropper.value.rotateRight()
|
|
||||||
}}>
|
|
||||||
<OhVueIcon name="md-croprotate-round" scale={1} fill="#707070" ></OhVueIcon>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
<span class="flex items-center gap-x-1">
|
|
||||||
<svg
|
|
||||||
onClick={() => cropper.value?.changeScale(1)}
|
|
||||||
class="icon cursor-pointer"
|
|
||||||
viewBox="0 0 1024 1024"
|
|
||||||
width="2rem"
|
|
||||||
height="2rem"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M886.51776 799.66208l-139.93984-139.93984c-10.50624-10.50624-23.90016-16.13824-37.60128-17.44896 42.16832-52.59264 67.54304-119.1936 67.54304-191.6928 0-169.39008-137.80992-307.2-307.2-307.2s-307.2 137.80992-307.2 307.2 137.80992 307.2 307.2 307.2c63.91808 0 123.31008-19.6608 172.52352-53.18656 0.34816 15.23712 6.22592 30.37184 17.85856 42.00448l139.93984 139.93984c11.9808 12.00128 27.72992 18.00192 43.43808 18.00192s31.45728-6.00064 43.43808-18.00192C910.52032 862.55616 910.52032 823.66464 886.51776 799.66208zM469.31968 655.38048c-112.92672 0-204.8-91.87328-204.8-204.8s91.87328-204.8 204.8-204.8 204.8 91.87328 204.8 204.8S582.2464 655.38048 469.31968 655.38048zM610.14016 450.58048c0 22.60992-18.35008 40.96-40.96 40.96l-56.32 0 0 56.32c0 22.60992-18.35008 40.96-40.96 40.96s-40.96-18.35008-40.96-40.96l0-56.32-56.32 0c-22.60992 0-40.96-18.35008-40.96-40.96s18.35008-40.96 40.96-40.96l56.32 0 0-56.32c0-22.60992 18.35008-40.96 40.96-40.96s40.96 18.35008 40.96 40.96l0 56.32 56.32 0C591.79008 409.62048 610.14016 427.95008 610.14016 450.58048z"
|
|
||||||
fill="#707070"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
onClick={() => cropper.value?.changeScale(-1)}
|
|
||||||
class="icon cursor-pointer"
|
|
||||||
viewBox="0 0 1024 1024"
|
|
||||||
width="2rem"
|
|
||||||
height="2rem"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M886.51776 799.66208l-139.93984-139.93984c-10.50624-10.50624-23.90016-16.13824-37.60128-17.44896 42.16832-52.59264 67.54304-119.1936 67.54304-191.6928 0-169.39008-137.80992-307.2-307.2-307.2s-307.2 137.80992-307.2 307.2 137.80992 307.2 307.2 307.2c63.91808 0 123.31008-19.6608 172.52352-53.18656 0.34816 15.23712 6.22592 30.37184 17.85856 42.00448l139.93984 139.93984c11.9808 12.00128 27.72992 18.00192 43.43808 18.00192s31.45728-6.00064 43.43808-18.00192C910.52032 862.55616 910.52032 823.66464 886.51776 799.66208zM469.31968 655.38048c-112.92672 0-204.8-91.87328-204.8-204.8s91.87328-204.8 204.8-204.8 204.8 91.87328 204.8 204.8S582.2464 655.38048 469.31968 655.38048zM610.14016 450.58048c0 22.60992-18.35008 40.96-40.96 40.96l-194.56 0c-22.60992 0-40.96-18.35008-40.96-40.96s18.35008-40.96 40.96-40.96l194.56 0C591.79008 409.62048 610.14016 427.95008 610.14016 450.58048z"
|
|
||||||
fill="#707070"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<NativeColorPicker value={fillColor.value} onUpdate:value={e => fillColor.value = e} transparent={true} />
|
|
||||||
{/* {props.colorList && (
|
|
||||||
<div class="w-[250px] flex justify-center">
|
|
||||||
<NativeColorPicker
|
|
||||||
colorList={colorList}
|
|
||||||
v-model={fillColor}
|
|
||||||
onUpdate:modelValue={(e) => { }}
|
|
||||||
transparent={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</Modal >
|
|
||||||
<div class="w-full h-full bg-white flex items-center justify-center"
|
|
||||||
onClick={() => {
|
|
||||||
inputRef.value?.click?.()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<OhVueIcon name={BiPlusLg.name} fill='#666666' scale={2}></OhVueIcon>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
ref={inputRef}
|
|
||||||
style={{
|
|
||||||
display: 'none'
|
|
||||||
}} accept=".jpg,.jpeg,.png,.svg" type="file" onChange={handleFile} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue