Skip to content

Commit

Permalink
feat: Custom sort (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhea-so committed May 8, 2024
2 parents 3d1d9f6 + ffb2b0e commit 3b2ccb5
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 40 deletions.
27 changes: 18 additions & 9 deletions web/src/themes/03_ONE_LINE/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const ONE_LINE_OPTIONS: ThemeOption[] = [
{ id: 'FONT_SIZE', type: 'number', default: 70, description: 'px' },
{ id: 'FONT_FAMILY', type: 'select', options: ['Barlow', ...Object.values(Font)], default: 'Barlow', description: 'ex. din-alternate-bold, digital-7, Barlow, Arial, sans-serif' },
{ id: 'TOP_LABEL', type: 'string', default: '', description: 'ex. @username' },
{ id: 'DIVIDER', type: 'string', default: '|', description: 'ex. ∙' },
{ id: 'DIVIDER', type: 'string', default: '∙', description: 'ex. |' },
{ id: 'TEMPLATE', type: 'string', default: '{MAKER}{BODY}{LENS}{ISO}{MM}{F}{SEC}' },
];

const ONE_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Store) => {
Expand All @@ -37,6 +38,7 @@ const ONE_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store:
const FONT_FAMILY = (input.get('FONT_FAMILY') as string).trim();
const TOP_LABEL = (input.get('TOP_LABEL') as string).trim();
const DIVIDER = (input.get('DIVIDER') as string).trim();
const TEMPLATE = (input.get('TEMPLATE') as string).trim();

const canvas = sandbox(photo, {
targetRatio: store.ratio,
Expand All @@ -54,14 +56,21 @@ const ONE_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store:

context.textAlign = TEXT_ALIGN as CanvasTextAlign;

context.fillText(
[photo.make, photo.model, photo.lensModel, ...(store.disableExposureMeter ? [] : [`${photo.iso}`, `${photo.focalLength}`, `${photo.fNumber}`, `${photo.exposureTime}`])]
.filter(Boolean)
.map((value) => value!.trim())
.join(` ${DIVIDER} `),
TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT,
canvas.height - PADDING_BOTTOM / 2
);
const text = TEMPLATE.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ' + DIVIDER + ' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

context.fillText(text, TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT, canvas.height - PADDING_BOTTOM / 2);

return canvas;
};
Expand Down
49 changes: 35 additions & 14 deletions web/src/themes/04_TWO_LINE/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const TWO_LINE_OPTIONS: ThemeOption[] = [
{ id: 'FONT_SIZE', type: 'number', default: 70, description: 'px' },
{ id: 'FONT_FAMILY', type: 'select', options: ['Barlow', ...Object.values(Font)], default: 'Barlow', description: 'ex. din-alternate-bold, digital-7, Barlow, Arial, sans-serif' },
{ id: 'TOP_LABEL', type: 'string', default: '', description: 'ex. @username' },
{ id: 'DIVIDER', type: 'string', default: '|', description: 'ex. ∙' },
{ id: 'DIVIDER', type: 'string', default: '∙', description: 'ex. |' },
{ id: 'TEMPLATE1', type: 'string', default: '{MAKER}{BODY}{LENS}' },
{ id: 'TEMPLATE2', type: 'string', default: '{ISO}{MM}{F}{SEC}' },
];

const TWO_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Store) => {
Expand All @@ -37,6 +39,8 @@ const TWO_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store:
const FONT_FAMILY = (input.get('FONT_FAMILY') as string).trim();
const TOP_LABEL = (input.get('TOP_LABEL') as string).trim();
const DIVIDER = (input.get('DIVIDER') as string).trim();
const TEMPLATE1 = (input.get('TEMPLATE1') as string).trim();
const TEMPLATE2 = (input.get('TEMPLATE2') as string).trim();

const canvas = sandbox(photo, {
targetRatio: store.ratio,
Expand All @@ -52,22 +56,39 @@ const TWO_LINE_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store:
context.textAlign = 'center';
context.fillText(TOP_LABEL, canvas.width / 2, PADDING_TOP / 2);

const text1 = TEMPLATE1.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ' + DIVIDER + ' ')
.replace('{MAKER}', photo.make)
.replace('{BODY}', photo.model || '')
.replace('{LENS}', photo.lensModel || '')
.replace('{ISO}', store.disableExposureMeter ? '' : photo.iso || '')
.replace('{MM}', store.disableExposureMeter ? '' : photo.focalLength || '')
.replace('{F}', store.disableExposureMeter ? '' : photo.fNumber || '')
.replace('{SEC}', store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace('{TAKEN_AT}', photo.takenAt || '')
.replace('}', '');

context.textAlign = TEXT_ALIGN as CanvasTextAlign;
context.fillText(
[photo.make, photo.model, photo.lensModel]
.filter(Boolean)
.map((value) => value!.trim())
.join(` ${DIVIDER} `),
TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT,
canvas.height - PADDING_BOTTOM / 2 - FONT_SIZE / 1.5
);
context.fillText(text1, TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT, canvas.height - PADDING_BOTTOM / 2 - FONT_SIZE / 1.5);

if (!store.disableExposureMeter) {
context.fillText(
[`${photo.iso}`, `${photo.focalLength}`, `${photo.fNumber}`, `${photo.exposureTime}`].filter(Boolean).join(` ${DIVIDER} `),
TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT,
canvas.height - PADDING_BOTTOM / 2 + FONT_SIZE / 1.5
);
const text2 = TEMPLATE2.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ' + DIVIDER + ' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

context.fillText(text2, TEXT_ALIGN === 'left' ? PADDING_LEFT : TEXT_ALIGN === 'center' ? canvas.width / 2 : canvas.width - PADDING_RIGHT, canvas.height - PADDING_BOTTOM / 2 + FONT_SIZE / 1.5);
}

return canvas;
Expand Down
85 changes: 68 additions & 17 deletions web/src/themes/07_STRAP/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const STRAP_OPTIONS: ThemeOption[] = [
{ id: 'PADDING_BOTTOM', type: 'number', default: 0, description: 'px' },
{ id: 'PADDING_LEFT', type: 'number', default: 0, description: 'px' },
{ id: 'PADDING_RIGHT', type: 'number', default: 0, description: 'px' },
{ id: 'TEMPLATE1', type: 'string', default: '{ISO}{MM}{F}{SEC}' },
{ id: 'TEMPLATE2', type: 'string', default: '{MAKER}{BODY}' },
{ id: 'TEMPLATE3', type: 'string', default: '{TAKEN_AT}' },
{ id: 'TEMPLATE4', type: 'string', default: '{LENS}' },
];

const STRAP_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Store) => {
Expand All @@ -67,11 +71,71 @@ const STRAP_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Sto
const PADDING_BOTTOM = (input.get('PADDING_BOTTOM') as number) + 300;
const PADDING_LEFT = input.get('PADDING_LEFT') as number;
const PADDING_RIGHT = input.get('PADDING_RIGHT') as number;
const TEMPLATE1 = (input.get('TEMPLATE1') as string).trim();
const TEMPLATE2 = (input.get('TEMPLATE2') as string).trim();
const TEMPLATE3 = (input.get('TEMPLATE3') as string).trim();
const TEMPLATE4 = (input.get('TEMPLATE4') as string).trim();
const FONT_SIZE = 70;
const BACKGROUND_COLOR = DARK_MODE ? '#000000' : '#ffffff';
const PRIMARY_TEXT_COLOR = DARK_MODE ? '#ffffff' : '#000000';
const SECONDARY_TEXT_COLOR = DARK_MODE ? '#888888' : '#333333';

const text1 = TEMPLATE1.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

const text2 = TEMPLATE2.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

const text3 = TEMPLATE3.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

const text4 = TEMPLATE4.split('}')
.filter(Boolean)
.map((part) => `${part}}`)
.join(' ')
.replace(/{MAKER}/g, photo.make)
.replace(/{BODY}/g, photo.model || '')
.replace(/{LENS}/g, photo.lensModel || '')
.replace(/{ISO}/g, store.disableExposureMeter ? '' : photo.iso || '')
.replace(/{MM}/g, store.disableExposureMeter ? '' : photo.focalLength || '')
.replace(/{F}/g, store.disableExposureMeter ? '' : photo.fNumber || '')
.replace(/{SEC}/g, store.disableExposureMeter ? '' : photo.exposureTime || '')
.replace(/{TAKEN_AT}/g, photo.takenAt || '')
.replace(/}/g, '');

const canvas = sandbox(photo, {
targetRatio: store.ratio,
notCroppedMode: store.notCroppedMode,
Expand All @@ -89,14 +153,7 @@ const STRAP_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Sto
context.fillStyle = PRIMARY_TEXT_COLOR;

if (!store.disableExposureMeter) {
context.fillText(
[`${photo.iso}`, `${photo.focalLength}`, `${photo.fNumber}`, `${photo.exposureTime}`]
.filter(Boolean)
.map((value) => value.trim())
.join(' '),
FONT_SIZE,
canvas.height - PADDING_BOTTOM / 2 - FONT_SIZE / 2
);
context.fillText(text1, FONT_SIZE, canvas.height - PADDING_BOTTOM / 2 - FONT_SIZE / 2);
}

// Shot by
Expand All @@ -107,7 +164,7 @@ const STRAP_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Sto
} else {
context.font = `normal ${SECONDARY_TEXT_FONT_WEIGHT} ${FONT_SIZE}px Barlow`;
context.fillStyle = SECONDARY_TEXT_COLOR;
context.fillText(photo.takenAt, FONT_SIZE, canvas.height - PADDING_BOTTOM / 2 + FONT_SIZE / 2);
context.fillText(text3, FONT_SIZE, canvas.height - PADDING_BOTTOM / 2 + FONT_SIZE / 2);
}

// RIGHT SECOND
Expand All @@ -116,20 +173,14 @@ const STRAP_FUNC: ThemeFunc = (photo: Photo, input: ThemeOptionInput, store: Sto
// Maker, Model
context.fillStyle = PRIMARY_TEXT_COLOR;
context.font = `normal 500 ${FONT_SIZE}px Barlow`;
const makerModelText = [photo.make, photo.model]
.filter(Boolean)
.map((value) => value!.trim())
.join(' ');
const makerModelText = text2;
const topWidth = context.measureText(makerModelText).width;
context.fillText(makerModelText, canvas.width - FONT_SIZE, canvas.height - PADDING_BOTTOM / 2 - FONT_SIZE / 2);

// Lens Model
context.fillStyle = SECONDARY_TEXT_COLOR;
context.font = `normal ${SECONDARY_TEXT_FONT_WEIGHT} ${FONT_SIZE}px Barlow`;
const lensModelText = [photo.lensModel]
.filter(Boolean)
.map((value) => value!.trim())
.join(' ');
const lensModelText = text4;
const bottomWidth = context.measureText(lensModelText).width;
context.fillText(lensModelText, canvas.width - FONT_SIZE, canvas.height - PADDING_BOTTOM / 2 + FONT_SIZE / 2);

Expand Down

0 comments on commit 3b2ccb5

Please sign in to comment.