Skip to content

Commit

Permalink
Type the lib (#25)
Browse files Browse the repository at this point in the history
* WIP: start typing the lib

* more types

* complete typings...
  • Loading branch information
erikengervall authored Oct 13, 2021
1 parent 249f051 commit 401150a
Show file tree
Hide file tree
Showing 23 changed files with 1,004 additions and 486 deletions.
14 changes: 0 additions & 14 deletions .eslintrc.js

This file was deleted.

21 changes: 21 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"env": {
"es6": true,
"node": false
},
"parserOptions": {
"sourceType": "module"
},
"rules": {
"prettier/prettier": "error",
"@typescript-eslint/explicit-module-boundary-types": "off"
},
"plugins": ["@typescript-eslint", "prettier"]
}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ _loc
npm-debug.log
.DS_Store
config.cson
yarn-error.log
yarn-error.log
dist
14 changes: 7 additions & 7 deletions dist/parallax-vanilla.js

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions dist/src/ts/constants.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Settings } from './types';
export declare const VIDEO_EXTENSIONS: string[];
export declare const MEDIA_TYPES: {
image: 'image';
video: 'video';
none: 'none';
};
export declare const ELEMENT_DATA_KEYS: {
MEDIAPATH: string;
MEDIATYPE: string;
MUTE: string;
HEIGHT: string;
SPEED: string;
};
export declare const defaultSettings: Settings;
2 changes: 2 additions & 0 deletions dist/src/ts/init.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { Settings } from './types';
export declare const init: (userSettings: Partial<Settings>) => void;
9 changes: 9 additions & 0 deletions dist/src/ts/initBlock.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Block, Container, Settings } from './types';
export declare const setBlockSpeed: (blockEl: HTMLElement, settings: Settings) => number;
export declare const setBlockMediaProps: (blockEl: HTMLElement, settings: Settings) => {
mediatype: "image" | "video" | "none";
mediapath: string | null;
};
export declare const setBlockMute: (blockEl: HTMLElement, settings: Settings) => boolean;
export declare const setBlockVisual: (block: Block) => void;
export declare const setBlockAttributes: (container: Container, block: Block) => void;
2 changes: 2 additions & 0 deletions dist/src/ts/initContainer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { Settings } from './types';
export declare const setContainerHeight: (containerEl: HTMLElement, settings: Settings) => string;
1 change: 1 addition & 0 deletions dist/src/ts/parallax-vanilla.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '../less/parallax-vanilla.less';
1 change: 1 addition & 0 deletions dist/src/ts/resize.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export declare const resize: () => void;
1 change: 1 addition & 0 deletions dist/src/ts/translate.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export declare const translate: () => void;
42 changes: 42 additions & 0 deletions dist/src/ts/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { MEDIA_TYPES } from './constants';
export interface Settings {
container: {
class: string;
height: string;
};
block: {
class: string;
speed: number;
mediatype: keyof typeof MEDIA_TYPES;
mediapath: null;
mute: boolean;
};
}
export interface Block {
blockEl: HTMLElement;
speed: number;
mediatype: string | null;
mediapath: string | null;
mute: boolean;
muted: boolean;
videoEl?: HTMLVideoElement;
audioButton?: HTMLAnchorElement;
}
export interface Container {
containerEl: HTMLElement;
offset: number;
height: number;
blocks: Block[];
hasVideoBlock?: boolean;
}
export declare type PV = any;
export interface Window {
raf: typeof window.requestAnimationFrame;
pv?: PV;
orientation: typeof window.orientation;
requestAnimationFrame: typeof window.requestAnimationFrame;
webkitRequestAnimationFrame: typeof window.requestAnimationFrame;
mozRequestAnimationFrame: typeof window.requestAnimationFrame;
setTimeout: typeof window.setTimeout;
onresize: () => void;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
},
"dependencies": {},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.29.3",
"@typescript-eslint/parser": "^4.29.3",
"concurrently": "^4.1.2",
"css-loader": "^3.2.0",
"eslint": "^6.3.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^6.1.0",
"eslint-plugin-prettier": "^3.1.0",
"express": "^4.16.2",
Expand Down
18 changes: 12 additions & 6 deletions src/ts/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Settings } from './types'

