Skip to content

Commit e169fb3

Browse files
committed
feat: resize
1 parent 26de6f2 commit e169fb3

File tree

10 files changed

+95
-18
lines changed

10 files changed

+95
-18
lines changed

src/app/page.tsx

+17-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,18 @@ import { useThemeStore } from '@/store/use-theme-store'
2525

2626
export default function Home() {
2727
const [contents, setContents] = useState<ContentWithId[]>([])
28-
const { templateName, setTemplateName, theme, setTheme, templateMap, themeMap } = useThemeStore()
28+
const {
29+
templateName,
30+
setTemplateName,
31+
theme,
32+
setTheme,
33+
templateMap,
34+
themeMap,
35+
size,
36+
setSize,
37+
sizeName,
38+
setSizeName,
39+
} = useThemeStore()
2940
const [cssVariables, setCssVariables] = useState({})
3041
const [tabValue, setTabValue] = useState('workspace')
3142
const { toast } = useToast()
@@ -169,6 +180,9 @@ export default function Home() {
169180
theme={theme}
170181
setTheme={setTheme}
171182
setTableValue={setTabValue}
183+
sizeName={sizeName}
184+
setSize={setSize}
185+
setSizeName={setSizeName}
172186
/>
173187
<main className="h-[calc(100%-58px)]">
174188
<Tabs
@@ -183,10 +197,8 @@ export default function Home() {
183197
<TabsTrigger value="preview">预览</TabsTrigger>
184198
</TabsList>
185199
<TabsContent value="preview" forceMount className="data-[state=inactive]:hidden sm:!block flex-grow sm:flex-grow-0 flex-shrink sm:flex-shrink-0 overflow-y-auto mt-0">
186-
<div
187-
className={
188-
cn('one scroll-smooth h-full mx-auto w-[375px]')
189-
}>
200+
{/* 根据实际像素比,缩小3倍,保证正常预览。导出图片时放大三倍,可还原实际像素比 */}
201+
<div style={{ width: `${size.width / 3}px` }} className={cn('one scroll-smooth h-full mx-auto w-[375px]')}>
190202
<Preview ref={previewRef} contents={contents} className="w-full flex flex-col m-auto" />
191203
</div>
192204
</TabsContent>

src/components/header/header.tsx

+35-4
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ import {
1818
} from '@/components/ui/dialog'
1919
import { Input } from '@/components/ui/input'
2020
import { Logo } from '@/components/logo'
21-
import type { Content, ContentWithId, PreviewRef } from '@/types'
21+
import type { Content, ContentWithId, PreviewRef, Size } from '@/types'
2222
import type { ExportContent, ExportJSON } from '@/components/header/types'
2323
import {
24+
CACHE_KEY_SIZE,
25+
CACHE_KEY_SIZE_NAME,
2426
CACHE_KEY_TEMPLATE, CACHE_KEY_THEME,
2527
addAllContents,
2628
cn,
@@ -49,6 +51,8 @@ import {
4951
SelectValue,
5052
} from '@/components/ui/select'
5153
import {
54+
DEFAULT_SIZE_MAP,
55+
DEFAULT_SIZE_NAMES,
5256
DEFAULT_TEMPLATE,
5357
DEFAULT_TEMPLATES,
5458
DEFAULT_THEME,
@@ -58,10 +62,14 @@ import { usePlatform } from '@/hooks/use-platform'
5862

5963
interface HeaderProps {
6064
contents: Content[];
61-
setContents: (contents: ContentWithId[]) => void;
6265
previewRef: React.RefObject<PreviewRef>;
6366
templateName: string;
6467
theme: string;
68+
size?: Size;
69+
sizeName: string;
70+
setSize: (size: Size) => void;
71+
setSizeName: (sizeName: string) => void;
72+
setContents: (contents: ContentWithId[]) => void;
6573
setTemplateName: (template: string) => void;
6674
setTheme: (color: string) => void
6775
setTableValue?: (tab: string) => void
@@ -76,7 +84,7 @@ export function Header(props: HeaderProps) {
7684
const [isExporting, setIsExporting] = useState(true)
7785
const [scale, setScale] = useState('3')
7886
const platform = usePlatform()
79-
const { contents, setContents, previewRef, templateName, theme, setTemplateName, setTheme, setTableValue } = props
87+
const { contents, setContents, previewRef, templateName, theme, setTemplateName, setTheme, setTableValue, sizeName, setSizeName, setSize } = props
8088
const { toast } = useToast()
8189
const fileRef = useRef<HTMLInputElement>(null)
8290

@@ -390,7 +398,7 @@ export function Header(props: HeaderProps) {
390398
</SelectGroup>
391399
</SelectContent >
392400
</Select >
393-
</div >
401+
</div>
394402
<div className="px-1.5 py-2 text-sm">
395403
<div className="mb-2">模版色</div>
396404
<div>
@@ -412,6 +420,29 @@ export function Header(props: HeaderProps) {
412420
</MenubarContent >
413421
</MenubarMenu >
414422
</Menubar >
423+
<Select defaultValue="default" value={sizeName} onValueChange={(value: string) => {
424+
const size = DEFAULT_SIZE_MAP[value]
425+
setSizeName(value)
426+
setSize(size)
427+
localStorage.setItem(CACHE_KEY_SIZE, JSON.stringify(size))
428+
localStorage.setItem(CACHE_KEY_SIZE_NAME, sizeName)
429+
}}>
430+
<SelectTrigger className="h-8 w-[146px]">
431+
<SelectValue className="text-muted-foreground" placeholder="调整尺寸" />
432+
</SelectTrigger>
433+
<SelectContent>
434+
<SelectGroup>
435+
{
436+
DEFAULT_SIZE_NAMES.map(size => (
437+
<SelectItem key={size.value} value={size.value} disabled={size.disabled}>
438+
{size.label}
439+
{/* <p className="text-xs">{size.description}</p> */}
440+
</SelectItem>
441+
))
442+
}
443+
</SelectGroup>
444+
</SelectContent >
445+
</Select >
415446
<div className="flex flex-wrap gap-2 ml-auto">
416447
<Button size="sm" asChild variant="ghost" className="py-2 px-2 hidden md:flex gap-2">
417448
<a href="https://github.com/byodian/oneimg" target="_blank" rel="noreferrer">

src/components/preview/card.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { baseTemplate } from './styles'
66
import type { ContentWithId, ImageFile } from '@/types'
77
import { base64ToBlob, cn, createStyleClassMap, stripEmptyParagraphs } from '@/lib'
88
import { CustomThemeContext } from '@/contexts/custom-theme-context'
9+
import { useThemeStore } from '@/store/use-theme-store'
910

1011
interface PreviewItemProps {
1112
content: ContentWithId,
@@ -32,12 +33,14 @@ const Card = forwardRef<HTMLDivElement, PreviewItemProps>(({ content, children,
3233
const heroTemplate = templateClassNameMap.hero
3334
const mainTemplate = templateClassNameMap.main
3435
const subTemplate = templateClassNameMap.sub
36+
const { size } = useThemeStore()
37+
const height = typeof size.height === 'number' ? `${size.height / 3}px` : size.height
3538

3639
return (
3740
<div
3841
id={`${content.id}`}
39-
className={cn(
40-
templateClassNameMap.common.container,
42+
style={{ height: content.parentId ? 'auto' : height }}
43+
className={cn(templateClassNameMap.common.container,
4144
content.parentId
4245
? `${subTemplate.container}`
4346
: content.type === 'theme_content'

src/components/preview/styles/base-template.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const baseTemplate: ArticleModuleTemplate = {
8787
padding: 0,
8888
letterSpacing: 0,
8989
lineHeight: '1.5',
90-
overflow: 'visible',
90+
overflow: 'hidden',
9191
overflowWrap: 'break-word',
9292
tabSize: 4,
9393
textAlign: 'left',
@@ -121,7 +121,7 @@ export const baseTemplate: ArticleModuleTemplate = {
121121
padding: 0,
122122
letterSpacing: 0,
123123
lineHeight: '1.5',
124-
overflow: 'visible',
124+
overflow: 'hidden',
125125
overflowWrap: 'break-word',
126126
tabSize: 4,
127127
textAlign: 'left',

src/components/ui/select.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
1919
<SelectPrimitive.Trigger
2020
ref={ref}
2121
className={cn(
22-
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
22+
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 [&>span]:block',
2323
className,
2424
)}
2525
{...props}

src/lib/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export const CACHE_KEY_TEMPLATE = 'currentTemplate'
22
export const CACHE_KEY_THEME = 'currentTheme'
3+
export const CACHE_KEY_SIZE = 'currentSize'
4+
export const CACHE_KEY_SIZE_NAME = 'currentSizeName'

src/store/use-theme-store.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { create } from 'zustand'
2-
import type { ArticleModuleTemplate, ThemeColorItem } from '@/types'
3-
import { DEFAULT_TEMPLATE, DEFAULT_TEMPLATE_MAP, DEFAULT_THEME, DEFAULT_THEME_COLOR_MAP } from '@/theme'
2+
import type { ArticleModuleTemplate, Size, ThemeColorItem } from '@/types'
3+
import { DEFAULT_SIZE_MAP, DEFAULT_SIZE_NAME, DEFAULT_TEMPLATE, DEFAULT_TEMPLATE_MAP, DEFAULT_THEME, DEFAULT_THEME_COLOR_MAP } from '@/theme'
44

55
interface TemplateStore {
66
templateMap: Record<string, ArticleModuleTemplate>;
77
templateName: string;
88
theme: string;
99
themeMap: Record<string, ThemeColorItem[]>;
10+
sizeName: string;
11+
size: Size,
12+
setSize: (size: Size) => void;
13+
setSizeName: (sizeName: string) => void;
1014
setTemplateName: (templateName: string) => void;
1115
setTheme: (theme: string) => void;
1216
setTemplateMap: (templateMap: Record<string, ArticleModuleTemplate>) => void;
@@ -17,6 +21,10 @@ export const useThemeStore = create<TemplateStore>(set => ({
1721
theme: DEFAULT_THEME.label,
1822
templateMap: DEFAULT_TEMPLATE_MAP,
1923
themeMap: DEFAULT_THEME_COLOR_MAP,
24+
sizeName: DEFAULT_SIZE_NAME,
25+
size: DEFAULT_SIZE_MAP.default,
26+
setSize: size => set({ size }),
27+
setSizeName: sizeName => set({ sizeName }),
2028
setTemplateName: templateName => set({ templateName }),
2129
setTemplateMap: templateMap => set({ templateMap }),
2230
setTheme: theme => set({ theme }),

src/theme/index.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
techTemplate,
1313
techVibrantOrange,
1414
} from './templates'
15-
import type { ArticleModuleTemplate, ThemeColorItem } from '@/types'
15+
import type { ArticleModuleTemplate, Size, ThemeColorItem } from '@/types'
1616

1717
export const DEFAULT_TEMPLATES = [
1818
{ label: '简约科技风格', value: 'wechat-post-1', disabled: false, template: techTemplate },
@@ -57,3 +57,19 @@ export const DEFAULT_THEME = {
5757
label: 'snow_white',
5858
value: '#ddd',
5959
}
60+
61+
export const DEFAULT_SIZE_NAME = 'default'
62+
export const DEFAULT_SIZE_NAMES = [
63+
{ label: 'Instagramt 帖子', value: 'instagram_post', disabled: false, description: '1080 × 1350 px' },
64+
{ label: 'Twitter 帖子', value: 'twitter_post', disabled: false, description: '1600 × 900 px' },
65+
{ label: '小红书帖子', value: 'redbook_post', disabled: false, description: '1242 × 1660 px' },
66+
{ label: '微信长图', value: 'default', disabled: false, description: '' },
67+
{ label: '更多尺寸尽情期待', value: 'size-more', disabled: true, description: '' },
68+
] as const
69+
70+
export const DEFAULT_SIZE_MAP: Record<string, Size> = {
71+
redbook_post: { width: 1242, height: 1660 },
72+
instagram_post: { width: 1080, height: 1350 },
73+
twitter_post: { width: 1600, height: 900 },
74+
default: { width: 1125, height: 'auto' },
75+
}

src/theme/templates/tech-template/tech-template.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const techTemplate: ArticleModuleTemplate = {
2626
title: {
2727
position: 'relative',
2828
zIndex: 1,
29-
marginTop: '45px',
29+
// marginTop: '45px',
3030
marginBottom: '5px',
3131
fontWeight: 'bold',
3232
fontSize: '30px',

src/types/template.ts

+5
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,8 @@ export type ThemeColorItem = {
5555
label: string;
5656
theme?: ThemeConfig;
5757
}
58+
59+
export type Size = {
60+
width: number;
61+
height: number | 'auto';
62+
}

0 commit comments

Comments
 (0)