Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a016c53
rename package folder to module
patik Feb 11, 2023
c4ea0cc
use consts in DoF calc
patik Feb 11, 2023
ee95c2e
tweaks
patik Feb 11, 2023
dfa6c7a
aperture calculation and tests
patik Feb 11, 2023
1fdfa36
calculateAperture takes an object for input
patik Feb 11, 2023
39b100e
calculate focal length
patik Feb 11, 2023
a628725
move calculators
patik Feb 11, 2023
b11eefe
accept object for calculateDof function
patik Feb 11, 2023
0d97dc7
export calculators
patik Feb 11, 2023
bb095fe
move unit converters to own file
patik Feb 11, 2023
a970d8a
bump version number to 2.2.0
patik Feb 11, 2023
06ab5ba
Merge branch 'main' into calculate-aperture
patik Feb 12, 2023
32f105c
added calculateCropFactor
patik Feb 13, 2023
c2e3adc
consistent naming of 'near' prop
patik Feb 13, 2023
a481886
Merge branch 'main' into calculate-aperture
patik Mar 4, 2023
f9f9172
tests for aperture mapping
patik Mar 4, 2023
1ec6af7
more tests for aperture mapping
patik Mar 4, 2023
488c2ea
Merge branch 'main' into calculate-aperture
patik Mar 4, 2023
0f46864
fix type import
patik Mar 4, 2023
9762c79
Merge branch 'main' into calculate-aperture
patik Jul 2, 2023
b4f8037
Merge branch 'main' into calculate-aperture
patik Aug 29, 2023
ee20d7b
Merge branch 'main' into calculate-aperture
patik Jan 1, 2024
158f8ec
Merge branch 'main' into calculate-aperture
patik Jan 1, 2024
ea8f9bc
Merge branch 'main' into calculate-aperture
patik Jan 1, 2024
33daea5
Merge branch 'main' into calculate-aperture
patik Dec 7, 2025
ee254d1
post-merge fixes
patik Dec 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
node_modules
gui
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ updates:
interval: daily
open-pull-requests-limit: 5
- package-ecosystem: npm
directory: "/package"
directory: "/module"
schedule:
interval: daily
open-pull-requests-limit: 5
8 changes: 4 additions & 4 deletions .github/workflows/publish-npm-github-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ jobs:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- run: yarn install
- run: yarn --cwd package build
- run: yarn --cwd package publish
- run: yarn --cwd module build
- run: yarn --cwd module publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

Expand All @@ -50,7 +50,7 @@ jobs:
node-version: "24.x"
registry-url: https://npm.pkg.github.com/
- run: yarn install
- run: yarn --cwd package build
- run: yarn --cwd package publish
- run: yarn --cwd module build
- run: yarn --cwd module publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_PUBLISH_TOKEN}}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package/coverage/
module/coverage/
dist/
node_modules/
yarn-error.log
Expand Down
2 changes: 1 addition & 1 deletion app/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface LensInputs {
}

interface LensDefinition extends LensInputs {
depthOfField: import('dof').DepthOfFieldDetails
depthOfField: import('../module/dist').DepthOfFieldDetails
}

type DefaultLensData = Pick<LensDefinition, 'name' | 'focalLength' | 'aperture' | 'sensorKey'>
Expand Down
2 changes: 1 addition & 1 deletion app/src/store/lensSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Lens } from 'dof'
import { Lens } from '../../../module/dist'
import { compact, defaults } from 'lodash'
import { StateCreator } from 'zustand'
import areDuplicateLenses from '../utilities/areDuplicateLenses'
Expand Down
2 changes: 1 addition & 1 deletion app/src/ui/Graph/useData.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LineSeries } from '@nivo/line'
import { Lens } from 'dof'
import { compact } from 'lodash'
import { useMemo } from 'react'
import { Lens } from '../../../../package/dist/Lens'
import useDoFStore from '../../store'
import sensorList from '../../utilities/sensorList'
import useIsMobile from '../../utilities/useIsMobile'
Expand Down
2 changes: 1 addition & 1 deletion app/src/ui/LensTable/Table/Row/Aperture.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'
import { apertureMap } from 'dof'
import { apertureMap } from '../../../../../../module/dist'
import useDoFStore from '../../../../store'
import useIsMobile from '../../../../utilities/useIsMobile'