export const VIDEO_EXTENSIONS = [
'3g2',
'3gp',
Expand All @@ -18,10 +20,14 @@ export const VIDEO_EXTENSIONS = [
'wmv',
]

export const MEDIA_TYPES = {
IMAGE: 'image',
VIDEO: 'video',
NONE: 'none',
export const MEDIA_TYPES: {
image: 'image'
video: 'video'
none: 'none'
} = {
image: 'image',
video: 'video',
none: 'none',
}

export const ELEMENT_DATA_KEYS = {
Expand All @@ -32,15 +38,15 @@ export const ELEMENT_DATA_KEYS = {
SPEED: 'pv-speed',
}

export const defaultSettings = {
export const defaultSettings: Settings = {
container: {
class: 'pv-container',
height: '250px',
},
block: {
class: 'pv-block',
speed: -Math.PI,
mediatype: MEDIA_TYPES.IMAGE,
mediatype: MEDIA_TYPES.image,
mediapath: null,
mute: false,
},
Expand Down
94 changes: 49 additions & 45 deletions src/ts/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,51 @@ import {
setBlockVisual,
setBlockAttributes,
} from './initBlock'
import { Block, Container, Settings, Window } from './types'

export default (userSettings: any) => {
const pv = (<any>window).pv
export const init = (userSettings: Partial<Settings>) => {
const { pv } = (window as unknown) as Window
pv.containerArr = []
pv.settings = mergeSettings(userSettings, defaultSettings)

const containerElements = document.getElementsByClassName(pv.settings.container.class)
for (let i = 0; i < containerElements.length; i++) {
const container: any = {}

container.el = containerElements[i]
container.offset = calculateOffsetTop(container.el)
container.el.style.height = setContainerHeight(container, pv.settings)
container.height = container.el.clientHeight

container.blocks = []
for (let i = 0; i < containerElements.length; i++) {
const containerEl = containerElements[i] as HTMLElement
const offset = calculateOffsetTop(containerEl)
containerEl.style.height = setContainerHeight(containerEl, pv.settings)
const height = containerEl.clientHeight
const blocks: Block[] = []

const container: Container = {
containerEl,
offset,
height,
blocks,
}

const blockElements = containerElements[i].getElementsByClassName(pv.settings.block.class)
for (let j = 0; j < blockElements.length; j++) {
const block: any = {}

block.el = blockElements[j]
block.speed = setBlockSpeed(block, pv.settings)
const { mediatype, mediapath } = setBlockMediaProps(block, pv.settings)
block.mediatype = mediatype
block.mediapath = mediapath
block.mute = setBlockMute(block, pv.settings)

if (block.mediatype !== MEDIA_TYPES.NONE) {
if (block.mediatype === MEDIA_TYPES.VIDEO) container.hasVideoBlock = true
for (let j = 0; j < blockElements.length; j++) {
const blockEl = blockElements[j] as HTMLElement
const speed = setBlockSpeed(blockEl, pv.settings)
const { mediatype, mediapath } = setBlockMediaProps(blockEl, pv.settings)

const block: Block = {
blockEl,
speed,
mediatype,
mediapath,
mute: setBlockMute(blockEl, pv.settings),
muted: false,
}

const successful = setBlockVisual(block)
if (!successful) {
console.error('Did not successfully set media for block:', block)
throw new Error('Did not successfully set media')
if (block.mediatype !== MEDIA_TYPES.none) {
if (block.mediatype === MEDIA_TYPES.video) {
container.hasVideoBlock = true
}

setBlockVisual(block)
setBlockAttributes(container, block)
}

Expand All @@ -54,30 +62,26 @@ export default (userSettings: any) => {
}
}

const mergeSettings = (userSettings: any = {}, defaultSettings: any) => {
Object.keys(userSettings).forEach(elementSettings => {
if (!(userSettings[elementSettings] instanceof Object)) {
throw new Error(`Expected ${elementSettings} to be of instance Object`)
}

Object.keys(userSettings[elementSettings]).forEach(setting => {
if (userSettings[elementSettings][setting] instanceof Object) {
throw new Error(`Expected ${elementSettings} to be primitive value`)
}
if (!defaultSettings[elementSettings].hasOwnProperty(setting)) {
throw new Error(`Expected ${setting} to match available settings`)
}

defaultSettings[elementSettings][setting] = userSettings[elementSettings][setting]
})
})

return defaultSettings
const mergeSettings = (
userSettings: Partial<Settings> = {},
defaultSettings: Settings
): Settings => {
return {
container: {
...defaultSettings.container,
...userSettings.container,
},
block: {
...defaultSettings.block,
...userSettings.block,
},
}
}

// Calculates the top offset from an element to the window's || document's top, Link: https://plainjs.com/javascript/styles/get-the-position-of-an-element-relative-to-the-document-24/
const calculateOffsetTop = (el: any) => {
const calculateOffsetTop = (el: HTMLElement) => {
const rectTop = el.getBoundingClientRect().top
const scrollTop = window.pageYOffset || document.documentElement.scrollTop

return rectTop + scrollTop
}
Loading

0 comments on commit 401150a

Please sign in to comment.