cdejs
Version:
CanvasDotEffect is a lightweight JS library that helps create customizable and interactive dot-based effects using the Canvas API
2 lines • 7.02 kB
JavaScript
#!/usr/bin/env node
import{exec,spawn}from"child_process";import{mkdirSync,writeFileSync}from"fs";import{join}from"path";import{createInterface}from"readline";const destination=join(process.cwd(),process.argv[2]||""),mediaDest=join(destination,"medias"),binDest=join(destination,"bin");try{mkdirSync(destination,{recursive:!0}),mkdirSync(mediaDest),mkdirSync(binDest)}catch{}writeFileSync(join(destination,"index.html"),'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>Template</title>\n <link rel="stylesheet" href="index.css">\n</head>\n<body>\n \n <div class="canvasHolder">\n <canvas id="canvasId"></canvas>\n </div>\n\n <div class="debug">\n <span id="fpsDisplay"></span>\n <span id="mouseInfo"></span>\n <span id="mouseSpeed"></span>\n <span id="mouseAngle"></span>\n </div>\n\n <script type="module" src="index.js"><\/script>\n</body>\n</html>'),writeFileSync(join(destination,"index.css"),"html, body {\n background-color: black;\n overflow: hidden;\n color: aliceblue;\n margin: 0;\n width: 100%;\n height: 100%;\n}\n\n.canvasHolder {\n width: 98%;\n height: 88%;\n border: 2px solid aliceblue;\n user-select: none;\n}"),writeFileSync(join(destination,"index.js"),'import {FPSCounter, Canvas, Shape, Dot, CDEUtils, CanvasUtils, Anim, Pattern} from "cdejs"\n\nconst _ = null, fpsCounter = new FPSCounter(), CVS = new Canvas(document.getElementById("canvasId"), \n ()=>{// loopingCB\n\n // Debug infos\n const fpsValue = fpsCounter.getFps()+" "+fpsCounter.fpsRaw\n if (fpsDisplay.textContent !== fpsValue) fpsDisplay.textContent = fpsValue\n mouseSpeed.textContent = CVS.mouse.speed?.toFixed(2)+" px/sec"\n mouseAngle.textContent = CVS.mouse.dir?.toFixed(2)+" deg"\n }\n)\n\n// Canvas objects declarations \nconst demoShape = new Shape(CVS.getCenter(), [new Dot([-50, -50]),new Dot([-50, 0]),new Dot([-50, 50]),new Dot([0, -50]),new Dot([0, 50]),new Dot([50, -50]),new Dot([50, 0]),new Dot([50, 50])], _, _, 100,\n (render, dot, ratio)=>{// drawEffectCB\n \n // Changing the dot\'s radius from 50px down to 80% of 50px (range of 50px..10px), according to the mouse distance\n dot.radius = CDEUtils.mod(50, ratio, 50*0.8)\n \n // Drawing a ring around the dot\n CanvasUtils.drawOuterRing(dot, [255,255,255,0.25], 1)\n\n }, _, (shape)=>{// setupCB\n\n // Adding a rotation and scale animation\n shape.playAnim(new Anim((prog, i)=>{\n const adjustedProgress = i%2 ? prog : 1-prog\n \n shape.rotateAt(360*prog)\n shape.scaleAt([1+adjustedProgress*2, 1+adjustedProgress*2])\n }, -7500, Anim.easeInOutQuad))\n\n // Creating a pattern that will get duplicated for each dot of demoShape ((↓) set the "positions" parameter to the area containing all the dots)\n new Pattern(CVS.render, "./medias/coolBackground.mp4", demoShape.getBounds(50, 0, [3, 3]), _, true, true, _, \n ()=>{// errorCB\n // If there is an error loading the file, set color to grey\n demoShape.setColor([255,255,255,0.25])\n },\n (pattern)=>{// readyCB\n // Once the video is loaded, set the shape2\'s color to the value of the pattern\n demoShape.setColor(pattern)\n \n // Speed up the video to 3x speed\n pattern.playbackRate = 3\n }\n )\n })\n\nCVS.add(demoShape)\n\n\n// Event listeners\nlet mouseMoveEvent=(mouse)=>mouseInfo.textContent = "("+mouse.x+", "+mouse.y+")" // debug info\nCVS.setMouseMove(mouseMoveEvent)\nCVS.setMouseLeave(mouseMoveEvent)\nCVS.setMouseDown()\nCVS.setMouseUp()\nCVS.setKeyDown(_, true)\nCVS.setKeyUp(_, true)\n\n// Start drawing loop\nCVS.start()'),writeFileSync(join(destination,".gitignore"),"# Logs\nlogs\n*.log\nnpm-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n.env*"),writeFileSync(join(destination,"package.json"),'{\n "name": "project_template",\n "version": "1.0.0",\n "main": "index.js",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vite build && node ./bin/build.js"\n },\n "dependencies": {\n "cdejs": "^1.3.0"\n },\n "devDependencies": {\n "vite": "^6.2.2"\n }\n }'),writeFileSync(join(binDest,"build.js"),'#!/usr/bin/env node\nimport {copyFileSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync} from "fs"\nimport {extname, join} from "path"\nimport {cwd} from "process"\n\nfunction copyFolder(src, dest) {\n const filepaths = readdirSync(src, {recursive:true}), f_ll = filepaths.length\n for (let i=0;i<f_ll;i++) {\n const filepath = join(src, filepaths[i]), destPath = join(dest, filepaths[i])\n if (statSync(filepath).isDirectory()) {\n mkdirSync(destPath, {recursive:true})\n copyFolder(filepath, destPath)\n } else copyFileSync(filepath, destPath)\n }\n}\n\n// Add async attribute to main script\nconst indexHtmlPath = join(cwd(), "dist/index.html")\nwriteFileSync(indexHtmlPath, readFileSync(indexHtmlPath, "utf8").replace(\'type="module" crossorigin\', \'type="module" async crossorigin\'))\n\n// Define user medias / assets\nconst defaultFolders = ["dist", "bin", "node_modules"],\n userMediasExtensions = ["mp3","wav","ogg","aac","m4a","opus","flac","jpg","jpeg","png","gif","svg","webp","bmp","tiff","ico","heif","heic","mp4","webm","ogv","mov","avi","mkv","flv","wmv","3gp","m4v"], \n source = process.cwd()\n\n// Add user medias / assets\nreaddirSync(source).filter(filepath=>{\n const fullPath = join(source, filepath)\n return statSync(fullPath).isDirectory() && !defaultFolders.includes(filepath) && readdirSync(fullPath).some(file=>userMediasExtensions.includes(extname(file).replace(".","")))\n}).forEach(folder=>{\n const destination = join(source, "dist", folder)\n mkdirSync(destination, {recursive:true})\n copyFolder(join(source, folder), destination)\n})\n\nconsole.log("Build completed!\n")'),fetch("https://file-examples.com/storage/fe9a194958686838db9645f/2017/04/file_example_MP4_480_1_5MG.mp4").then((e=>e.ok&&e.arrayBuffer())).then((e=>e&&writeFileSync(join(mediaDest,"coolBackground.mp4"),Buffer.from(e)))),spawn("npm",["i"],{cwd:destination,shell:!0}),console.log("CDEJS project template successfully created at '"+destination+"'!\n");const cli=createInterface({input:process.stdin,output:process.stdout});function close(e){e.close(),console.log("")}cli.question("Open in explorer [Y/N]? ",(e=>{const n=e?.toLowerCase()?.trim();"code"==n?exec("code --new-window "+destination):n&&!["y","yes","ye","ok","for sure"].includes(n)||exec("explorer "+destination),close(cli)})),process.stdin.on("keypress",((e,n)=>{"escape"==n.name&&close(cli)}));