Expand Down
8 changes: 5 additions & 3 deletions app/src/utilities/sensorList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ const fullList = {
name: '1" CCD, Nikon CX, Sony RX100',
value: 2.72,
},
iPhone14: {
name: 'iPhone 14 (2022)',
value: 2.86, // 9.8x7.3mm, or 71.54mm^2
iPhone14Pro: {
name: 'iPhone 14 Pro (2022)',
// https://www.dpreview.com/articles/6110937480
// 48MP Type 1/1.28 (9.8x7.3mm, or 71.54mm^2)
value: 2.86,
isCommon: true,
},
BlackmagicCC: {
Expand Down
2 changes: 1 addition & 1 deletion app/src/utilities/useReadFromHash.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isApertureString } from 'dof'
import { isApertureString } from '../../../module/dist'
import { compact } from 'lodash'
import { useEffect, useState } from 'react'
import useDoFStore from '../store'
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion package/package.json → module/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dof",
"description": "Depth-of-field calculator for comparing camera lenses",
"version": "3.0.0",
"version": "3.1.0",
"repository": {
"type": "git",
"url": "https://github.com/patik/dof.git"
Expand Down
File renamed without changes.
10 changes: 8 additions & 2 deletions package/src/Lens.ts → module/src/Lens.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { calculateDepthOfField } from './calculators/calculateDepthOfField'
import { combineSettings } from './utilities/combineSettings'
import { calculateDepthOfField } from './utilities/calculateDepthOfField'

export const builtInDefaults: DefaultOptions = Object.freeze({
focalLength: 35,
Expand Down Expand Up @@ -45,6 +45,12 @@ export class Lens {
distance = imperialUnits ? defaultDistanceImperial : defaultDistanceMetric
}

return calculateDepthOfField(this.focalLength, this.aperture, this.cropFactor, distance, imperialUnits)
return calculateDepthOfField({
focalLength: this.focalLength,
aperture: this.aperture,
cropFactor: this.cropFactor,
distance,
imperialUnits,
})
}
}
86 changes: 86 additions & 0 deletions module/src/calculators/calculateAperture.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { calculateAperture } from './calculateAperture'

describe('Calculating the depth of field with calculateAperture()', () => {
describe('metric units (meters)', () => {
test('DoF 2.6 meters, 35mm, f/2, crop factor of 1, 5 meters', () => {
const result = calculateAperture({
focalLength: 35,
cropFactor: 1,
distance: 5,
dof: 2.584690961719362,
near: 4.021931840567339,
imperialUnits: false,
})

expect(result.aperture).toBe(2)
})

test('DoF 11 meters, 50mm, f/1.4, crop factor of 2, 25 meters', () => {
const result = calculateAperture({
focalLength: 50,
cropFactor: 2,
distance: 25,
dof: 11.082093523926748,
near: 20.63203625607849,
imperialUnits: false,
})

expect(result.aperture).toBe(1.4142139999999992)
})

test('DoF 7.9 meters, 28mm, f/5, crop factor of 3.02, 7 meters', () => {
// Blackmagic Cine Cam sensor
const result = calculateAperture({
focalLength: 28,
cropFactor: 3.02,
distance: 7,
dof: 7.851429380291624,
near: 4.833680315786585,
imperialUnits: false,
})

expect(result.aperture).toBe(5.039684)
})

test('such that the far end of the range is infinity', () => {
const result = calculateAperture({
focalLength: 24,
cropFactor: 1,
distance: 5,
dof: Infinity,
near: 0.9715025906735751,
imperialUnits: false,
})

expect(result.aperture).toBe(NaN)
})
})

describe('imperial units (feet)', () => {
test('DoF 7 feet, 35mm, f/2, crop factor of 1, 15 feet', () => {
const result = calculateAperture({
focalLength: 35,
cropFactor: 1,
distance: 15,
dof: 7.012923816256398,
near: 12.27274548830499,
imperialUnits: true,
})

expect(result.aperture).toBe(2.000000000000001)
})

test('DoF 12.6 feet, 55mm, f/3.2, crop factor of 2.7, 42 feet', () => {
const result = calculateAperture({
focalLength: 55,
cropFactor: 2.7,
distance: 42,
dof: 12.634717336600715,
near: 36.61227928000945,
imperialUnits: true,
})

expect(result.aperture).toBe(3.1748020000000055)
})
})
})
38 changes: 38 additions & 0 deletions module/src/calculators/calculateAperture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getApertureName } from '../utilities/aperture'
import { toMillimeters } from '../utilities/units'

/**
* Returns the aperture for a given lens' attributes and depth of field
*/
export function calculateAperture({
focalLength,
cropFactor,
distance,
dof,
near,
imperialUnits,
}: {
focalLength: number
cropFactor: number
distance: number
dof: number
near: number
imperialUnits?: boolean
}): ApertureResult {
const mmDist = toMillimeters(distance, imperialUnits)
const mmDof = toMillimeters(dof, imperialUnits)
const mmNear = toMillimeters(near, imperialUnits)

const mmFar = mmNear + mmDof
const mmHF = (-1 * mmDist * focalLength + mmDist * mmFar) / (-1 * mmDist + mmFar)
const cropMultiplier = 1 / cropFactor
const coc = Math.round(0.03 * cropMultiplier * 1000) / 1000
const aperture = Math.pow(focalLength, 2) / (coc * mmHF - coc * focalLength)

const result: ApertureResult = {
aperture,
fStop: getApertureName(aperture),
}

return result
}
73 changes: 73 additions & 0 deletions module/src/calculators/calculateCropFactor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { calculateCropFactor } from './calculateCropFactor'

describe('Calculating the depth of field with calculateCropFactor()', () => {
describe('metric units (meters)', () => {
test('35mm, f/2, crop factor of 1, 5 meters', () => {
const result = calculateCropFactor({
dof: 2.584690961719362,
near: 4.021931840567339,
focalLength: 35,
aperture: 2,
distance: 5,
imperialUnits: false,
})

expect(result.cropFactor).toBe(1)
})

test('50mm, f/1.4, crop factor of 2, 25 meters', () => {
const result = calculateCropFactor({
dof: 11.082093523926748,
near: 20.63203625607849,
focalLength: 50,
aperture: 1.414214,
distance: 25,
imperialUnits: false,
})

expect(result.cropFactor).toBe(2)
})

test('28mm, f/5, crop factor of 3.02, 7 meters', () => {
// Blackmagic Cine Cam sensor
const result = calculateCropFactor({
focalLength: 28,
aperture: 5.039684,
dof: 7.851429380291624,
near: 4.833680315786585,
distance: 7,
imperialUnits: false,
})

expect(result.cropFactor).toBe(3)
})
})

describe('imperial units (feet)', () => {
test('35mm, f/2, crop factor of 1, 15 feet', () => {
const result = calculateCropFactor({
focalLength: 35,
aperture: 2,
near: 12.27274548830499,
dof: 7.012923816256398,
distance: 15,
imperialUnits: true,
})

expect(result.cropFactor).toBe(1)
})

test('55mm, f/3.2, crop factor of 2.7, 42 feet', () => {
const result = calculateCropFactor({
focalLength: 55,
aperture: 3.174802,
dof: 12.634717336600715,
near: 36.61227928000945,
distance: 42,
imperialUnits: true,
})

expect(result.cropFactor).toBe(2.727)
})
})
})
32 changes: 32 additions & 0 deletions module/src/calculators/calculateCropFactor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { toMillimeters } from '../utilities/units'

/**
* Returns the depth of field characteristics for a given lens' attributes
*/
export function calculateCropFactor({
near,
dof,
focalLength,
aperture,
distance,
imperialUnits,
}: {
near: number
dof: number
focalLength: number
aperture: number
distance: number
imperialUnits: boolean
}): CropFactorResult {
const mmDist = toMillimeters(distance, imperialUnits)
const mmDof = toMillimeters(dof, imperialUnits)
const mmNear = toMillimeters(near, imperialUnits)

const mmFar = mmNear + mmDof
const mmHF = (-1 * mmDist * focalLength + mmDist * mmFar) / (-1 * mmDist + mmFar)
const coc = Math.pow(focalLength, 2) / (aperture * mmHF - aperture * focalLength)
const cropMultiplier = (100 * coc) / 3
const cropFactor = Math.round((1 / cropMultiplier) * 1000) / 1000

return { cropFactor }
}
Loading
Loading