Skip to content

Commit

Permalink
feat: Better webtoon cover handling approach
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsuz0u committed Nov 23, 2021
1 parent 731fa3e commit 8bc2998
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 53 deletions.
16 changes: 9 additions & 7 deletions EhPanda/App/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@ struct Defaults {
DeviceUtil.isPadWidth ? 175 : DeviceUtil.isSEWidth ? 125 : 150
}
struct ImageSize {
static let rowScale: CGFloat = 8/11
static let avatarScale: CGFloat = 1/1
static let headerScale: CGFloat = 8/11
static let previewScale: CGFloat = 8/11
static let contentScale: CGFloat = 7/10
static let rowAspect: CGFloat = 8/11
static let avatarAspect: CGFloat = 1/1
static let headerAspect: CGFloat = 8/11
static let previewAspect: CGFloat = 8/11
static let contentAspect: CGFloat = 7/10
static let webtoonMinAspect: CGFloat = 1/4
static let webtoonIdealAspect: CGFloat = 2/3

static let rowW: CGFloat = rowH * rowScale
static let rowW: CGFloat = rowH * rowAspect
static let rowH: CGFloat = 110
static let avatarW: CGFloat = 100
static let avatarH: CGFloat = 100
static let headerW: CGFloat = headerH * headerScale
static let headerW: CGFloat = headerH * headerAspect
static let headerH: CGFloat = 150
static let previewMinW: CGFloat = DeviceUtil.isPadWidth ? 180 : 100
static let previewMaxW: CGFloat = DeviceUtil.isPadWidth ? 220 : 120
Expand Down
4 changes: 2 additions & 2 deletions EhPanda/App/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ extension UIImage {
return UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
}

func cropping(size: CGSize, offset: CGFloat) -> UIImage? {
let origin = CGPoint(x: offset, y: 0)
func cropping(size: CGSize, offset: CGSize) -> UIImage? {
let origin = CGPoint(x: offset.width, y: offset.height)
let rect = CGRect(origin: origin, size: size)
return cropping(to: rect)
}
Expand Down
6 changes: 3 additions & 3 deletions EhPanda/App/Tools/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,7 @@ extension Parser {
}

// MARK: parsePreviewConfigs
static func parsePreviewConfigs(string: String) -> (String, CGSize, CGFloat)? {
static func parsePreviewConfigs(string: String) -> (String, CGSize, CGSize)? {
guard let rangeA = string.range(of: Defaults.PreviewIdentifier.width),
let rangeB = string.range(of: Defaults.PreviewIdentifier.height),
let rangeC = string.range(of: Defaults.PreviewIdentifier.offset)
Expand All @@ -1517,11 +1517,11 @@ extension Parser {
let plainURL = String(string[..<rangeA.lowerBound])
guard let width = Int(string[rangeA.upperBound..<rangeB.lowerBound]),
let height = Int(string[rangeB.upperBound..<rangeC.lowerBound]),
let offset = Int(string[rangeC.upperBound...])
let offsetX = Int(string[rangeC.upperBound...])
else { return nil }

let size = CGSize(width: width, height: height)
return (plainURL, size, CGFloat(offset))
return (plainURL, size, CGSize(width: offsetX, height: 0))
}

// MARK: parseWrappedHex
Expand Down
63 changes: 32 additions & 31 deletions EhPanda/App/ViewModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import Kingfisher

extension View {
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
clipShape( RoundedCorner(radius: radius, corners: corners) )
clipShape(RoundedCorner(radius: radius, corners: corners))
}

@ViewBuilder
func withHorizontalSpacing(height: CGFloat? = nil) -> some View {
@ViewBuilder func withHorizontalSpacing(height: CGFloat? = nil) -> some View {
Color.clear.frame(width: 8, height: height)
self
Color.clear.frame(width: 8, height: height)
Expand Down Expand Up @@ -62,56 +61,58 @@ struct CornersModifier: ImageModifier {

struct OffsetModifier: ImageModifier {
private let size: CGSize?
private let offset: CGFloat?
private let offset: CGSize?

init(size: CGSize?, offset: CGFloat?) {
init(size: CGSize?, offset: CGSize?) {
self.size = size
self.offset = offset
}

func modify(
_ image: KFCrossPlatformImage
) -> KFCrossPlatformImage
{
guard let size = size,
let offset = offset
func modify(_ image: KFCrossPlatformImage) -> KFCrossPlatformImage {
guard let size = size, let offset = offset
else { return image }

return image.cropping(
size: size, offset: offset
) ?? image
return image.cropping(size: size, offset: offset) ?? image
}
}

struct RoundedOffsetModifier: ImageModifier {
private let size: CGSize?
private let offset: CGFloat?
private let offset: CGSize?

init(size: CGSize?, offset: CGFloat?) {
init(size: CGSize?, offset: CGSize?) {
self.size = size
self.offset = offset
}

func modify(
_ image: KFCrossPlatformImage
) -> KFCrossPlatformImage
{
guard let size = size,
let offset = offset,
let croppedImg = image.cropping(
size: size, offset: offset
),
let roundedCroppedImg = croppedImg
.withRoundedCorners(radius: 5)
else {
return image
.withRoundedCorners(radius: 5) ?? image
}
func modify(_ image: KFCrossPlatformImage) -> KFCrossPlatformImage {
guard let size = size, let offset = offset,
let croppedImg = image.cropping(size: size, offset: offset),
let roundedCroppedImg = croppedImg.withRoundedCorners(radius: 5)
else { return image.withRoundedCorners(radius: 5) ?? image }

return roundedCroppedImg
}
}

struct WebtoonModifier: ImageModifier {
private let minAspect: CGFloat
private let idealAspect: CGFloat

init(minAspect: CGFloat, idealAspect: CGFloat) {
self.minAspect = minAspect
self.idealAspect = idealAspect
}

func modify(_ image: KFCrossPlatformImage) -> KFCrossPlatformImage {
let width = image.size.width
let height = image.size.height
let idealHeight = width / idealAspect
guard width / height < minAspect else { return image }
return image.cropping(size: CGSize(width: width, height: idealHeight), offset: .zero) ?? image
}
}

extension KFImage {
func defaultModifier(withRoundedCorners: Bool = true) -> KFImage {
self
Expand Down
8 changes: 4 additions & 4 deletions EhPanda/View/Detail/DetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ private struct HeaderView: View {
var body: some View {
HStack {
KFImage(URL(string: gallery.coverURL))
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.headerScale)) }
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.headerAspect)) }
.defaultModifier().scaledToFit().frame(width: width, height: height)
VStack(alignment: .leading) {
Text(title).fontWeight(.bold).lineLimit(3).font(.title3)
Expand Down Expand Up @@ -647,7 +647,7 @@ private struct PreviewView: View {
Defaults.ImageSize.previewAvgW
}
private var height: CGFloat {
width / Defaults.ImageSize.previewScale
width / Defaults.ImageSize.previewAspect
}

var body: some View {
Expand Down Expand Up @@ -679,7 +679,7 @@ private struct PreviewView: View {
.placeholder {
Placeholder(style: .activity(
ratio: Defaults.ImageSize
.previewScale
.previewAspect
))
}
.imageModifier(modifier)
Expand Down Expand Up @@ -745,7 +745,7 @@ private struct MorePreviewView: View {
.placeholder {
Placeholder(style: .activity(
ratio: Defaults.ImageSize
.previewScale
.previewAspect
))
}
.imageModifier(modifier)
Expand Down
4 changes: 2 additions & 2 deletions EhPanda/View/Reading/ControlPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ private struct SliderPreivew: View {
KFImage.url(URL(string: url), cacheKey: previews[index])
.placeholder {
Placeholder(style: .activity(
ratio: Defaults.ImageSize.previewScale
ratio: Defaults.ImageSize.previewAspect
))
}
// .fade(duration: 0.25)
Expand Down Expand Up @@ -309,7 +309,7 @@ private extension SliderPreivew {
}
var previewSpacing: CGFloat { 10 }
var previewHeight: CGFloat {
previewWidth / Defaults.ImageSize.previewScale
previewWidth / Defaults.ImageSize.previewAspect
}
var previewWidth: CGFloat {
guard previewsCount > 0 else { return 0 }
Expand Down
2 changes: 1 addition & 1 deletion EhPanda/View/Reading/ReadingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ private struct ImageContainer: View {
DeviceUtil.windowW / (isDualPage ? 2 : 1)
}
private var height: CGFloat {
width / Defaults.ImageSize.contentScale
width / Defaults.ImageSize.contentAspect
}
private var loadFailedFlag: Bool {
loadError != nil || webImageLoadFailed
Expand Down
2 changes: 1 addition & 1 deletion EhPanda/View/Tools/GalleryDetailCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct GalleryDetailCell: View {
var body: some View {
HStack(spacing: 10) {
KFImage(URL(string: gallery.coverURL))
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.rowScale)) }
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.rowAspect)) }
.defaultModifier().scaledToFit().frame(width: Defaults.ImageSize.rowW, height: Defaults.ImageSize.rowH)
VStack(alignment: .leading) {
Text(gallery.title).lineLimit(1).font(.headline).foregroundStyle(.primary)
Expand Down
8 changes: 6 additions & 2 deletions EhPanda/View/Tools/GalleryThumbnailCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ struct GalleryThumbnailCell: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
KFImage(URL(string: gallery.coverURL))
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.rowScale)) }
.placeholder { Placeholder(style: .activity(ratio: Defaults.ImageSize.rowAspect)) }
.imageModifier(WebtoonModifier(
minAspect: Defaults.ImageSize.webtoonMinAspect,
idealAspect: Defaults.ImageSize.webtoonIdealAspect
))
/*.fade(duration: 0.25)*/
.resizable().frame(maxHeight: DeviceUtil.absWindowH * 2/3).scaledToFit().overlay {
.resizable().scaledToFit().overlay {
VStack {
HStack {
Spacer()
Expand Down

0 comments on commit 8bc2998

Please sign in to comment.