Skip to content

Instantly share code, notes, and snippets.

@tohagan
tohagan / README.md
Created February 7, 2025 01:40
Upload image, recommend cropping scale and offsets (AI), allow the user to adjust the final cropping to a fixed image size.

Example code from GPT 4o-mini to support capturing images from a user of a fixed size.

  • File Upload: The user uploads an image, which is read using a FileReader.
  • SmartCrop: Once the image is loaded, SmartCrop analyzes it and provides a suggested cropping area based on the preset final dimensions.
  • Cropper.js: The suggested crop area is set in Cropper.js, allowing the user to see the recommended crop and make adjustments. The aspect ratio is fixed to the desired dimensions.
  • Cropping: When the user clicks the "Crop" button, the cropped image is drawn onto a canvas with the specified final dimensions.
@tohagan
tohagan / usePersistedRef.ts
Last active September 11, 2024 03:12
Vue/Quasar: Persist a ref value to local storage
// Persist a ref value to local storage
// Quasar performs the conversion to/from the data type T
// https://quasar.dev/quasar-plugins/web-storage#localstorage-api
// usePersistedRef.ts
import { watch, Ref } from 'vue';
import { LocalStorage } from 'quasar';
export function usePersistedRef<T>(key: string, ref: Ref<T>): Ref<T> {
const storedValue = LocalStorage.getItem(key) as T
## YouTube thumbnail URLs
- `ytimg.com` is owned by Google
- Use in compliance with owner copyright and YouTube terms
Player Background Thumbnail (480x360):
- https://i.ytimg.com/vi_webp/VIDEO_ID/0.webp
- https://i.ytimg.com/vi/VIDEO_ID/0.jpg
Video frames thumbnails (120x90)
@tohagan
tohagan / run.js
Created August 2, 2023 12:10
NodeJS async run() starter example
#!/usr/bin/env node
async function run() {
// do async stuff
console.log('')
}
// Start
run()
.then(() => {
@tohagan
tohagan / dns_resolve_names.js
Created July 23, 2023 04:52
Resolve a list of DNS names
// Accessing dns module
const dns = require('dns');
async function run() {
const names = [
'hostname1.com',
'hostname2.com',
]
for await (const name of names) {
@tohagan
tohagan / loadScript.js
Last active March 10, 2023 01:02
Dynamically load a script with callback (JS) or Promise (TS)
function loadScript(id, src, async = true, onload = undefined, onerror = undefined) {
var elScript = Object.assign(document.createElement('script'), {
id, src, async, type: 'text/javascript'
})
if (onload) elScript.addEventListener("load", onload);
if (onerror) elScript.addEventListener("error", onerror);
document.head.appendChild(elScript)
}
@tohagan
tohagan / gist:2b3cd587a19e37046fbc7881272c108c
Created March 3, 2023 07:41
Convert diacritic / accented letters to non-accented (for search, code etc)
const removeAccents = (name) => name.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
@tohagan
tohagan / delay-node16.ts
Last active December 3, 2022 11:52
delay() using a Promise
// Requires Node 16 or later
import { setTimeout } from 'timers/promises';
const result = await setTimeout(2000, 'done');
import * as functions from "firebase-functions";
import * as firebase from "firebase-admin";
import { parseAsync } from 'json2csv';
import { v4 as uuidv4 } from 'uuid';
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
firebase.initializeApp({
storageBucket: 'storage-bucket-name',
@tohagan
tohagan / firebase-grpc-middleware.ts
Last active October 22, 2022 09:30
Firebase Middleware for GRPC Callable functions
/*
* Middleware for Firebase GRPC Callable functions
*
* Reference: https://stackoverflow.com/a/70057694/365261
*
* Example:
* export const myCallableFunction = functions.https.onCall(
* return withMiddlewares([assertAppCheck, assertAuthenticated], async (data, context) => {
* // Your callable function handler
* })