feat: 移植截图中心(浏览/分组/编辑/导出)
This commit is contained in:
1 parent
300df18aca
commit
b5406c2da0
34 files changed
+7954
-1124
No files matched your search
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
CircleIcon,
|
||||
CropIcon,
|
||||
EraserIcon,
|
||||
EyeOffIcon,
|
||||
HighlighterIcon,
|
||||
MousePointer2Icon,
|
||||
MoveUpRightIcon,
|
||||
PencilIcon,
|
||||
SquareIcon,
|
||||
TypeIcon,
|
||||
} from '@modrinth/assets'
|
||||
|
||||
import IconButton from '#ui/components/base/buttons/IconButton.vue'
|
||||
import { useVIntl } from '#ui/composables/i18n'
|
||||
|
||||
import { imageViewerEditorMessages as messages } from './image-viewer-editor-messages'
|
||||
import type { ScreenshotEditorTool } from './image-viewer-editor-types'
|
||||
|
||||
const props = defineProps<{
|
||||
tool: ScreenshotEditorTool
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [tool: ScreenshotEditorTool]
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const toolGroups = [
|
||||
[
|
||||
{ id: 'select', message: messages.select, icon: MousePointer2Icon, shortcut: 'V' },
|
||||
{ id: 'crop', message: messages.crop, icon: CropIcon, shortcut: 'K' },
|
||||
],
|
||||
[
|
||||
{ id: 'pen', message: messages.pen, icon: PencilIcon, shortcut: 'P' },
|
||||
{ id: 'highlight', message: messages.highlight, icon: HighlighterIcon, shortcut: 'H' },
|
||||
{ id: 'eraser', message: messages.eraser, icon: EraserIcon, shortcut: 'E' },
|
||||
],
|
||||
[
|
||||
{ id: 'arrow', message: messages.arrow, icon: MoveUpRightIcon, shortcut: 'A' },
|
||||
{ id: 'rectangle', message: messages.rectangle, icon: SquareIcon, shortcut: 'R' },
|
||||
{ id: 'ellipse', message: messages.ellipse, icon: CircleIcon, shortcut: 'O' },
|
||||
],
|
||||
[
|
||||
{ id: 'text', message: messages.text, icon: TypeIcon, shortcut: 'T' },
|
||||
{ id: 'censor', message: messages.censor, icon: EyeOffIcon, shortcut: 'C' },
|
||||
],
|
||||
] satisfies Array<
|
||||
Array<{
|
||||
id: ScreenshotEditorTool
|
||||
message: (typeof messages)[keyof typeof messages]
|
||||
icon: typeof MousePointer2Icon
|
||||
shortcut: string
|
||||
}>
|
||||
>
|
||||
|
||||
function tooltip(groupIndex: number, toolIndex: number) {
|
||||
const option = toolGroups[groupIndex]?.[toolIndex]
|
||||
return option ? `${formatMessage(option.message)} (${option.shortcut})` : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="absolute left-6 top-1/2 z-10 flex -translate-y-1/2 flex-col items-center gap-2 rounded-[20px] border border-solid border-white/10 bg-surface-3 px-3 py-2.5 shadow-[0_1rem_3rem_rgb(0_0_0_/_32%)] max-[900px]:bottom-[5.25rem] max-[900px]:left-1/2 max-[900px]:top-auto max-[900px]:-translate-x-1/2 max-[900px]:translate-y-0 max-[900px]:flex-row"
|
||||
role="toolbar"
|
||||
:aria-label="formatMessage(messages.annotationTools)"
|
||||
@click.stop
|
||||
>
|
||||
<template v-for="(group, groupIndex) in toolGroups" :key="group[0]?.id">
|
||||
<div v-if="groupIndex > 0" class="h-px w-6 bg-white/10 max-[900px]:h-6 max-[900px]:w-px" />
|
||||
<IconButton
|
||||
v-for="(option, toolIndex) in group"
|
||||
:key="option.id"
|
||||
v-tooltip="tooltip(groupIndex, toolIndex)"
|
||||
:label="formatMessage(option.message)"
|
||||
type="quiet"
|
||||
:color="props.tool === option.id ? 'brand' : undefined"
|
||||
:class="{
|
||||
'!bg-brand-highlight shadow-[inset_0_0_0_1px_var(--color-brand)]':
|
||||
props.tool === option.id,
|
||||
}"
|
||||
:aria-pressed="props.tool === option.id"
|
||||
@click="emit('select', option.id)"
|
||||
>
|
||||
<component :is="option.icon" />
|
||||
</IconButton>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user