npm package: @poengalex/handy-utils
Description: Utils lib for Handy applications
Author: poengAlex
Latest version: 1.5.2

# How to use
## Browser 
Latest:
```html
<script src="https://unpkg.com/@poengalex/handy-utils"></script>
```

Specific version:
```html
<script src="https://unpkg.com/@poengalex/handy-utils@1.0.2"></script>
```

Latest of major
```html
<script src="https://unpkg.com/@poengalex/handy-utils@1"></script>
```

Example of use:
Utils.FUNCTION_NAME or Utils.VARIABLE_NAME
```js
let funscript = Utils.generateFunscript(1000,100);
```

## Info

### Links

[Bootstrap website](https://getbootstrap.com/docs/5.1/getting-started/introduction/)
[html2canvas website](https://html2canvas.hertzen.com/)
### Bootstrap
If you want to use the bootstrap functions in this lib add bootstrap to your project.

You will need to attach bootrap to the window for the lib to have access to the bootrap lib:
```js
    window.bootstrap = bootstrap;
```

Bootstrap version 5.1.3

Add the css file to the header:
```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
```

Add the js file before the utils lib:
```html
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

```

### Html2canvas
Add html2canvas lib to your project to use the html2canvas functions

You will need to attach html2canvas to the window for the lib to have access to the html2canvas lib:
```js
    window.html2canvas = html2canvas;
```

html2canvas version used: 1.4.1

Website: https://html2canvas.hertzen.com/

Add the js file before the utils lib:
```html
<script src="https://unpkg.com/html2canvas@1.4.1"></script>
```

---


# Functions

## Handy

### adjustFunscriptForPlaybackSpeed
Returns a Funscript that is adjusted by playbackspeed

```ts
adjustFunscriptForPlaybackSpeed(funscript: Funscript, playbackSpeed: number = 1);
```
### convertCSVtoFunscript
Returns Funscript
```ts
function convertCSVtoFunscript(csv: string);
```
### generateFunscript
Returns Funscript
```ts
generateFunscript(timeBetweenPoints: number, numberOfPoints: number,upValue: 100 = 100,downValue: 0 = 0);
```

### setHeatmap
Generates a heatmap and show it on a canvas
NB! the canvas HTML element should have a fixed hight!
```ts
setHeatmap(funscript: Funscript, canvas: HTMLCanvasElement,slide:HandySlide = {min:0,max:100},playbackSpeed: number=1, showLimits = false);
```

Example:
```html
<canvas id="heatmap" class="w-100" style="height: 50px"></canvas>
<script>
    let canvas = document.getElementById("heatmap");
    Utils.setHeatmap(funscript,canvas);
</script>
```

### readScriptFromFile
Read a script from a file - returns a Funscript
```ts
function readScriptFromFile(file: Blob);
```

## Div functions

### humanFileSize
Returns a readable file size Y Tb | Gb | Mb | kb | b
```ts
humanFileSize(bytes: number, si = false, dp = 1);
```

### wait
Wait function for javascript - Promise
```ts
wait(ms:number)
```
Example
```js
await Utils.wait(1000);
```

### getExtensionFromFilename
Extract the extension for a filename
```ts
getExtensionFromFilename(filename:string);
```





---




## Browser functions
### getFileRemoteSize
Returns a nr of bytes of a remote file
```ts
getFileRemoteSize(url: string);
```
### createFile
Returns a HTML Blob file
```ts
createFile(data: string,type:FileTypeMime = FileTypeMime.funscript);
```

Mime types:

```ts
enum FileTypeMime {
    csv = "text/csv",
    funscript = "application/json",
    json = "application/json",
    text = "text/plain"
}
```
Example of mime types use:
```js
Utils.FileTypeMime.text
```
### downloadFile
Creates and download a file.
 
```ts
downloadFile(data: string, filename: string, type:FileTypeMime = FileTypeMime.funscript);
```

Mime types:

```ts
enum FileTypeMime {
    csv = "text/csv",
    funscript = "application/json",
    json = "application/json",
    text = "text/plain"
}
```
Example of mime types use:
```js
Utils.FileTypeMime.text
```
### downloadFile
Creates and download a file.
 
```ts
goFullScreen(element: HTMLBaseElement);
```
### createToast
NB! Needs bootstrap lib to function!

Creates a Botstrap toast in the body - removed after 60s
bg: bg-XXXX
textColor: text-primary | text-secondary | text-success | text-danger | text-warning | text-info | text-light | text-dark | text-white | text-black

```ts
createToast(text:string, header = "Something went wrong...", bg = "bg-danger", textColor = "text-white");
```
### createToastSuccess
NB! Needs bootstrap lib to function!
Creates a Botstrap toast in the body - removed after 60s

```ts
createToastSuccess(text:string, header = "Success");
```
### createToastWarning
NB! Needs bootstrap lib to function!
Creates a Botstrap toast in the body - removed after 60s

```ts
createToastWarning(text:string, header = "Warning");
```
### convertHtmlElementToBase64
NB! Needs html2canvas lib to function!

Converts a html element to base64 image
width in pixels - default is -1 that results in that the element keeps it original width.
Aspect ratio is keeped
```ts
convertHtmlElementToBase64(htmlElement: HTMLElement,width = -1);
```
### downloadHtmlElementAsJpeg
NB! Needs html2canvas lib to function!

Converts a html element to jpg image and downloads it
width in pixels - default is -1 that results in that the element keeps it original width.
Aspect ratio is keeped
```ts
downloadHtmlElementAsJpeg(filename:string, htmlElement: HTMLElement, width = -1);
```
### readFile
Reads a file content and returns the string contents in a promise
width in pixels - default is -1 that results in that the element keeps it original width.
Aspect ratio is keeped
```ts
function readFile(file: Blob);
```
### getStyle
Returns a int value of css rules
```ts
getStyle (htmlElement: any, strCssRule: string)
```
Example
```ts
let borderWidth = getStyle(videoPlayer, "border-top-width"); //Returns int value of thickness of the top border
```
### getQueryParams
Returns a object of the GET parms
```ts
function getQueryParams(queryParams: string = window.location.search): any;
```
### addTextToClipboard
Addes a text to the clipboard
```ts
function addTextToClipboard(text: string): Promise<void>;
```


---




## Math function

### roundNumber
```ts
roundNumber(number:number, decimals = 2);
```

### getAngleBetweenPoints
```ts
getAngleBetweenPoints(point1:point, point2:point);
```

### getAngleBetweenThreePoints
```ts
getAngleBetweenThreePoints(A:point, B:point, C:point);
```

### getVectorLength
```ts
getVectorLength(point1:point, point2:point);
```

### radToAngle
```ts
radToAngle(rad:number);
```

### dec2hexString
```ts
dec2hexString(dec:number);
```

### randomIntFromInterval
```ts
randomIntFromInterval(min:number = 0, max:number = 100);
```


---



## Canvas

### Canvas Intro
Creates a canvas over a video

Example HTML code
Note that the parent element must have a ID!
```html
<div id="videoPlayerHolder" class="w-100 ratio ratio-16x9">
    <video id="video-player" crossorigin='anonymous' class="w-100" src="" type="video" allowfullscreen controls>
    </video>
</div>
```

Create a new canvas object
optional construcor params:

- videoPlayerId: string = "video-player"
- id = "videoCanvas - " + VideoCanvas.#canvasCounter++

```js
let videoCanvas = new Utils.VideoCanvas();
```

### setBackgroundColor
Sets the permanent background color of the canvas (style - background-color)
```ts
setBackgroundColor(red: number, green: number, blue: number, opacity: number);
```

### removeBackgroundColor
Removes the permanent background color of the canvas (style - background-color)
```js
removeBackgroundColor();
```

### removeRightClickContextMenu
Removes the context menu on right clicks
```js
removeRightClickContextMenu();
```

### setEventListners
Sets the event listners on mouse event
BUG: This is done automaticlly, but due to a bug you must set this after the widnow is loaded
```js
setEventListners();
```

### resize
Resize the canvas to fit over the video object
TODO: This is called automaticlly, but due to a bug it might be needed to call manually
```js
resize();
```

### clearCanvas
Clears the complete canvas
```js
clearCanvas();
```

### clearRect
Clear a recangle of the canvas

Example 1:
```js
clearRect(_config: RectangleClearConfig);
```

Example 2:
```js
clearRect({
    from:   {x: 0.3 , y: 0.2},
    to:     {x: 0.5 , y: 0.6},
    percent: true, //OPTIONAL - default is true
});
```

Config type:
```ts
interface RectangleClearConfig {
    from: GraphPointPixel | GraphPointPercent,
    to: GraphPointPixel | GraphPointPercent,
    percent?: boolean,
}
```

### clearRect
Set the Z value of the canvas

Use this if you have multiple canvases and want one on top for mouse events to trigger

Example:
```js
setZValue = (zIndex: string);
```

### Draw shapes
Some details:
- You must provide a color to see the shape (fillStyle | gradientfillStyle | strokeStyle | gradientStrokeStyle)
- Gradient overrides normal fill style
- If a value can be set in percent or pixels -> Percent overrides

General config options:
```ts
interface ShapeConfig {
    strokeStyle?: string | CanvasGradient | CanvasPattern,
    gradientStrokeStyle?: GradientConfig,
    fillStyle?: string | CanvasGradient | CanvasPattern ,
    gradientFillStyle?: GradientConfig,
    lineWidth?: SinglePointPixel,
    lineWidthPercent?: SinglePointPercent,
    percent?: boolean,
}
```

Gradient config options:
```ts
interface GradientConfig {
    from: GraphPointPixel | GraphPointPercent,
    to: GraphPointPixel | GraphPointPercent,
    percent?: boolean,
    colors: [{ start: number, color: string }],
}
```

---

### drawRect
Draws a rectangle on the canvas
```ts
drawRect(_config: RectangleConfig);
```

```ts
interface RectangleConfig extends ShapeConfig {
    from: GraphPointPixel | GraphPointPercent,
    to: GraphPointPixel | GraphPointPercent,
    rounded?: SinglePointPixel,  
}
```

Example
```js
let videoCanvas = new Utils.VideoCanvas();
videoCanvas.drawRect({
    from:{x:0.1,y:0.1}, //MANDATORY
    to: {x:0.5,y:0.5}, //MANDATORY
    rounded: 50, //pixel size of the rounded corner
    lineWidthPercent: 0.01, //Optional
    fillStyle: "#ffffff", //Optional
    gradientfillStyle: { //Optional - Will override fillStyle
    	from:{x:0.5,y:0.5},
    	to: {x:0.1,y:0.1},
    	// percent: true, // Percent===true is default
    	colors: [{start: 0, color: "#ff0000"},{start: 1, color: "rgba(0,0,255,0.5)"}]
    }
    strokeStyle: "#00ffff",
    gradientStrokeStyle: {
    	from:{x:0.5,y:0.5},
    	to: {x:0.1,y:0.1},
    	percent: true, // Percent===true is default
    	colors: [{start: 0, color: "#ff0000"},{start: 1, color: "rgba(0,0,255,0.5)"}]
    }
});
```


### drawArrow
Draws a arrow on the canvas
```ts
drawArrow = (_config: ArrowConfig);
```

```ts
interface ArrowConfig  {
    from: GraphPointPixel | GraphPointPercent,
    to: GraphPointPixel | GraphPointPercent,
    percent?: boolean,
    r?: SinglePointPixel,
    rPercent?: SinglePointPercent,
    rectangleColor?: string | CanvasGradient | CanvasPattern,
    rectangleColorGradient?: GradientConfig,
    triangleColor?: string | CanvasGradient | CanvasPattern,
    triangleColorGradient?: GradientConfig,
}
```

Example
```js
let videoCanvas = new Utils.VideoCanvas();
videoCanvas.drawArrow({
    from:{x:0.1,y:0.1},
    to: {x:0.5,y:0.5}, //percent values is default - set percent = false if you want to use absolute values
    rPercent: 0.1,  //optional default is r = 20px (not percent)
    rectangleColor: "rgba(77, 117, 157, 0.1)", //Will bo overwritten by rectangleColorGradient 
    triangleColor: "rgba(77, 117, 157, 0.2)", //Will bo overwritten by triangleColorGradient
    rectangleColorGradient: {
    	from:{x:100,y:100},
    	to: {x:300,y:300},
    	percent: false, //Default is true
    	colors: [{start: 0, color: "#ff0000"},{start: 1, color: "rgba(0,0,255,0.5)"}]
    },
    triangleColorGradient: {
    	from:{x:0.5,y:0.5},
    	to: {x:0.1,y:0.1},
    	colors: [{start: 0, color: "#ff0000"},{start: 1, color: "rgba(0,0,255,0.5)"}]
    }
});
```

### drawCircle
Draws a arrow on the canvas
```ts
drawCircle = (_config: CircleConfig);
```

```ts
interface CircleConfig extends ShapeConfig {
    center: GraphPointPixel | GraphPointPercent,
    radius?: SinglePointPixel,
    radiusPercent?: SinglePointPercent,
}
```

Example
```js
let videoCanvas = new Utils.VideoCanvas();
videoCanvas.drawCircle({ center: { x: 0.5, y: 0.5 }});
```


### drawText
Draws a arrow on the canvas
```ts
drawText = (_config: TextConfig);
```

```ts
interface TextConfig extends ShapeConfig {
    position: GraphPointPixel | GraphPointPercent,
    text?: string,
    font?: string,
    size?: SinglePointPixel,
    sizePercent?: SinglePointPercent,
    textAlign?: CanvasTextAlign,
    textBaseline?: CanvasTextBaseline,
    dynamicWidth?: SinglePointPercent,
    dynamicWidthHeightBased?: boolean,
}
```
Size, sizePercent and dynamicWidth:
- All sets the font size
- dynamicWidth sets the font size automaticlly to fit the width that is spesified
 - dynamicWidth is based on the canvas height - set dynamicWidthHeightBased to false if you want to use width

textAlign: center|end|left|right|start
textBaseline: alphabetic|top|hanging|middle|ideographic|bottom

font: "hind" - NB must be added to the website
```html
<style>
	@import url(https://fonts.googleapis.com/css?family=Hind:300,400,500);
</style
```


Example
```js
let videoCanvas = new Utils.VideoCanvas();
videoCanvas.drawText({
    position: { x: 0.6, y: 0.6 },
    text: "HEIHEI",
    dynamicWidth: 0.4,
    fillStyle: "blue",
});

### drawLine
Draws a arrow on the canvas
```ts
drawLine = (_config: LineConfig);
```

NB! fillStyle does not work on Line
```ts
interface LineConfig extends ShapeConfig {
    from: GraphPointPixel | GraphPointPercent,
    to: GraphPointPixel | GraphPointPercent,
}
```

Example
```js
let videoCanvas = new Utils.VideoCanvas();
videoCanvas.drawLine({
    from:{x:0.1,y:0.1},
    to: {x:0.5,y:0.5},
});
```

---



## Variables
Access directly with Utils.VARIABLE_NAME
### HandyLimits
Can be changed - but have effects on other functions
```ts
HandyLimits = {
    MIN_SPEED: 32,     //mm/s
    MAX_SPEED: 400,    //mm/s
    MAX_STROKE_LENGTH: 96, //mm
}
```

### TEST_VIDEO_URL
Contains the URL to the testvideo
```
https://playground.handyfeeling.com/assets/sync_video_2021.mp4
```
### TEST_SCRIPT
Contains the funscript object that matches the test video

### TEST_SCRIPT_URL
URL to the test script funscript

### TEST_SCRIPT_URL_CSV
URL to the test script csv file

### API
Contains the different urls
production | staging | local
api | script | uui | channel
Example of use
```js
Utils.production.api
```