From 759aa1b6844dc69d8fce2096fa5ec6e849076e69 Mon Sep 17 00:00:00 2001 From: Akshaj Rawat <159126002+akshajrawat@users.noreply.github.com> Date: Wed, 28 Jan 2026 01:48:21 +0530 Subject: [PATCH] feat: add option to disable image anti-aliasing (#14278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What this PR does Closes #13869 Adds a global setting to toggle image anti-aliasing in AFFiNE. When disabled, images are rendered using nearest-neighbor scaling (`image-rendering: pixelated`), preserving crisp pixels for pixel art, sprites, icons, and low-resolution images. ## Why Anti-aliasing causes small images to become blurry when scaled, making it difficult to work with pixel art and technical assets. ## How to test 1. Open Settings → Appearance → Images 2. Toggle “Smooth image rendering” 3. Observe image scaling behavior: - ON: smooth / anti-aliased - OFF: pixelated / nearest-neighbor ## Notes - Frontend-only change - No backend required # BEFORE Screenshot 2026-01-18 202651 # AFTER Screenshot 2026-01-18 202705 ## Summary by CodeRabbit * **New Features** * Added an Images section in Appearance with a toggle to switch image antialiasing on/off (setting is persisted). * **Style** * When antialiasing is turned off, images render with pixelated scaling for a crisp, non-smoothed look. * **Localization** * Added English labels and description for the new Images and antialiasing options. ✏️ Tip: You can customize this high-level summary in your review settings. --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> --- packages/common/infra/src/atom/settings.ts | 2 ++ .../apps/electron-renderer/src/shell/app.tsx | 1 + .../frontend/component/src/theme/global.css | 4 ++++ .../core/src/components/context/index.tsx | 3 +++ .../components/hooks/use-image-antialiasing.ts | 12 ++++++++++++ .../general-setting/appearance/index.tsx | 17 +++++++++++++++++ .../frontend/i18n/src/i18n-completenesses.json | 8 ++++---- packages/frontend/i18n/src/i18n.gen.ts | 12 ++++++++++++ packages/frontend/i18n/src/resources/en.json | 3 +++ 9 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 packages/frontend/core/src/components/hooks/use-image-antialiasing.ts diff --git a/packages/common/infra/src/atom/settings.ts b/packages/common/infra/src/atom/settings.ts index 8ff46461d..404cf443c 100644 --- a/packages/common/infra/src/atom/settings.ts +++ b/packages/common/infra/src/atom/settings.ts @@ -17,6 +17,7 @@ export type AppSetting = { autoDownloadUpdate: boolean; enableTelemetry: boolean; showLinkedDocInSidebar: boolean; + disableImageAntialiasing: boolean; }; export const windowFrameStyleOptions: AppSetting['windowFrameStyle'][] = [ 'frameless', @@ -35,6 +36,7 @@ const appSettingBaseAtom = atomWithStorage( autoDownloadUpdate: true, enableTelemetry: true, showLinkedDocInSidebar: true, + disableImageAntialiasing: false, }, undefined, { diff --git a/packages/frontend/apps/electron-renderer/src/shell/app.tsx b/packages/frontend/apps/electron-renderer/src/shell/app.tsx index 57f9da723..24eb8d07e 100644 --- a/packages/frontend/apps/electron-renderer/src/shell/app.tsx +++ b/packages/frontend/apps/electron-renderer/src/shell/app.tsx @@ -32,6 +32,7 @@ export function App() { BUILD_CONFIG.isElectron && environment.isMacOs && appSettings.enableBlurBackground; + return ( diff --git a/packages/frontend/component/src/theme/global.css b/packages/frontend/component/src/theme/global.css index 7a1f3155c..249e3ec88 100644 --- a/packages/frontend/component/src/theme/global.css +++ b/packages/frontend/component/src/theme/global.css @@ -322,3 +322,7 @@ math { .ai-block-diff-deleted .affine-block-component { margin: 0 !important; } + +html[data-image-antialiasing='off'] img { + image-rendering: pixelated; +} diff --git a/packages/frontend/core/src/components/context/index.tsx b/packages/frontend/core/src/components/context/index.tsx index 2e9bec4ff..e4c64fe56 100644 --- a/packages/frontend/core/src/components/context/index.tsx +++ b/packages/frontend/core/src/components/context/index.tsx @@ -6,11 +6,14 @@ import { Provider } from 'jotai'; import type { PropsWithChildren } from 'react'; import { useMemo } from 'react'; +import { useImageAntialiasing } from '../hooks/use-image-antialiasing'; + export type AffineContextProps = PropsWithChildren<{ store?: ReturnType; }>; export function AffineContext(props: AffineContextProps) { + useImageAntialiasing(); return ( { + document.documentElement.dataset.imageAntialiasing = + appSettings.disableImageAntialiasing ? 'off' : 'on'; + }, [appSettings.disableImageAntialiasing]); +} diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx index d7575a540..c7016e01c 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/appearance/index.tsx @@ -197,6 +197,23 @@ export const AppearanceSettings = () => { {enableThemeEditor ? : null} + + + + updateSettings('disableImageAntialiasing', !checked) + } + /> + + + {BUILD_CONFIG.isWeb && !environment.isMobile ? (