Skip to content

Commit

Permalink
fix: Refactor & resize directive
Browse files Browse the repository at this point in the history
This simplifies the resize directive and fixes issue #91
  • Loading branch information
JonasKruckenberg committed May 7, 2021
1 parent 8e86de1 commit 5b2fca0
Showing 1 changed file with 48 additions and 60 deletions.
108 changes: 48 additions & 60 deletions packages/core/src/transforms/resize.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getMetadata, setMetadata } from "../lib/metadata";
import { TransformFactory } from "../types";
import { getFit } from './fit'
import { getPosition } from './position'
import { getKernel } from './kernel'
import { getBackground } from './background'
import { setMetadata, getMetadata } from "../lib/metadata";

export interface ResizeOptions {
width: string
Expand All @@ -14,90 +14,78 @@ export interface ResizeOptions {
ar: string
}

function parseAspect(aspect?: string) {
if (!aspect || !aspect.split) {
return undefined
}

/**
* This function parses a user provided aspect-ratio string into a float.
* Valid syntaxes are `16:9` or `1.777`
* @param aspect
* @returns
*/
function parseAspect(aspect: string): number | undefined {
const parts = aspect.split(':')

let aspectRatio
if (parts.length === 1) {
/* handle decimal aspect ratios, ignore negative values */
const [aspect] = parts
const parsed = parseFloat(aspect)

return parsed > 0 ? parsed : undefined
// the string was a float
aspectRatio = parseFloat(parts[0])
} else if (parts.length === 2) {
/* handle aspect ratio strings */
const [width, height] = parts;
const widthInt = parseInt(width)
const heightInt = parseInt(height)
// the string was a colon delimited aspect ratio
const [width, height] = parts.map(str => parseInt(str));

return widthInt && heightInt && widthInt > 0 && heightInt > 0
? widthInt / heightInt
: undefined
}
if (!width || !height) return undefined

return undefined;
aspectRatio = width / height
}
if(!aspectRatio || aspectRatio <= 0) return undefined
return aspectRatio
}

export const resize: TransformFactory<ResizeOptions> = (config, ctx) => {
const width = parseInt(config.width || config.w || '')
const height = parseInt(config.height || config.h || '')
const aspect = parseAspect(config.aspect || config.ar || '')

const width = config.width
? parseInt(config.width)
: config.w
? parseInt(config.w)
: undefined
const height = config.height
? parseInt(config.height)
: config.h
? parseInt(config.h)
: undefined
const aspect = width && height
? width / height
: parseAspect(config.aspect || config.ar)

if (!width && !height && !aspect) return

return function resizeTransform(image) {
let finalWidth = width
let finalHeight = height

const w = getMetadata(image, 'width')
const h = getMetadata(image, 'height')

const metaAspect = w / h

if (width && height) {
/* both dimensions were provided, aspect is ignored and no calculations are needed */
}
else if (!height && !width) {
/* only aspect was given, need to calculate which dimension to crop */
const useWidth = aspect! > metaAspect

finalHeight = useWidth ? Math.round(w / aspect!) : h
finalWidth = useWidth ? w : Math.round(h / aspect!)
// calculate finalWidth & finalHeight
const originalWidth = getMetadata(image, 'width')
const originalHeight = getMetadata(image, 'height')
const originalAspect = originalWidth / originalHeight

let finalWidth = width, finalHeight = height

if (!width && !height) {
// only aspect was given, need to calculate which dimension to crop
const useWidth = aspect! > originalAspect

if(aspect! > originalAspect) {
finalHeight = originalWidth / aspect!
finalWidth = originalWidth
} else {
finalHeight = originalHeight
finalWidth = originalHeight / aspect!
}
} else if (!height) {
/* only width was provided, need to calculate height */
finalHeight = width! / (aspect || metaAspect)
finalWidth = width
} else {
// only width was provided, need to calculate height

finalHeight = width! / (aspect || originalAspect)
} else if (!width) {
/* only height was provided, need to calculate width */
finalHeight = height
finalWidth = height * (aspect || metaAspect)
finalWidth = height * (aspect || originalAspect)
}

setMetadata(image, 'height', finalHeight)
setMetadata(image, 'width', finalWidth)
setMetadata(image, 'aspect', aspect || metaAspect)
setMetadata(image, 'aspect', aspect || originalAspect)

return image.resize({
width: finalWidth,
height: finalHeight,
width: Math.round(finalWidth) || undefined,
height: Math.round(finalHeight) || undefined,
fit: getFit(config, image),
position: getPosition(config, image),
kernel: getKernel(config, image),
background: getBackground(config, image)
})
}
}
}

0 comments on commit 5b2fca0

Please sign in to comment.