Skip to content

Commit

Permalink
build: enable TypeScript strict mode
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMalch committed Nov 13, 2020
1 parent a1b13a4 commit e3400db
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 56 deletions.
16 changes: 10 additions & 6 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,28 @@
let previewVisible = false;
let loadedImages: Array<{ src: string; alt: string }> = [];
let loadedImages: Array<{ src: string | null; alt: string | null }> = [];
let imageElements: HTMLImageElement[] = [];
let canvasReady = false;
async function onFilesChange({ detail: fileList }) {
async function onFilesChange({ detail: fileList }: { detail: File[] }) {
imageElements = []; // make canvas not ready while images are loading
loadedImages.forEach((img) => URL.revokeObjectURL(img.src));
loadedImages.forEach((img) => {
if (img?.src != null) {
URL.revokeObjectURL(img.src)
}
});
loadedImages = fileList.map((file) => ({
src: file == null ? null : URL.createObjectURL(file),
alt: file?.name,
alt: file?.name ?? null,
}));
imageElements = await Promise.all(
loadedImages.map((img) => loadIntoImage(img.src))
loadedImages.map((img) => loadIntoImage(img?.src ?? null))
);
}
function loadIntoImage(source: string): Promise<HTMLImageElement> {
function loadIntoImage(source: string | null): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
if (source == null) {
return Promise.resolve(null);
Expand Down
27 changes: 16 additions & 11 deletions src/components/Canvas.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { checks, isDefined } from 'ts-code-contracts';
import { drawGlue } from '../drawing/glue';
import { magicScale, magicWidth } from '../formulas/content';
import { degreeToRadian } from '../formulas/math';
import { leftwardTriangle, rightwardTriangle } from '../shapes';
import type { ProcessingOptions } from '../types';
import TriangleProcessing from './TriangleProcessing.svelte';
export let drawables: HTMLImageElement[] = [];
Expand All @@ -24,7 +26,7 @@
}
}
const lookup = [
const lookup: ProcessingOptions[] = [
{
relativeRectangle: {
x: 0.5 - magicWidth,
Expand All @@ -43,12 +45,12 @@
},
{
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(-90));
ctx.drawImage(prev, prev.width * -1, 0);
},
secondRotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.translate(0, canvas.height / 2);
ctx.rotate(degreeToRadian(-30));
ctx.drawImage(prev, 0, 0);
Expand All @@ -66,12 +68,12 @@
},
{
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(-30));
ctx.drawImage(prev, 0, 0);
},
secondRotation: (canvas, prev) => {
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(-90));
ctx.drawImage(prev, -1 * inputValues.triangleBase, 0);
},
Expand All @@ -88,12 +90,12 @@
},
{
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(90));
ctx.drawImage(prev, 0, canvas.width * -1);
},
secondRotation: (canvas, prev) => {
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d')!;
ctx.translate(canvas.width, canvas.height);
ctx.rotate(degreeToRadian(30));
ctx.drawImage(prev, -1 * canvas.height, -1 * canvas.width);
Expand All @@ -111,13 +113,13 @@
},
{
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.translate(canvas.width, 0);
ctx.rotate(degreeToRadian(90));
ctx.drawImage(prev, 0, 0);
},
secondRotation: (canvas, prev) => {
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(30));
ctx.drawImage(prev, 0, 0);
},
Expand Down Expand Up @@ -152,10 +154,11 @@
);
function onProcessingFinish(
{ detail: partialCanvas },
{ detail: partialCanvas }: { detail: HTMLCanvasElement },
line: number,
index: number
) {
checks(isDefined(ctx), 'Canvas context must be available')
if (line % 2 === 0) {
if (index === 0) {
ctx.drawImage(
Expand Down Expand Up @@ -188,7 +191,9 @@
{#each triangleSetups as setup, i}
<strong>A{i}</strong>
<TriangleProcessing
{...setup}
options="{setup}"
image="{setup.image}"
clippingTriangle="{setup.clippingTriangle}"
inputValues="{inputValues}"
scalingFactor="{magicScale}"
on:finish="{(ev) => onProcessingFinish(ev, line, i)}" />
Expand Down
10 changes: 5 additions & 5 deletions src/components/FileInputs.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let images: { src: string; alt: string }[] = [];
export let images: { src: string | null; alt: string | null }[] = [];
const dispatch = createEventDispatcher();
let inputs: HTMLInputElement[] = Array(4).fill(null);
function onInputChange(_: Event, index: number) {
const originalFiles = inputs[index].files;
const originalFiles = inputs[index].files!;
const bound = Math.min(4, index + originalFiles.length);
for (let i = index; i < bound; i++) {
const list = new DataTransfer();
list.items.add(originalFiles.item(i - index));
list.items.add(originalFiles.item(i - index)!);
inputs[i].files = list.files;
}
const files = inputs.map((input) => input.files.item(0));
const files = inputs.map((input) => input.files!.item(0));
dispatch('filesChange', files);
}
</script>
Expand All @@ -25,7 +25,7 @@
{#each inputs as _, i}
<div class="box-shadow">
{#if images[i] != null}
<img src="{images[i].src}" alt="{images[i].alt}}" />
<img src="{images[i].src ?? undefined}" alt="{images[i].alt}}" />
{/if}
<label for="file-{i}">
{images[i] == null ? `Select one ${i !== 3 ? 'or more' : ''} image${i === 3 ? '' : 's'}.` : 'Swap image.'}
Expand Down
53 changes: 21 additions & 32 deletions src/components/TriangleProcessing.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,35 @@
import { ORIGIN } from '../factories';
import { magicWidth } from '../formulas/content';
import type {
InputValues,
Rectangle,
RectangleDef,
InputValues, ProcessingOptions,
TriangleDef,
} from '../types';
export let options: ProcessingOptions;
export let image: HTMLImageElement;
export let inputValues: InputValues;
export let rotation: (
canvas: HTMLCanvasElement,
previous: HTMLCanvasElement
) => void;
export let secondRotation: (
canvas: HTMLCanvasElement,
previous: HTMLCanvasElement
) => void;
export let secondCanvasDimensions: (
defaultWidth: number,
defaultHeight: number
) => RectangleDef = (w, h) => ({ width: w, height: h });
export let scalingFactor: number;
export let clippingTriangle: TriangleDef;
export let relativeRectangle: Rectangle;
/**
* @deprecated remove from application
*/
let showLines = false;
let toTriangleCanvas: HTMLCanvasElement | null = null;
let rotatedTriangleCanvas: HTMLCanvasElement | null = null;
let fullRotatedTriangleCanvas: HTMLCanvasElement | null = null;
let scaledRotatedTriangleCanvas: HTMLCanvasElement | null = null;
let toTriangleCanvas: HTMLCanvasElement; // | null = null;
let rotatedTriangleCanvas: HTMLCanvasElement; // | null = null;
let fullRotatedTriangleCanvas: HTMLCanvasElement; // | null = null;
let scaledRotatedTriangleCanvas: HTMLCanvasElement; // | null = null;
$: secondCanvasDimensions = options?.secondCanvasDimensions ?? ((width, height) => ({ width, height })) as NonNullable<ProcessingOptions["secondCanvasDimensions"]>;
const dispatch = createEventDispatcher();
afterUpdate(() => redraw());
function loadIntoTriangleCanvas() {
const ctx = toTriangleCanvas.getContext('2d');
const ctx = toTriangleCanvas!.getContext('2d')!;
ctx.clearRect(0, 0, toTriangleCanvas.width, toTriangleCanvas.height);
ctx.save();
Expand All @@ -67,10 +56,10 @@
height: toTriangleCanvas.height,
},
{
x: relativeRectangle.x * image.naturalWidth,
y: relativeRectangle.y * image.naturalHeight,
width: relativeRectangle.width * image.naturalWidth,
height: relativeRectangle.height * image.naturalHeight,
x: options.relativeRectangle.x * image.naturalWidth,
y: options.relativeRectangle.y * image.naturalHeight,
width: options.relativeRectangle.width * image.naturalWidth,
height: options.relativeRectangle.height * image.naturalHeight,
}
);
}
Expand All @@ -80,29 +69,29 @@
}
function loadIntoRotatedCanvas() {
const ctx = rotatedTriangleCanvas.getContext('2d');
const ctx = rotatedTriangleCanvas!.getContext('2d')!;
ctx.save();
if (rotation) {
rotation(rotatedTriangleCanvas, toTriangleCanvas);
if (options.rotation) {
options.rotation(rotatedTriangleCanvas, toTriangleCanvas);
} else {
ctx.drawImage(toTriangleCanvas, 0, 0);
}
ctx.restore();
}
function loadIntoFullRotatedCanvas() {
const ctx = fullRotatedTriangleCanvas.getContext('2d');
const ctx = fullRotatedTriangleCanvas!.getContext('2d')!;
ctx.save();
if (secondRotation) {
secondRotation(fullRotatedTriangleCanvas, rotatedTriangleCanvas);
if (options.secondRotation) {
options.secondRotation(fullRotatedTriangleCanvas, rotatedTriangleCanvas);
} else {
ctx.drawImage(rotatedTriangleCanvas, 0, 0);
}
ctx.restore();
}
function loadIntoScaledCanvas() {
const ctx = scaledRotatedTriangleCanvas.getContext('2d');
const ctx = scaledRotatedTriangleCanvas!.getContext('2d')!;
ctx.save();
drawImage(
ctx,
Expand Down
10 changes: 9 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { magicWidth } from './formulas/content';
import { degreeToRadian } from './formulas/math';

/**
* Describes a single point.
*/
Expand Down Expand Up @@ -47,4 +50,9 @@ export interface NaturalImage {
naturalHeight: number;
}

export type Drawable = CanvasImageSource | string; // TODO: 4.1 BETA? for generic string patterns (#rrggbb)
export interface ProcessingOptions {
rotation?: (canvas: HTMLCanvasElement, prev: HTMLCanvasElement) =>void;
secondRotation?: (canvas: HTMLCanvasElement, prev: HTMLCanvasElement) =>void;
secondCanvasDimensions?: (defaultWidth: number, defaultHeight: number) => RectangleDef;
relativeRectangle: Rectangle;
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
"compilerOptions": {
"types": ["jest"]
"types": ["jest"],
"strict": true
}
}

0 comments on commit e3400db

Please sign in to comment.