feat: revamp element tool bar

This commit is contained in:
dscyrescotti
2024-07-09 22:08:42 +07:00
parent a5ef50eb24
commit f36cc3e20c
3 changed files with 119 additions and 62 deletions

View File

@@ -32,18 +32,10 @@ struct ElementToolbar: View {
ZStack(alignment: .bottom) {
if tool.selection == .photo {
photoOption
.background {
RoundedRectangle(cornerRadius: 8)
.fill(.regularMaterial)
}
.padding(.bottom, 10)
.frame(maxWidth: .infinity)
.transition(.move(edge: .bottom).combined(with: .blurReplace))
} else {
compactToolbar
}
}
.padding(.bottom, 10)
}
#endif
}
@@ -228,7 +220,6 @@ struct ElementToolbar: View {
openCamera()
} label: {
Image(systemName: "camera.fill")
.contentShape(.circle)
.frame(width: size, height: size)
.clipShape(.rect(cornerRadius: 8))
.contentShape(.rect(cornerRadius: 8))
@@ -237,7 +228,6 @@ struct ElementToolbar: View {
#endif
PhotosPicker(selection: $photosPickerItem, matching: .images, preferredItemEncoding: .compatible) {
Image(systemName: "photo.fill.on.rectangle.fill")
.contentShape(.circle)
.frame(width: size, height: size)
.clipShape(.rect(cornerRadius: 8))
.contentShape(.rect(cornerRadius: 8))
@@ -247,7 +237,35 @@ struct ElementToolbar: View {
#else
.buttonStyle(.plain)
#endif
if horizontalSizeClass == .compact {
Divider()
.padding(.vertical, 4)
.frame(height: size)
.foregroundStyle(Color.accentColor)
Button {
withAnimation {
tool.selectTool(.hand)
}
} label: {
Image(systemName: "xmark")
.frame(width: size, height: size)
.clipShape(.rect(cornerRadius: 8))
.contentShape(.rect(cornerRadius: 8))
}
#if os(iOS)
.hoverEffect(.lift)
#else
.buttonStyle(.plain)
#endif
}
}
.background {
RoundedRectangle(cornerRadius: 8)
.fill(.regularMaterial)
}
.padding(.bottom, 10)
.frame(maxWidth: .infinity)
.transition(.move(edge: .bottom).combined(with: .blurReplace))
}
func openCamera() {

View File

@@ -108,25 +108,25 @@ struct MemoView: View {
.transition(.move(edge: .bottom).combined(with: .blurReplace))
}
}
.overlay(alignment: .bottom) {
if tool.selection != .hand {
Button {
withAnimation {
tool.selectTool(.hand)
}
} label: {
Image(systemName: "chevron.compact.down")
.font(.headline)
.frame(width: 80)
.padding(5)
.background(.regularMaterial)
.clipShape(.capsule)
.contentShape(.capsule)
}
.offset(y: 5)
.transition(.move(edge: .bottom).combined(with: .blurReplace))
}
}
// .overlay(alignment: .bottom) {
// if tool.selection != .hand {
// Button {
// withAnimation {
// tool.selectTool(.hand)
// }
// } label: {
// Image(systemName: "chevron.compact.down")
// .font(.headline)
// .frame(width: 80)
// .padding(5)
// .background(.regularMaterial)
// .clipShape(.capsule)
// .contentShape(.capsule)
// }
// .offset(y: 5)
// .transition(.move(edge: .bottom).combined(with: .blurReplace))
// }
// }
}
@ViewBuilder

View File

@@ -14,10 +14,10 @@ struct PenDock: View {
let size: CGFloat
var width: CGFloat {
horizontalSizeClass == .compact ? 30 : 90
horizontalSizeClass == .compact ? 25 : 90
}
var height: CGFloat {
horizontalSizeClass == .compact ? 90 : 30
horizontalSizeClass == .compact ? 75 : 30
}
var factor: CGFloat = 0.9
@@ -55,6 +55,29 @@ struct PenDock: View {
compactPenItemList
.fixedSize(horizontal: false, vertical: true)
compactPenPropertyTool
HStack(spacing: 5) {
Divider()
.padding(.vertical, 4)
.frame(height: size)
.foregroundStyle(Color.accentColor)
.frame(height: height * factor - 18)
Button {
withAnimation {
tool.selectTool(.hand)
}
} label: {
Image(systemName: "xmark")
.frame(width: size, height: size)
.clipShape(.rect(cornerRadius: 8))
.contentShape(.rect(cornerRadius: 8))
}
#if os(iOS)
.hoverEffect(.lift)
#else
.buttonStyle(.plain)
#endif
.frame(height: height * factor - 18)
}
}
.padding(.horizontal, 10)
.clipped()
@@ -63,8 +86,7 @@ struct PenDock: View {
.fill(.regularMaterial)
.frame(height: height * factor - 18)
}
.padding(.horizontal, 10)
.padding(.bottom, 20)
.padding([.horizontal, .bottom], 10)
.frame(maxWidth: min(proxy.size.height, proxy.size.width), maxHeight: .infinity, alignment: .bottom)
.frame(maxWidth: .infinity)
}
@@ -75,30 +97,35 @@ struct PenDock: View {
@ViewBuilder
var penItemList: some View {
ScrollViewReader { proxy in
ScrollView(.vertical, showsIndicators: false) {
LazyVStack(spacing: 0) {
ForEach(tool.pens) { pen in
penItem(pen)
.id(pen.id)
.scrollTransition { content, phase in
content
.scaleEffect(phase.isIdentity ? 1 : 0.04, anchor: .trailing)
}
VStack(alignment: .trailing, spacing: 0) {
ScrollViewReader { proxy in
ScrollView(.vertical, showsIndicators: false) {
LazyVStack(spacing: 0) {
ForEach(tool.pens) { pen in
penItem(pen)
.id(pen.id)
.scrollTransition { content, phase in
content
.scaleEffect(phase.isIdentity ? 1 : 0.04, anchor: .trailing)
}
}
}
.padding(.vertical, 10)
.id(refreshScrollId)
}
.onReceive(tool.scrollPublisher) { id in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
proxy.scrollTo(id)
}
}
}
}
newPenButton
.padding(.vertical, 10)
.id(refreshScrollId)
}
.onReceive(tool.scrollPublisher) { id in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
proxy.scrollTo(id)
}
}
}
.frame(width: width * factor - 18)
}
.frame(maxHeight: ((height * factor + 10) * 6) + 20)
.frame(maxHeight: ((height * factor + 10) * 7) + 20)
.fixedSize()
.background(alignment: .trailing) {
RoundedRectangle(cornerRadius: 8)
@@ -106,10 +133,6 @@ struct PenDock: View {
.frame(width: width * factor - 18)
}
.clipShape(.rect(cornerRadii: .init(bottomTrailing: 8, topTrailing: 8)))
.overlay(alignment: .bottomLeading) {
newPenButton
.offset(x: 15, y: 10)
}
}
@ViewBuilder
@@ -126,7 +149,7 @@ struct PenDock: View {
}
}
}
.padding(.horizontal, 10)
.padding(.horizontal, 5)
.id(refreshScrollId)
}
.onReceive(tool.scrollPublisher) { id in
@@ -235,7 +258,7 @@ struct PenDock: View {
tool.selectPen(pen)
}
}
.padding(.horizontal, 10)
.padding(.horizontal, 5)
.contextMenu(if: pen.strokeStyle != .eraser) {
ControlGroup {
Button {
@@ -273,7 +296,7 @@ struct PenDock: View {
}
.controlGroupStyle(.menu)
} preview: {
penPreview(pen)
compactPenPreview(pen)
.drawingGroup()
#if os(iOS)
.contentShape(.contextMenuPreview, .rect(cornerRadius: 10))
@@ -284,7 +307,7 @@ struct PenDock: View {
tool.draggedPen = pen
return NSItemProvider(contentsOf: URL(string: pen.id)) ?? NSItemProvider()
} preview: {
penPreview(pen)
compactPenPreview(pen)
.contentShape(.dragPreview, .rect(cornerRadius: 10))
}
.onDrop(of: [.item], delegate: PenDropDelegate(id: pen.id, tool: tool, action: { refreshScrollId = UUID() }))
@@ -440,7 +463,7 @@ struct PenDock: View {
createNewPen()
} label: {
Image(systemName: "plus.circle.fill")
.font(.title2)
.font(.headline)
.padding(1)
.contentShape(.circle)
.background {
@@ -472,6 +495,22 @@ struct PenDock: View {
.padding(.leading, 10)
}
func compactPenPreview(_ pen: Pen) -> some View {
ZStack {
if let tip = pen.style.compactIcon.tip {
Image(tip)
.resizable()
.renderingMode(.template)
.foregroundStyle(Color.rgba(from: pen.rgba))
}
Image(pen.style.compactIcon.base)
.resizable()
}
.frame(width: width * factor, height: height * factor)
.padding(.top, 5)
.padding(.horizontal, 5)
}
func penShadow(_ pen: Pen) -> some View {
ZStack {
Group {