diff --git a/.eslintrc.json b/.eslintrc.json index 1993e6f..0e65c0e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,8 +1,8 @@ { "root": true, - "extends": [ - "eslint:recommended" - ], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], "parserOptions": { "sourceType": "module", "ecmaVersion": 2020 @@ -13,6 +13,9 @@ "node": true }, "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/ban-types": "off", "no-constant-condition": "off" } } diff --git a/package.json b/package.json index f693be7..95de889 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "build": "rollup -c", "prepare": "rollup -c", "watch": "rollup -c -w", - "lint": "eslint src/*.js" + "lint": "eslint src/*.ts" }, "homepage": "https://projects.calebevans.me/jcanvas/", "author": "Caleb Evans", @@ -33,6 +33,8 @@ "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@types/jquery": "^3.5.30", + "@typescript-eslint/eslint-plugin": "^7.10.0", + "@typescript-eslint/parser": "^7.10.0", "eslint": "^8.56.0", "glob": "^10.3.10", "jquery": "^3.7.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e52bc8c..f0bc3c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,12 @@ devDependencies: '@types/jquery': specifier: ^3.5.30 version: 3.5.30 + '@typescript-eslint/eslint-plugin': + specifier: ^7.10.0 + version: 7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.56.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.10.0 + version: 7.10.0(eslint@8.56.0)(typescript@5.4.5) eslint: specifier: ^8.56.0 version: 8.56.0 @@ -529,6 +535,133 @@ packages: resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} dev: true + /@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.56.0)(typescript@5.4.5): + resolution: {integrity: sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 7.10.0(eslint@8.56.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/type-utils': 7.10.0(eslint@8.56.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.10.0(eslint@8.56.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.10.0 + eslint: 8.56.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@7.10.0(eslint@8.56.0)(typescript@5.4.5): + resolution: {integrity: sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.10.0 + debug: 4.3.4 + eslint: 8.56.0 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.10.0: + resolution: {integrity: sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/visitor-keys': 7.10.0 + dev: true + + /@typescript-eslint/type-utils@7.10.0(eslint@8.56.0)(typescript@5.4.5): + resolution: {integrity: sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.10.0(eslint@8.56.0)(typescript@5.4.5) + debug: 4.3.4 + eslint: 8.56.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@7.10.0: + resolution: {integrity: sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==} + engines: {node: ^18.18.0 || >=20.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.10.0(typescript@5.4.5): + resolution: {integrity: sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/visitor-keys': 7.10.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@7.10.0(eslint@8.56.0)(typescript@5.4.5): + resolution: {integrity: sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@7.10.0: + resolution: {integrity: sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==} + engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.10.0 + eslint-visitor-keys: 3.4.3 + dev: true + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true @@ -582,6 +715,11 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -599,6 +737,13 @@ packages: balanced-match: 1.0.2 dev: true + /braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -661,6 +806,13 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -821,6 +973,17 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + dev: true + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true @@ -842,6 +1005,13 @@ packages: flat-cache: 3.0.4 dev: true + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -888,6 +1058,13 @@ packages: resolve-pkg-maps: 1.0.0 dev: true + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} @@ -940,6 +1117,18 @@ packages: resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} dev: true + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + /globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} dev: true @@ -958,6 +1147,11 @@ packages: engines: {node: '>= 4'} dev: true + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -999,6 +1193,11 @@ packages: is-extglob: 2.1.1 dev: true + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -1073,6 +1272,19 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + dev: true + /minimatch@3.0.8: resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} dependencies: @@ -1099,6 +1311,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} @@ -1179,6 +1398,11 @@ packages: minipass: 7.0.4 dev: true + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -1278,6 +1502,12 @@ packages: queue-microtask: 1.2.3 dev: true + /semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + dev: true + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1295,6 +1525,11 @@ packages: engines: {node: '>=14'} dev: true + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -1350,6 +1585,22 @@ packages: globrex: 0.1.2 dev: true + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /ts-api-utils@1.3.0(typescript@5.4.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.4.5 + dev: true + /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: true diff --git a/src/jcanvas-handles.ts b/src/jcanvas-handles.ts index d43256d..79480c3 100644 --- a/src/jcanvas-handles.ts +++ b/src/jcanvas-handles.ts @@ -95,7 +95,7 @@ function addRectHandle( px: number, py: number ) { - let handle, cursor; + let cursor; // Determine cursor to use depending on handle's placement if ((px === -1 && py === -1) || (px === 1 && py === 1)) { @@ -110,7 +110,7 @@ function addRectHandle( const nonNullWidth = parent.width || 0; const nonNullHeight = parent.height || 0; - handle = $.extend( + const handle = $.extend( { // Set cursors for handle cursors: { @@ -309,8 +309,9 @@ function addPathHandles( // Update handle guides for line path function updatePathGuides(parent: JCanvasObject) { - let handles = parent._handles, - guides = parent._guides; + let handles = parent._handles; + const guides = parent._guides; + if (parent._method === $.fn.drawQuadratic) { if (handles) { const guide = parent._guide; diff --git a/src/jcanvas-hearts.ts b/src/jcanvas-hearts.ts index c76954f..018a175 100644 --- a/src/jcanvas-hearts.ts +++ b/src/jcanvas-hearts.ts @@ -15,19 +15,17 @@ $.jCanvas.extend<{ size: number }>({ size: 0, }, fn: function (ctx, params) { - let canvas = this, + const canvas = this, width = params.size, factor = 0.75, height = width * factor, - angle = PI * (factor * (1 - factor)), - x: number, - y: number; + angle = PI * (factor * (1 - factor)); // Enable shape transformation $.jCanvas.transformShape(canvas, ctx, params, width, height); - x = params.x; - y = params.y + width / 8; + const x = params.x; + const y = params.y + width / 8; ctx.beginPath(); ctx.moveTo(x, y + height / 2); diff --git a/src/jcanvas.d.ts b/src/jcanvas.d.ts index fdfa7f2..6232a6f 100644 --- a/src/jcanvas.d.ts +++ b/src/jcanvas.d.ts @@ -1,5 +1,3 @@ -/// - interface JCanvasPluginParams { name: string; props?: Record; @@ -79,7 +77,7 @@ interface JQueryStatic { jCanvasObject: JCanvasObjectFunction; } -interface JQuery { +interface JQuery { getEventHooks(): JCanvasEventHooks; setEventHooks(eventHooks: JCanvasEventHooks): JQuery; getLayers(callback?: JCanvasLayerCallback): JCanvasObject[]; diff --git a/src/jcanvas.ts b/src/jcanvas.ts index 654beea..da392b8 100644 --- a/src/jcanvas.ts +++ b/src/jcanvas.ts @@ -1,10 +1,10 @@ -/// /** * @license jCanvas v21.0.1 * Copyright 2017 Caleb Evans * Released under the MIT license */ import $ from "jquery"; +import "./jcanvas.d"; // Define local aliases to frequently used properties const extendObject = $.extend, @@ -20,8 +20,6 @@ const extendObject = $.extend, sin = Math.sin, cos = Math.cos, atan2 = Math.atan2, - // The Array slice() method - arraySlice = Array.prototype.slice, // jQuery's internal event normalization function jQueryEventFix = ($.event as JQueryEventWithFix).fix, // Object for storing a number of internal property maps @@ -218,11 +216,6 @@ function isFunction(operand: any): operand is Function { return typeOf(operand) === "function"; } -// Determines if the given operand is a function -function isObject(operand: any): operand is T { - return typeOf(operand) === "object"; -} - // Determines if the given operand is numeric function isNumeric(operand: any): operand is number | string { return !isNaN(Number(operand)) && !isNaN(parseFloat(operand)); @@ -275,9 +268,8 @@ function _cloneTransforms(transforms: JCanvasBaseTransforms) { // Save canvas context and update transformation stack function _saveCanvas(ctx: CanvasRenderingContext2D, data: JCanvasInternalData) { - let transforms; ctx.save(); - transforms = _cloneTransforms(data.transforms); + const transforms = _cloneTransforms(data.transforms); data.savedTransforms.push(transforms); } @@ -344,12 +336,12 @@ function _setGlobalProps( if (ctx.setLineDash) { ctx.setLineDash(params.strokeDash); } - // @ts-expect-error + // @ts-expect-error Permit vendor-prefixed property ctx.webkitLineDash = params.strokeDash; ctx.lineDashOffset = - // @ts-expect-error + // @ts-expect-error Permit vendor-prefixed property ctx.webkitLineDashOffset = - // @ts-expect-error + // @ts-expect-error Permit vendor-prefixed property ctx.mozDashOffset = params.strokeDashOffset; // Drop shadow @@ -529,7 +521,6 @@ jCanvas.extend = function extend(plugin) { // @ts-expect-error TODO: fix this $.fn[plugin.name] = function self(args) { const $canvases = this; - let canvas, params; for (let e = 0; e < $canvases.length; e += 1) { const canvas = $canvases[e]; @@ -621,8 +612,8 @@ class JCanvasInternalData { // Retrieved the stored jCanvas data for a canvas element function _getCanvasData(canvas: HTMLCanvasElement) { - let dataCache = caches.dataCache, - data; + const dataCache = caches.dataCache; + let data; if (dataCache._canvas === canvas && dataCache._data) { // Retrieve canvas data from cache if possible data = dataCache._data; @@ -649,7 +640,7 @@ function _addLayerEvents( layer: JCanvasObject ) { // Determine which jCanvas events need to be bound to this layer - for (let eventName in jCanvas.events) { + for (const eventName in jCanvas.events) { if (Object.prototype.hasOwnProperty.call(jCanvas.events, eventName)) { // If layer has callback function to complement it if (layer[eventName] || (layer.cursors && layer.cursors[eventName])) { @@ -775,7 +766,7 @@ function _updateLayerGroups( layer: JCanvasObject, props?: Partial ) { - let groupMap = data.layer.groups; + const groupMap = data.layer.groups; let index: number | undefined = undefined; // If group name is not changing @@ -893,7 +884,7 @@ $.fn.getLayers = function getLayers(callback) { // Get a single jCanvas layer object $.fn.getLayer = function getLayer(layerId) { const $canvases = this; - let canvas, data, layers, layer, l, idType; + let layer; if ($canvases.length !== 0) { const canvas = $canvases[0]; @@ -924,7 +915,7 @@ $.fn.getLayer = function getLayer(layerId) { // Get layer with the given index layer = layers[layerIndex]; } else if (idType === "regexp") { - let layerPattern = layerId as RegExp; + const layerPattern = layerId as RegExp; // Get layer with the name that matches the given regex for (let l = 0; l < layers.length; l += 1) { // Check if layer matches name @@ -934,7 +925,7 @@ $.fn.getLayer = function getLayer(layerId) { } } } else { - let layerName = layerId as string; + const layerName = layerId as string; // Get layer with the given name layer = data.layer.names[layerName]; } @@ -947,7 +938,6 @@ $.fn.getLayerGroup = function getLayerGroup(groupId) { const $canvases = this; const idType = typeOf(groupId); - let group: JCanvasObject[]; if ($canvases.length !== 0) { const canvas = $canvases[0]; if (!_isCanvas(canvas)) { @@ -958,12 +948,12 @@ $.fn.getLayerGroup = function getLayerGroup(groupId) { // Return layer group if given return groupId as Exclude; } else if (idType === "regexp") { - let groupPattern = groupId as RegExp; + const groupPattern = groupId as RegExp; // Get canvas data const data = _getCanvasData(canvas); const groups = data.layer.groups; // Loop through all layers groups for this canvas - for (let groupName in groups) { + for (const groupName in groups) { // Find a group whose name matches the given regex if (groupName.match(groupPattern)) { // Stop after finding the first matching group @@ -972,7 +962,7 @@ $.fn.getLayerGroup = function getLayerGroup(groupId) { } } else if (typeof groupId === "string") { // Find layer group with the given group name - let groupName = groupId as string; + const groupName = groupId as string; const data = _getCanvasData(canvas); return data.layer.groups[groupName]; } @@ -1455,10 +1445,6 @@ function _setCursor( // Retrieve cursor from cursors object if it exists cursor = layer.cursors[eventType]; } - // Prefix any CSS3 cursor - if ($.inArray(cursor, css.cursors) !== -1) { - cursor = cursor; - } // If cursor is defined if (cursor) { // Set canvas cursor @@ -1590,7 +1576,7 @@ $.fn.drawLayers = function drawLayers(args) { if (!_isCanvas(canvas)) { continue; } - let $canvas = $(canvas); + const $canvas = $(canvas); const ctx = _getContext(canvas); if (!ctx) { continue; @@ -2352,14 +2338,14 @@ function _getMouseEventName(eventName: string) { function _createEvent(eventName: string) { jCanvas.events[eventName] = function ($canvas, data) { // Retrieve canvas's event cache - let eventCache = data.event; + const eventCache = data.event; // Both mouseover/mouseout events will be managed by a single mousemove event - let helperEventName = + const helperEventName = eventName === "mouseover" || eventName === "mouseout" ? "mousemove" : eventName; - let touchEventName = _getTouchEventName(helperEventName); + const touchEventName = _getTouchEventName(helperEventName); function eventCallback(event: MouseEvent) { // Cache current mouse position and redraw layers @@ -2435,8 +2421,8 @@ function _detectEvents( const layer = params._args; // Canvas must have event bindings if (layer) { - let data = _getCanvasData(canvas); - let eventCache = data.event; + const data = _getCanvasData(canvas); + const eventCache = data.event; let intersects: boolean = false; let x: number; let y: number; @@ -2455,7 +2441,7 @@ function _detectEvents( (ctx.isPointInStroke && ctx.isPointInStroke(x, y)); } } - let transforms = data.transforms; + const transforms = data.transforms; // Allow callback functions to retrieve the mouse coordinates layer.eventX = eventCache.x; @@ -2465,7 +2451,7 @@ function _detectEvents( // Adjust coordinates to match current canvas transformation // Keep track of some transformation values - let angle = data.transforms.rotate; + const angle = data.transforms.rotate; x = layer.eventX; y = layer.eventY; @@ -2840,9 +2826,9 @@ $.fn.drawRect = function drawRect(args) { const nonNullWidth = params.width || 0; const nonNullHeight = params.height || 0; ctx.beginPath(); - let x1 = params.x - nonNullWidth / 2; - let y1 = params.y - nonNullHeight / 2; - let r = abs(params.cornerRadius); + const x1 = params.x - nonNullWidth / 2; + const y1 = params.y - nonNullHeight / 2; + const r = abs(params.cornerRadius); // If corner radius is defined and is not zero if (r) { // Draw rectangle with rounded corners if cornerRadius is defined @@ -2918,10 +2904,10 @@ function _drawArc( } // Calculate coordinates for start arrow - let x1 = _getConicX(pathX, path.radius, path.start + diff); - let y1 = _getConicY(pathY, path.radius, path.start + diff); - let x2 = _getConicX(pathX, path.radius, path.start); - let y2 = _getConicY(pathY, path.radius, path.start); + const x1 = _getConicX(pathX, path.radius, path.start + diff); + const y1 = _getConicY(pathY, path.radius, path.start + diff); + const x2 = _getConicX(pathX, path.radius, path.start); + const y2 = _getConicY(pathY, path.radius, path.start); _addStartArrow(canvas, ctx, params, path, x1, y1, x2, y2); @@ -2929,10 +2915,10 @@ function _drawArc( ctx.arc(pathX, pathY, path.radius, path.start, path.end, path.ccw); // Calculate coordinates for end arrow - let x3 = _getConicX(pathX, path.radius, path.end + diff); - let y3 = _getConicY(pathY, path.radius, path.end + diff); - let x4 = _getConicX(pathX, path.radius, path.end); - let y4 = _getConicY(pathY, path.radius, path.end); + const x3 = _getConicX(pathX, path.radius, path.end + diff); + const y3 = _getConicY(pathY, path.radius, path.end + diff); + const x4 = _getConicX(pathX, path.radius, path.end); + const y4 = _getConicY(pathY, path.radius, path.end); _addEndArrow(canvas, ctx, params, path, x4, y4, x3, y3); } @@ -2982,10 +2968,10 @@ function _drawEllipse( const nonNullHeight = path.height || 0; // Calculate coordinates for start arrow - let x1 = _getConicX(path.x, nonNullWidth / 2, path.start + diff); - let y1 = _getConicY(path.y, nonNullHeight / 2, path.start + diff); - let x2 = _getConicX(path.x, nonNullWidth / 2, path.start); - let y2 = _getConicY(path.y, nonNullHeight / 2, path.start); + const x1 = _getConicX(path.x, nonNullWidth / 2, path.start + diff); + const y1 = _getConicY(path.y, nonNullHeight / 2, path.start + diff); + const x2 = _getConicX(path.x, nonNullWidth / 2, path.start); + const y2 = _getConicY(path.y, nonNullHeight / 2, path.start); _addStartArrow(canvas, ctx, params, path, x1, y1, x2, y2); @@ -3001,10 +2987,10 @@ function _drawEllipse( ); // Calculate coordinates for end arrow - let x3 = _getConicX(pathX, nonNullWidth / 2, path.end + diff); - let y3 = _getConicY(pathY, nonNullHeight / 2, path.end + diff); - let x4 = _getConicX(pathX, nonNullWidth / 2, path.end); - let y4 = _getConicY(pathY, nonNullHeight / 2, path.end); + const x3 = _getConicX(pathX, nonNullWidth / 2, path.end + diff); + const y3 = _getConicY(pathY, nonNullHeight / 2, path.end + diff); + const x4 = _getConicX(pathX, nonNullWidth / 2, path.end); + const y4 = _getConicY(pathY, nonNullHeight / 2, path.end); _addEndArrow(canvas, ctx, params, path, x4, y4, x3, y3); } @@ -3597,10 +3583,10 @@ function _drawVector( } let l = 1; - let x = path.x + offsetX; + const x = path.x + offsetX; let x3 = x; let x4 = x; - let y = path.y + offsetY; + const y = path.y + offsetY; let y3 = y; let y4 = y; @@ -3621,7 +3607,7 @@ function _drawVector( } while (true) { const angle = path["a" + l]; - length = path["l" + l]; + const length = path["l" + l]; if (angle !== undefined && length !== undefined) { // Convert the angle to radians with 0 degrees starting at north @@ -3932,7 +3918,7 @@ $.fn.drawText = function drawText(args) { } if (params.radius) { - let fontSize = parseFloat(params.fontSize); + const fontSize = parseFloat(params.fontSize); // Greater values move clockwise if (params.letterSpacing === null) { @@ -4075,9 +4061,9 @@ $.fn.measureText = function measureText(args) { // Draws image on canvas $.fn.drawImage = function drawImage(args) { const $canvases = this; + const imageCache = caches.imageCache; let img: HTMLImageElement | HTMLCanvasElement | null = null, - source: JCanvasObject["source"], - imageCache = caches.imageCache; + source: JCanvasObject["source"]; // Draw image function function draw( @@ -4256,7 +4242,7 @@ $.fn.drawImage = function drawImage(args) { // Use image or canvas element if given img = source; } else if (source) { - let cachedImg = imageCache[source]; + const cachedImg = imageCache[source]; if (cachedImg && cachedImg.complete) { // Get the image element from the cache if possible img = cachedImg; @@ -4295,7 +4281,6 @@ $.fn.createPattern = function createPattern(args) { const $canvases = this; let img: HTMLCanvasElement | HTMLImageElement; let pattern: CanvasPattern | null = null; - let source: HTMLImageElement | HTMLCanvasElement | string; // Function to be called when pattern loads function onload(ctx: CanvasRenderingContext2D, params: JCanvasObject) { @@ -4318,7 +4303,7 @@ $.fn.createPattern = function createPattern(args) { const params = new jCanvasObject(args); // Cache the given source - source = params.source; + const source = params.source; // Draw when image is loaded (if load() callback function is defined) @@ -4328,7 +4313,7 @@ $.fn.createPattern = function createPattern(args) { img = $("")[0] as HTMLCanvasElement; img.width = params.width || 0; img.height = params.height || 0; - let imgCtx = _getContext(img); + const imgCtx = _getContext(img); source.call(img, imgCtx); onload(ctx, params); } else { @@ -4413,7 +4398,7 @@ $.fn.createGradient = function createGradient(args) { stops.push(null); } } - let nstops = stops.length; + const nstops = stops.length; // Define start stop if not already defined if (stops[0] === null) { @@ -4499,14 +4484,14 @@ $.fn.setPixels = function setPixels(args) { if (params.width !== 0 && params.height !== 0) { // Only set pixels if width and height are not zero - let imgData = ctx.getImageData( + const imgData = ctx.getImageData( (params.x - params.width / 2) * canvasData.pixelRatio, (params.y - params.height / 2) * canvasData.pixelRatio, params.width * canvasData.pixelRatio, params.height * canvasData.pixelRatio ); - let pixelData = imgData.data; - let len = pixelData.length; + const pixelData = imgData.data; + const len = pixelData.length; // Loop through pixels with the "each" callback function if (params.each) { @@ -4567,19 +4552,19 @@ $.fn.detectPixelRatio = function detectPixelRatio(callback) { if (!ctx) { continue; } - let data = _getCanvasData(canvas); + const data = _getCanvasData(canvas); // If canvas has not already been scaled with this method if (!data.scaled) { // Determine device pixel ratios - let ratio = window.devicePixelRatio || 1; + const ratio = window.devicePixelRatio || 1; if (ratio !== 1) { // Scale canvas relative to ratio // Get the current canvas dimensions for future use - let oldWidth = canvas.width; - let oldHeight = canvas.height; + const oldWidth = canvas.width; + const oldHeight = canvas.height; // Resize canvas relative to the determined ratio canvas.width = oldWidth * ratio; @@ -4609,7 +4594,7 @@ $.fn.detectPixelRatio = function detectPixelRatio(callback) { // Clears the jCanvas cache jCanvas.clearCache = function clearCache() { - for (let cacheName in caches) { + for (const cacheName in caches) { if (Object.prototype.hasOwnProperty.call(caches, cacheName)) { caches[cacheName as keyof typeof caches] = {}; }