InfiniPaint, an infinite canvas with infinite zoom and online collaboration
Posted by ErrorAtLine0@reddit | linux | View on Reddit | 33 comments
I wanted to share a program I've been working on for a bit less than a year now. InfiniPaint is a collaborative, infinite canvas note-taking/drawing app. The biggest distinguishing feature of this application is that there is no zoom in or zoom out limit. Other than that, InfiniPaint's features include:
- Open online lobbies for collaboration
- Text chat with others in the lobby
- Jump to the location of other players through the player list
- See other members draw in real time
- Although this is a feature, you can also choose to completely forget about it. This app can be used offline
- Graphics tablet support (Pressure sensitive brush and eraser detection)
- Layers with blend modes and opacity. Layers can be sorted into folders with their own blend mode and opacity
- Save/load projects
- Saveable color palettes
- Quick menu usable by right clicking on the canvas, which can be used to:
- Quickly change brush colors using the currently selected color palette
- Rotate the canvas
- Place bookmarks on the canvas to jump to later. Bookmarks can be sorted into folders
- Undo/Redo
- PNG, JPG, WEBP export of specific parts of the canvas at any resolution (Screenshot)
- SVG export of specific parts of the canvas (Screenshot)
- Transform (Move, Scale, Rotate) any object on the canvas (Rectangle Select Tool/Lasso Select Tool)
- Display Images and animated GIFs on the canvas
- Note: May take a lot of memory to store and display images compared to other objects, especially GIFs
- Hide (or unhide) the UI by pressing Tab
- Remappable keybinds
- Create custom UI themes
- Place infinite square grids on the canvas as guides for drawing
- Grids come with various properties, including changing color, and displaying coordinate axes
- Textbox tool with formatting support (Bold, italics, underline, strikethrough, overline, fonts, text color, highlight color, text size, paragraph alignment, text direction)
- Other tools: Rectangle, Ellipse, Line, Eye dropper/color picker, Edit/cursor
- Can copy/paste selected objects (Ctrl-C Ctrl-V). This can also be done between different files, as long as they're open in different tabs in the same window
InfiniPaint is a native application written in C++ and licensed under the MIT License. You can find the source code on Github at: https://github.com/ErrorAtLine0/infinipaint
The best way to download this application for Linux is to get it on Flathub at: https://flathub.org/en/apps/com.infinipaint.infinipaint
You can try a (slightly restricted) version of InfiniPaint in your browser at: https://infinipaint.com/try.html (requires a WebGL2 capable browser, designed for desktops, and might take a while to load)
NotCisChiss@reddit
I just flatpak installed the latest version on my archcraft laptop and when I open it all it gives me is a black screen, but the laptop works fine other than that. Did I do something wrong?
When I try to click inside the black screen it doesn't let me close the program (not even killing with the terminal works) so I have to totally reboot the laptop. I don't know what the problem could possibly be.
EK4Sensei@reddit
Firstly, thank you for all youreffort in to making a lovely piece of software. It's smooth, responsive, and lightweight. Looks good to use as well. As a teacher who uses it as a virtual blackboard for online classes, I find it to be the best app I have used so far.
2 things I would like to bring in to consideration:
1. Very rarely, but it happens, there is a glitch where if I am using the line or pen tool and I click on a point it draws a random line from somewhere to that point. You're probably already aware of this.
Thank you once again.
Jayx_x@reddit
Hey man wondering if you have any plans for android port if so do you have any idea when you would start working on it been looking for an app like this it's really cool
parkerlreed@reddit
Thank you! Been looking for something that does this for a while. Excited to try this on the Android tablet as nobody ever made anything like this outside of iOS.
ErrorAtLine0@reddit (OP)
Unfortunately, touch screens aren't supported right now. I have plans to make an android port in the future, so I'll add touch screen gestures (pinch to zoom and two finger pan) to prepare for that in a future release.
netsrak@reddit
Could you add a way to draw a line locked to a grid? Leonardo lets you hold shift to restrict drawing lines to straight up/down/left/right. I like having that so I can easily build tables or keep diagrams clean.
ErrorAtLine0@reddit (OP)
This should be possible with the line tool. If you hold left shift while drawing a line, you'll restrict the lines you draw to a set of common angles, which include up/down/left/right.
coffenerd@reddit
AMAZING!!!
I’m 17 and I just uploaded my first project on GitHub, this is honestly really inspiring for me.
Hot-Employ-3399@reddit
I dunno if it's flatpak or wayland permissions, but I can't drag'n'drop or copy-paste image from browsers(both firefox and chromium) into InfiniPaint. Or from taken screenshot.
ErrorAtLine0@reddit (OP)
Here are some issues I'm aware of:
- Drag dropping image files will not work if the file is in a directory that the flatpak doesn't have permission to access. The single file flatpak bundle has permissions for the entire home directory, while the flathub version has permissions for Desktop, Documents, Downloads, and Pictures (you can change these permissions with Flatseal).
- Drag dropping images from the browser requires that the image you're dragging comes from a direct image URL. Some websites like Google Images don't use direct URLs when displaying their images, so you'll have to right click and open the image in a new tab, and drag that image to the canvas.
If possible, I'd like to know what distro you're running, what desktop environment you're using, and which version of InfiniPaint you downloaded (flathub or single file bundle). I'm not sure if what I mentioned before can resolve the drag drop issue, and I'm not aware of issues with copy-pasting images, so I'd like to see if I can find and resolve the issue for a future release.
Hot-Employ-3399@reddit
Garuda, niri, flathub's flathub.
For comparison, drag'n'drop works for librewriter from flathub. Image url is "https://shared.fastly.steamstatic.com/store_item_assets/steam/apps/2150660/capsule_616x353.jpg?t=1750958891" (that's preview of image if you click on it in image search of "touhou image")
Big_Wrongdoer_5278@reddit
Man that's amazing, I've recently looked into infinite drawing apps and found the most popular (if not only) app to be an iOS exclusive, so I couldn't play around with it unfortunately.
This being on Linux, already in an absolutely usable state, generously licensed is a massive contribution to the ecosystem. Can't thank you enough and hope you keep developing it for years to come!
parkerlreed@reddit
Yeah, you hit the same inside experience as me. There were attempts to do it on other platforms, but they always screwed multiple aspects up, including not being actually infinite, which was hilarious to me.
This is very refreshing to see and great to use.
Low_Big7602@reddit
How big are the files?
ErrorAtLine0@reddit (OP)
I have a file with 5003 brush strokes, and it has a size of 916.4 KB. Another file I have has a size of 226.5 KB with 439 brush strokes. The files are compressed when you save them (zstd compression), so I can't give an accurate answer on how big the files will end up being since compression can work better on some canvases compared to others. In general though, they should be pretty small as long as you aren't counting embedded images.
Low_Big7602@reddit
very interesting. I would've assumed anybody who wanted an "infinite zoom" effect would just make a really huge canvas that ends up taking up a lot of space. good luck to your project
parkerlreed@reddit
I mean that's the point. Done right, it shouldn't just be a huge bitmap canvas.
That's where a lot of solutions in the past have failed. "Infinite" zoom that eventually is a blurry mess.
This is doing it right with vectors and scaling bitmaps where applicable.
cqz@reddit
Implemented with gmp? How's performance? Does it use any particular tricks or just store every point as an arbitrary precision number?
ErrorAtLine0@reddit (OP)
I'm using Boost cpp_int, with the cpp_int backend. I could switch to the gmp backend, but arbitrary precision integer operations aren't a bottleneck in regular use so I've been happy with the cpp_int backend.
My strategy has mostly been to avoid arbitrary precision integer operations as much as I possibly can. To be more specific, I'm using cpp_int to implement a fixed point data type which I call "WorldScalar" in my code. Every brush stroke stores its points using regular floating point numbers. In addition to that, each brush stroke/canvas object has one transformation object, which stores its transform as:
The WorldScalar object does run out of precision if objects get too small. To fix this, when a user zooms in far enough into the canvas, the entire canvas scales up to compensate. You'll see a popup saying "Canvas scaled up" in InfiniPaint when that happens, but other than that popup it shouldn't look like anything has changed.
As for performance, it should be good enough since I've also implemented a cache to reduce how often the program draws objects. My cache performs better in certain scenarios, so I can't give an accurate answer, but as long as the objects aren't all very close to each other the cache can improve performance by a lot. My computer has a Radeon RX 6950XT GPU, and a Ryzen 7950X CPU (don't know how important this is since my program is mostly single threaded), and the program could still run at my screen's refresh rate (165 FPS) with hundreds of thousands of objects on canvas.
It will stutter a bit when zooming in/out or panning in areas with a lot of objects, and FPS drops when you place high resolution (8K) images on the canvas. I've implemented solutions to improve performance in these situations, but they aren't in the latest stable release.
cqz@reddit
Thanks for the elaboration, and releasing a cool project! I'm curious about whether multiple objects exist at different scales and how all that is handled.
ErrorAtLine0@reddit (OP)
Objects do exist at different scales. What I do to determine the scale the object is drawn at on the screen is divide the object scale by the camera scale/zoom. This will give me a floating point number I can use to scale the object.
And yes, the transform is just limited in how zoomed in it can be, not how zoomed out it can be. The WorldScalar has a limited number of decimal places, which limits zooming in when using it as a scale factor. But it can expand infinitely to the left of the decimal point, so zooming out is no issue.
hauntlunar@reddit
Neat!
Svani@reddit
Great news, I've been looking for a Linux replacement for Milton! Also the colab painting sounds very promising, it's kinda crazy how I used to have that in the early 2000's and then it sort of disappeared from the appscape.
Caddy666@reddit
but once we've zoomed, can we enhance?
ParserXML@reddit
I'm developing my first desktop application and this serves as an amazing inspiration for me.
Congrats on your release; will check it later.
litelinux@reddit
Did you really… create your own GUI toolkit on top of Skia (if I'm not reading the code wrong)? Very impressive if so!
ErrorAtLine0@reddit (OP)
Yes! I am using clay to layout the GUI, which makes things much easier, but other than that I wrote the code for all the widgets myself.
lukeyeaaah@reddit
Do you have any experience with mobile development? I don't really know if there is a difference in using a browser on an ipad-like device vs native pen input API.
ErrorAtLine0@reddit (OP)
I don't have any experience with mobile development unfortunately, and the web version isn't ready for use on touch screen only devices. I'm hoping to get an android port out at some point, but since I haven't done any mobile development I can't say when that'll be ready.
I accept donations! You can do that through Github Sponsors or Liberapay
jwaxy01@reddit
I see that you are using SDL. You easily use it's pen API. https://wiki.libsdl.org/SDL3/CategoryPen
ErrorAtLine0@reddit (OP)
I am using the pen API for pen tablet input right now (wacom, huion, etc). The issue is touch input on touch screen only devices like smartphones and ipads/android tablets. SDL can handle touch input as well, but I haven't used any of the touch screen API yet and am assuming the user is using a mouse or pen tablet. I'll get around to adding proper touch screen support when I work on the android port.
The app does technically work when using a touch screen right now, but that's just because SDL is emulating mouse input from the touch input. That works for some stuff, but some tools are very awkward to use or just completely broken with this emulation.
markhadman@reddit
You don't make this explicit so I must ask: when using it collaboratively, is this hosted on one computer and accessed by users via web browser, or must everyone install the software?
ErrorAtLine0@reddit (OP)
One computer hosts the lobby, and people access it through the software by using the code/address the host gives them. They can access it through the web version (https://infinipaint.com/try.html), so it's not necessary to install the software, although the web version has a few limitations so the native version is preferred.