cs193p-emojiart/EmojiArt/EmojiArtDocument.swift
Ching 89d38faea4 feat(view, viewmodel, model): 增加 document 和 palette,增加手势
1. 可以从另一个 app 中拖入图片或图片链接作为背景
2. 可以从 palette 中拖入 emoji
3. 可以拖动和双击缩放背景图

Signed-off-by: Ching <loooching@gmail.com>
2023-02-20 21:45:33 +08:00

81 lines
2.5 KiB
Swift

//
// EmojiArtDocument.swift
// EmojiArt
//
// Created by ching on 2023/2/19.
//
import SwiftUI
class EmojiArtDocument: ObservableObject {
@Published private(set) var emojiArt: EmojiArtModel {
didSet {
if emojiArt.background != oldValue.background {
fetchBackgoundImageDataIfNecessary()
}
}
}
init() {
emojiArt = EmojiArtModel()
}
var emojis: [EmojiArtModel.Emoji] { emojiArt.emojis }
var background: EmojiArtModel.Background { emojiArt.background }
@Published var backgroundImage: UIImage?
@Published var backgroundImageFetchStatus = BackgroundImageFetchStatus.idle
enum BackgroundImageFetchStatus {
case idle
case fetching
}
// MARK: - Intent(s)
func setBackground(_ background: EmojiArtModel.Background) {
emojiArt.background = background
print("background set to \(background)")
}
func addEmoji(_ emoji: String, at location: (x: Int, y: Int), size: CGFloat) {
emojiArt.addEmoji(emoji, at: location, size: Int(size))
}
func moveEmoji(_ emoji: EmojiArtModel.Emoji, by offset: CGSize) {
if let index = emojiArt.emojis.index(matching: emoji) {
emojiArt.emojis[index].x += Int(offset.width)
emojiArt.emojis[index].y += Int(offset.height)
}
}
func scaleEmoji(_ emoji: EmojiArtModel.Emoji, by scale: CGFloat) {
if let index = emojiArt.emojis.index(matching: emoji) {
emojiArt.emojis[index].size = Int((CGFloat(emojiArt.emojis[index].size) * scale).rounded(.toNearestOrAwayFromZero))
}
}
private func fetchBackgoundImageDataIfNecessary() {
backgroundImage = nil
switch emojiArt.background {
case .url(let url):
// fetch url
backgroundImageFetchStatus = .fetching
DispatchQueue.global(qos: .userInitiated).async {
let imageData = try? Data(contentsOf: url)
DispatchQueue.main.async { [weak self] in
if self?.emojiArt.background == EmojiArtModel.Background.url(url) {
self?.backgroundImageFetchStatus = .idle
if imageData != nil {
self?.backgroundImage = UIImage(data: imageData!)
}
}
}
}
case .imageData(let data):
backgroundImage = UIImage(data: data)
case .blank:
break
}
}
}