Modernize fSpy: Full Stack Upgrade & Bug Fixes#158
Conversation
…box for better user experience.
|
Hi @lzandman, I just wanted to let you know that I merged your fSpy modernization PR into my fSpy-UE fork. I was actually working on modernizing fSpy yesterday, but when I saw this morning that you had opened this PR, I took the opportunity to merge it into my fork. Thanks for your work on this, and keep up the good work! |
Great! That's what open-source is for! Please report back any findings/issues. |
|
I'm also curious whether Per @stuffmatic is still interested in maintaining fSpy, since it has been many years since any active development was done on it. I know fSpy is still very popular amongst the Blender Community and my son actually had an fSpy class in school! Personally, I've also been using Perspective Plotter, but I think there's value in having a separate app instead of a Blender add-on. Of course I could start a well-maintained fork of fSpy, but I'd rather have fSpy do well at this location. |
Added from Git Log and Github repo page.
Summary
Complete modernization of the fSpy desktop application, upgrading every major dependency from its legacy versions to current releases, implementing Electron's modern security model, and fixing several bugs.
Note
I've been using fSpy for many years, but I never really understood why it was never updated. While preparing for one of my AI masterclasses, I was looking for real‑world AI use cases. Upgrading fSpy seemed like a good candidate.
Dependency Upgrades
Main Changes
Build Toolchain
ES2022target,node16module resolution.ts-loader9,css-loader7,style-loader4,html-webpack-plugin5).ts-loaderhandles all transpilation and JSX.tslint,tslint-loader,standard-loader; replaced witheslint8 +@typescript-eslint.ts-jest— removedwebpack.tests.config.js(tests no longer webpack-compiled). Addedjest.config.js.trash-cliwithrimraf; addedcross-envfor cross-platformDEV=trueenv var; addedstartscript.Electron Security Model
src/main/preload.tsexposing a typedwindow.electronAPIsurface. Createdsrc/gui/types/electron-api.tswith fullElectronAPIinterface. Addedelectron-preloadwebpack target.remotemodule: Replaced allremote.dialog.showErrorBox()andremote.app.getVersion()calls with IPC handlers (ipcMain.handle/window.electronAPI.*).fs,Buffer,path,process, andelectronimports from renderer code. File I/O moved to main process via IPC.Bufferoperations inproject-file.tsrewritten to useDataView/Uint8Array/TextEncoder/TextDecoder.contextIsolation: true,nodeIntegration: false,sandbox: true.File.path→webUtils.getPathForFile,url.format()→pathToFileURL(),app.on('ready')→app.whenReady(), deprecated event type annotations, etc.).React & UI Framework
createRoot()API. Fixed removedcomponentWillMount→componentDidMount. Added explicitchildren?: React.ReactNodeprop where needed (React 18 no longer includes children implicitly).legacy_createStore, namedthunkimport, typed middlewareactionasunknown. Removed@types/react-redux(types now bundled).UX: Image Opacity Slider
Replaced the binary "Dim image" checkbox (which toggled between 100% and 20% opacity) with a continuous slider control, allowing any opacity value between 0% and 100%.
Bug Fix: Control Points Stuck After Dragging Outside Canvas
Fixed a bug where dragging a control point and releasing the mouse button outside the Konva stage (e.g. over a side panel) caused the control point to become permanently unresponsive. The Konva node's internal position and drag state could get out of sync when the
mouseupevent didn't reach the stage. The fix ensures the node position and drag state are always properly reset on drag end.Other Fixes
Various minor fixes including clipboard compatibility with sandbox mode, DEV mode resource path resolution, and TypeScript module settings.
Testing
npm test.Added test coverage
tests/gui/solver/vector-3d.tests.tstests/gui/solver/math-util.tests.tstests/gui/solver/coordinates-util.tests.tstests/gui/solver/transform.tests.tstests/gui/io/project-file.tests.ts.fspyheader parsing, state JSON validation, round-trip serialization ± image data; exercises all 14test_data/filestests/gui/reducers/reducers.tests.tsglobalSettings,imageState,resultDisplaySettings— all action types, defaults, unknown-action passthroughAI Disclosure
Claude Opus 4.6 (Anthropic) was used as an AI coding assistant during the development of this PR. This includes help with code migration, writing tests, debugging, and drafting documentation.