Overview of My Submission
Place iOS is r/place canvas clone made with Appwrite and pure SwiftUI.
I decide create this project for Appwrite Hackathon to test me in SwiftUI and use majority appwrite Apis. π
I'm a super fan of pixel art and this project fit perfect whit it. π©π¨πͺ
The rules are simple: You can place a pixel every 30 seconds and the canvas will be updated using realtime.
Manage accounts, database, storage, sessions, realtime, functions and more were super simple with appwrite. π
My approach for create the canvas in SwiftUI
class CanvasViewModel: ObservableObject { @Published var documents: [Doc] = [Doc]() // MARK: - Properties let canvasWidth: Int = 256 let canvasHeight: Int = 256 /// Pixel per pixels π /// if canvasPixelFactor is high every pixels looks better (no antialiasing) but the performance in older devices will be compromised... Int(UIScreen.main.scale) + (3-12) works good let canvasPixelFactor: Int = Int(UIScreen.main.scale) + 3 /// Computed canvas size var canvasWidthComputed: CGFloat { return CGFloat(canvasWidth * canvasPixelFactor) } var canvasHeightComputed: CGFloat { return CGFloat(canvasWidth * canvasPixelFactor) } . . . }
Fetch pixels from storage and database, then create image
private func createImage(completionHandler: @escaping (UIImage?, String?) -> Void){ guard !documents.isEmpty else { fatalError() } guard canvasWidth > 0 && canvasHeight > 0 else { fatalError() } DispatchQueue.global(qos: .utility).async { let width = self.canvasWidth * self.canvasPixelFactor let height = self.canvasHeight * self.canvasPixelFactor let rgbColorSpace = CGColorSpaceCreateDeviceRGB() let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue) // premultipliedLast or .none let bitsPerComponent = 8 let bitsPerPixel = 32 var pixels = [Pixel]() if self.pixelsArray.isEmpty { for _ in 0..<width { for _ in 0..<height { pixels.append(Pixel(r: 255, g: 255, b: 255, a: 255)) } } // Colorize for doc in self.documents { let x = doc.x + 1 let y = doc.y + 1 let startXPx = x > 0 ? Int((x-1) * self.canvasPixelFactor) : 1 let endXPx = Int(x * self.canvasPixelFactor) let startYPx = y > 0 ? Int((y-1) * self.canvasPixelFactor) : 1 let endYPx = Int(y * self.canvasPixelFactor) for i in startXPx..<endXPx{ for j in startYPx..<endYPx{ let offset: Int = (Int(self.canvasWidthComputed) * j) + i pixels[offset] = Pixel(hexString: doc.hex) } } } . . . . }
Bot
Also taking advantage of appwrite SDK's, i made a Bot in python for create pixel art in the canvas.π€
The bot converts Sprites (or any image) in a valid image for draw in the canvas, the bot uses secret enviroment variable such we provided previously in colorPixel function, thus, will skip the delay. π
Dependencies
Appwrite Apple SDK: For manage, accounts, sessions, database, storage, functions, realtime... β‘
Drops: For create notifications.
Popovers: For create pop menus.
SwiftyBeaver: For logging.
Submission Category:
Mobile Moguls
Link to Code
Additional Resources / Info
Onboarding
Func fact: In the last page, the third guy has an appwrite t-shirt.
Canvas View
For navigate in the canvas view you can zoom in, zoom out , drag and reset.
Func fact: The allowed colors is my favorite palette when i did pixel art: PICO-8 (only i was made a little change in white color to #FFFFFF)
Authentication
Only members are allowed to place pixels.
Settings
For log out, change zoom factor and information.
Fun fact: Tha app support Dark Mode. ππ
Notifications
I use drops for put cool notifications. π
Videos
App demostration
Bot demostration
Conclusion
This project was super fun to do.
Thanks for read and special thanks to Appwrite community for solves my questions ever. π
Top comments (2)
Nice!
Thanks a lot for your feedback π