mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 14:39:30 -07:00
Merge pull request #88 from Utkarsh-Singhal-26/feat/pixel-blast
FEAT: New <PixelBlast /> background
This commit is contained in:
230
package-lock.json
generated
230
package-lock.json
generated
@@ -693,20 +693,20 @@
|
|||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/core": {
|
"node_modules/@emnapi/core": {
|
||||||
"version": "1.4.5",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz",
|
||||||
"integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==",
|
"integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emnapi/wasi-threads": "1.0.4",
|
"@emnapi/wasi-threads": "1.1.0",
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/runtime": {
|
"node_modules/@emnapi/runtime": {
|
||||||
"version": "1.4.5",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz",
|
||||||
"integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==",
|
"integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -714,9 +714,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/wasi-threads": {
|
"node_modules/@emnapi/wasi-threads": {
|
||||||
"version": "1.0.4",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
|
||||||
"integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==",
|
"integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1398,9 +1398,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ioredis/commands": {
|
"node_modules/@ioredis/commands": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.1.tgz",
|
||||||
"integrity": "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==",
|
"integrity": "sha512-bYtU8avhGIcje3IhvF9aSjsa5URMZBHnwKtOvXsT4sfYy9gppW11gLPT/9oNqlJZD47yPKveQFTAFWpHjKvUoQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
@@ -5077,9 +5077,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz",
|
||||||
"integrity": "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==",
|
"integrity": "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -5090,9 +5090,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==",
|
"integrity": "sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5103,9 +5103,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==",
|
"integrity": "sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5116,9 +5116,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.0.tgz",
|
||||||
"integrity": "sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==",
|
"integrity": "sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -5129,9 +5129,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.0.tgz",
|
||||||
"integrity": "sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==",
|
"integrity": "sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5142,9 +5142,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.0.tgz",
|
||||||
"integrity": "sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==",
|
"integrity": "sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -5155,9 +5155,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.0.tgz",
|
||||||
"integrity": "sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==",
|
"integrity": "sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -5168,9 +5168,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.0.tgz",
|
||||||
"integrity": "sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==",
|
"integrity": "sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -5181,9 +5181,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==",
|
"integrity": "sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5194,9 +5194,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==",
|
"integrity": "sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5207,9 +5207,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==",
|
"integrity": "sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@@ -5220,9 +5220,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==",
|
"integrity": "sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -5233,9 +5233,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==",
|
"integrity": "sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -5246,9 +5246,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==",
|
"integrity": "sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -5259,9 +5259,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==",
|
"integrity": "sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -5272,9 +5272,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.0.tgz",
|
||||||
"integrity": "sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==",
|
"integrity": "sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -5285,9 +5285,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.0.tgz",
|
||||||
"integrity": "sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==",
|
"integrity": "sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -5297,10 +5297,23 @@
|
|||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||||
|
"version": "4.50.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.0.tgz",
|
||||||
|
"integrity": "sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==",
|
"integrity": "sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -5311,9 +5324,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==",
|
"integrity": "sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -5324,9 +5337,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz",
|
||||||
"integrity": "sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==",
|
"integrity": "sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -7649,9 +7662,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001737",
|
"version": "1.0.30001739",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz",
|
||||||
"integrity": "sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==",
|
"integrity": "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -10107,9 +10120,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-east-asian-width": {
|
"node_modules/get-east-asian-width": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.1.tgz",
|
||||||
"integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
|
"integrity": "sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -12207,9 +12220,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/motion-v": {
|
"node_modules/motion-v": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/motion-v/-/motion-v-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/motion-v/-/motion-v-1.7.1.tgz",
|
||||||
"integrity": "sha512-5oPDF5GBpcRnIZuce7Wap09S8afH4JeBWD3VbMRg4hZKk0olQnTFuHjgQUGMpX3V1WXrZgyveoF02W51XMxx9w==",
|
"integrity": "sha512-B22fYcHGx05moUtoIH0ZP/JzeacGOHzLkLmMTKU9tRB+uVMSfgqiXVzZb602qiG1ap8W7TZ+5RD5R3MmODu9oA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"framer-motion": "12.23.12",
|
"framer-motion": "12.23.12",
|
||||||
@@ -14860,9 +14873,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.49.0",
|
"version": "4.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.0.tgz",
|
||||||
"integrity": "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==",
|
"integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.8"
|
"@types/estree": "1.0.8"
|
||||||
@@ -14875,26 +14888,27 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.49.0",
|
"@rollup/rollup-android-arm-eabi": "4.50.0",
|
||||||
"@rollup/rollup-android-arm64": "4.49.0",
|
"@rollup/rollup-android-arm64": "4.50.0",
|
||||||
"@rollup/rollup-darwin-arm64": "4.49.0",
|
"@rollup/rollup-darwin-arm64": "4.50.0",
|
||||||
"@rollup/rollup-darwin-x64": "4.49.0",
|
"@rollup/rollup-darwin-x64": "4.50.0",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.49.0",
|
"@rollup/rollup-freebsd-arm64": "4.50.0",
|
||||||
"@rollup/rollup-freebsd-x64": "4.49.0",
|
"@rollup/rollup-freebsd-x64": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.49.0",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.49.0",
|
"@rollup/rollup-linux-arm-musleabihf": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.49.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.49.0",
|
"@rollup/rollup-linux-arm64-musl": "4.50.0",
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": "4.49.0",
|
"@rollup/rollup-linux-loongarch64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-ppc64-gnu": "4.49.0",
|
"@rollup/rollup-linux-ppc64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.49.0",
|
"@rollup/rollup-linux-riscv64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-riscv64-musl": "4.49.0",
|
"@rollup/rollup-linux-riscv64-musl": "4.50.0",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.49.0",
|
"@rollup/rollup-linux-s390x-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.49.0",
|
"@rollup/rollup-linux-x64-gnu": "4.50.0",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.49.0",
|
"@rollup/rollup-linux-x64-musl": "4.50.0",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.49.0",
|
"@rollup/rollup-openharmony-arm64": "4.50.0",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.49.0",
|
"@rollup/rollup-win32-arm64-msvc": "4.50.0",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.49.0",
|
"@rollup/rollup-win32-ia32-msvc": "4.50.0",
|
||||||
|
"@rollup/rollup-win32-x64-msvc": "4.50.0",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16373,9 +16387,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unplugin": {
|
"node_modules/unplugin": {
|
||||||
"version": "2.3.9",
|
"version": "2.3.10",
|
||||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz",
|
||||||
"integrity": "sha512-2dcbZq6aprwXTkzptq3k5qm5B8cvpjG9ynPd5fyM2wDJuuF7PeUK64Sxf0d+X1ZyDOeGydbNzMqBSIVlH8GIfA==",
|
"integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/remapping": "^2.3.5",
|
"@jridgewell/remapping": "^2.3.5",
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="hero-main-content">
|
<div class="hero-main-content">
|
||||||
<router-link to="/backgrounds/prismatic-burst" class="hero-new-badge-container">
|
<router-link to="/backgrounds/pixel-blast" class="hero-new-badge-container">
|
||||||
<span class="hero-new-badge">New 🎉</span>
|
<span class="hero-new-badge">New 🎉</span>
|
||||||
<div class="hero-new-badge-text">
|
<div class="hero-new-badge-text">
|
||||||
<span>Prismatic Burst</span>
|
<span>Pixel Blast</span>
|
||||||
<i class="pi-arrow-right pi" style="font-size: 0.8rem"></i>
|
<i class="pi-arrow-right pi" style="font-size: 0.8rem"></i>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Highlighted sidebar items
|
// Highlighted sidebar items
|
||||||
export const NEW = ['Gradual Blur', 'Gradient Blinds', 'Bubble Menu', 'Prism', 'Plasma', 'Electric Border', 'Target Cursor', 'Pill Nav', 'Card Nav', 'Logo Loop', 'Prismatic Burst'];
|
export const NEW = ['Pixel Blast', 'Gradual Blur', 'Gradient Blinds', 'Bubble Menu', 'Prism', 'Plasma', 'Electric Border', 'Target Cursor', 'Pill Nav', 'Card Nav', 'Logo Loop', 'Prismatic Burst'];
|
||||||
export const UPDATED = [];
|
export const UPDATED = [];
|
||||||
|
|
||||||
// Used for main sidebar navigation
|
// Used for main sidebar navigation
|
||||||
@@ -101,6 +101,7 @@ export const CATEGORIES = [
|
|||||||
'Prism',
|
'Prism',
|
||||||
'Aurora',
|
'Aurora',
|
||||||
'Beams',
|
'Beams',
|
||||||
|
'Pixel Blast',
|
||||||
'Dark Veil',
|
'Dark Veil',
|
||||||
'Dither',
|
'Dither',
|
||||||
'Gradient Blinds',
|
'Gradient Blinds',
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ const backgrounds = {
|
|||||||
'prism': () => import('../demo/Backgrounds/PrismDemo.vue'),
|
'prism': () => import('../demo/Backgrounds/PrismDemo.vue'),
|
||||||
'gradient-blinds': () => import('../demo/Backgrounds/GradientBlindsDemo.vue'),
|
'gradient-blinds': () => import('../demo/Backgrounds/GradientBlindsDemo.vue'),
|
||||||
'prismatic-burst': () => import('../demo/Backgrounds/PrismaticBurstDemo.vue'),
|
'prismatic-burst': () => import('../demo/Backgrounds/PrismaticBurstDemo.vue'),
|
||||||
|
'pixel-blast': () => import('../demo/Backgrounds/PixelBlastDemo.vue'),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const componentMap = {
|
export const componentMap = {
|
||||||
|
|||||||
35
src/constants/code/Backgrounds/pixelBlastCode.ts
Normal file
35
src/constants/code/Backgrounds/pixelBlastCode.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import code from '@content/Backgrounds/PixelBlast/PixelBlast.vue?raw';
|
||||||
|
import { createCodeObject } from '../../../types/code';
|
||||||
|
|
||||||
|
export const pixelBlast = createCodeObject(code, 'Backgrounds/PixelBlast', {
|
||||||
|
installation: `npm install three postprocessing`,
|
||||||
|
usage: `// Component inspired by github.com/zavalit/bayer-dithering-webgl-demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="width: 100%; height: 600px; position: relative">
|
||||||
|
<PixelBlast
|
||||||
|
variant="circle"
|
||||||
|
:pixel-size="6"
|
||||||
|
color="#A7EF9E"
|
||||||
|
:pattern-scale="3"
|
||||||
|
:pattern-density="1.2"
|
||||||
|
:pixel-size-jitter="0.5"
|
||||||
|
:enable-ripples="true"
|
||||||
|
:ripple-speed="0.4"
|
||||||
|
:ripple-thickness="0.12"
|
||||||
|
:ripple-intensity-scale="1.5"
|
||||||
|
:liquid="true"
|
||||||
|
:liquid-strength="0.12"
|
||||||
|
:liquid-radius="1.2"
|
||||||
|
:liquid-wobble-speed="5"
|
||||||
|
:speed="0.6"
|
||||||
|
:edge-fade="0.25"
|
||||||
|
:transparent="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import PixelBlast from './PixelBlast.vue'
|
||||||
|
</script>`
|
||||||
|
});
|
||||||
661
src/content/Backgrounds/PixelBlast/PixelBlast.vue
Normal file
661
src/content/Backgrounds/PixelBlast/PixelBlast.vue
Normal file
@@ -0,0 +1,661 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
ref="containerRef"
|
||||||
|
:class="['w-full h-full relative overflow-hidden', className]"
|
||||||
|
:style="style"
|
||||||
|
aria-label="PixelBlast interactive background"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Effect, EffectComposer, EffectPass, RenderPass } from 'postprocessing';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { onBeforeUnmount, onMounted, ref, useTemplateRef, watch, type CSSProperties } from 'vue';
|
||||||
|
|
||||||
|
export type PixelBlastVariant = 'square' | 'circle' | 'triangle' | 'diamond';
|
||||||
|
|
||||||
|
type PixelBlastProps = {
|
||||||
|
variant?: PixelBlastVariant;
|
||||||
|
pixelSize?: number;
|
||||||
|
color?: string;
|
||||||
|
className?: string;
|
||||||
|
style?: CSSProperties;
|
||||||
|
antialias?: boolean;
|
||||||
|
patternScale?: number;
|
||||||
|
patternDensity?: number;
|
||||||
|
liquid?: boolean;
|
||||||
|
liquidStrength?: number;
|
||||||
|
liquidRadius?: number;
|
||||||
|
pixelSizeJitter?: number;
|
||||||
|
enableRipples?: boolean;
|
||||||
|
rippleIntensityScale?: number;
|
||||||
|
rippleThickness?: number;
|
||||||
|
rippleSpeed?: number;
|
||||||
|
liquidWobbleSpeed?: number;
|
||||||
|
autoPauseOffscreen?: boolean;
|
||||||
|
speed?: number;
|
||||||
|
transparent?: boolean;
|
||||||
|
edgeFade?: number;
|
||||||
|
noiseAmount?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createTouchTexture = () => {
|
||||||
|
const size = 64;
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
if (!ctx) throw new Error('2D context not available');
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
const texture = new THREE.Texture(canvas);
|
||||||
|
texture.minFilter = THREE.LinearFilter;
|
||||||
|
texture.magFilter = THREE.LinearFilter;
|
||||||
|
texture.generateMipmaps = false;
|
||||||
|
const trail: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
vx: number;
|
||||||
|
vy: number;
|
||||||
|
force: number;
|
||||||
|
age: number;
|
||||||
|
}[] = [];
|
||||||
|
let last: { x: number; y: number } | null = null;
|
||||||
|
const maxAge = 64;
|
||||||
|
let radius = 0.1 * size;
|
||||||
|
const speed = 1 / maxAge;
|
||||||
|
const clear = () => {
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
};
|
||||||
|
const drawPoint = (p: { x: number; y: number; vx: number; vy: number; force: number; age: number }) => {
|
||||||
|
const pos = { x: p.x * size, y: (1 - p.y) * size };
|
||||||
|
let intensity = 1;
|
||||||
|
const easeOutSine = (t: number) => Math.sin((t * Math.PI) / 2);
|
||||||
|
const easeOutQuad = (t: number) => -t * (t - 2);
|
||||||
|
if (p.age < maxAge * 0.3) intensity = easeOutSine(p.age / (maxAge * 0.3));
|
||||||
|
else intensity = easeOutQuad(1 - (p.age - maxAge * 0.3) / (maxAge * 0.7)) || 0;
|
||||||
|
intensity *= p.force;
|
||||||
|
const color = `${((p.vx + 1) / 2) * 255}, ${((p.vy + 1) / 2) * 255}, ${intensity * 255}`;
|
||||||
|
const offset = size * 5;
|
||||||
|
ctx.shadowOffsetX = offset;
|
||||||
|
ctx.shadowOffsetY = offset;
|
||||||
|
ctx.shadowBlur = radius;
|
||||||
|
ctx.shadowColor = `rgba(${color},${0.22 * intensity})`;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.fillStyle = 'rgba(255,0,0,1)';
|
||||||
|
ctx.arc(pos.x - offset, pos.y - offset, radius, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
};
|
||||||
|
const addTouch = (norm: { x: number; y: number }) => {
|
||||||
|
let force = 0;
|
||||||
|
let vx = 0;
|
||||||
|
let vy = 0;
|
||||||
|
if (last) {
|
||||||
|
const dx = norm.x - last.x;
|
||||||
|
const dy = norm.y - last.y;
|
||||||
|
if (dx === 0 && dy === 0) return;
|
||||||
|
const dd = dx * dx + dy * dy;
|
||||||
|
const d = Math.sqrt(dd);
|
||||||
|
vx = dx / (d || 1);
|
||||||
|
vy = dy / (d || 1);
|
||||||
|
force = Math.min(dd * 10000, 1);
|
||||||
|
}
|
||||||
|
last = { x: norm.x, y: norm.y };
|
||||||
|
trail.push({ x: norm.x, y: norm.y, age: 0, force, vx, vy });
|
||||||
|
};
|
||||||
|
const update = () => {
|
||||||
|
clear();
|
||||||
|
for (let i = trail.length - 1; i >= 0; i--) {
|
||||||
|
const point = trail[i];
|
||||||
|
const f = point.force * speed * (1 - point.age / maxAge);
|
||||||
|
point.x += point.vx * f;
|
||||||
|
point.y += point.vy * f;
|
||||||
|
point.age++;
|
||||||
|
if (point.age > maxAge) trail.splice(i, 1);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < trail.length; i++) drawPoint(trail[i]);
|
||||||
|
texture.needsUpdate = true;
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
canvas,
|
||||||
|
texture,
|
||||||
|
addTouch,
|
||||||
|
update,
|
||||||
|
set radiusScale(v: number) {
|
||||||
|
radius = 0.1 * size * v;
|
||||||
|
},
|
||||||
|
get radiusScale() {
|
||||||
|
return radius / (0.1 * size);
|
||||||
|
},
|
||||||
|
size
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createLiquidEffect = (texture: THREE.Texture, opts?: { strength?: number; freq?: number }) => {
|
||||||
|
const fragment = `
|
||||||
|
uniform sampler2D uTexture;
|
||||||
|
uniform float uStrength;
|
||||||
|
uniform float uTime;
|
||||||
|
uniform float uFreq;
|
||||||
|
|
||||||
|
void mainUv(inout vec2 uv) {
|
||||||
|
vec4 tex = texture2D(uTexture, uv);
|
||||||
|
float vx = tex.r * 2.0 - 1.0;
|
||||||
|
float vy = tex.g * 2.0 - 1.0;
|
||||||
|
float intensity = tex.b;
|
||||||
|
|
||||||
|
float wave = 0.5 + 0.5 * sin(uTime * uFreq + intensity * 6.2831853);
|
||||||
|
|
||||||
|
float amt = uStrength * intensity * wave;
|
||||||
|
|
||||||
|
uv += vec2(vx, vy) * amt;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return new Effect('LiquidEffect', fragment, {
|
||||||
|
uniforms: new Map<string, THREE.Uniform>([
|
||||||
|
['uTexture', new THREE.Uniform(texture)],
|
||||||
|
['uStrength', new THREE.Uniform(opts?.strength ?? 0.025)],
|
||||||
|
['uTime', new THREE.Uniform(0)],
|
||||||
|
['uFreq', new THREE.Uniform(opts?.freq ?? 4.5)]
|
||||||
|
])
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const SHAPE_MAP: Record<PixelBlastVariant, number> = {
|
||||||
|
square: 0,
|
||||||
|
circle: 1,
|
||||||
|
triangle: 2,
|
||||||
|
diamond: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const VERTEX_SRC = `
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(position, 1.0);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FRAGMENT_SRC = `
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform vec3 uColor;
|
||||||
|
uniform vec2 uResolution;
|
||||||
|
uniform float uTime;
|
||||||
|
uniform float uPixelSize;
|
||||||
|
uniform float uScale;
|
||||||
|
uniform float uDensity;
|
||||||
|
uniform float uPixelJitter;
|
||||||
|
uniform int uEnableRipples;
|
||||||
|
uniform float uRippleSpeed;
|
||||||
|
uniform float uRippleThickness;
|
||||||
|
uniform float uRippleIntensity;
|
||||||
|
uniform float uEdgeFade;
|
||||||
|
|
||||||
|
uniform int uShapeType;
|
||||||
|
const int SHAPE_SQUARE = 0;
|
||||||
|
const int SHAPE_CIRCLE = 1;
|
||||||
|
const int SHAPE_TRIANGLE = 2;
|
||||||
|
const int SHAPE_DIAMOND = 3;
|
||||||
|
|
||||||
|
const int MAX_CLICKS = 10;
|
||||||
|
|
||||||
|
uniform vec2 uClickPos [MAX_CLICKS];
|
||||||
|
uniform float uClickTimes[MAX_CLICKS];
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
float Bayer2(vec2 a) {
|
||||||
|
a = floor(a);
|
||||||
|
return fract(a.x / 2. + a.y * a.y * .75);
|
||||||
|
}
|
||||||
|
#define Bayer4(a) (Bayer2(.5*(a))*0.25 + Bayer2(a))
|
||||||
|
#define Bayer8(a) (Bayer4(.5*(a))*0.25 + Bayer2(a))
|
||||||
|
|
||||||
|
#define FBM_OCTAVES 5
|
||||||
|
#define FBM_LACUNARITY 1.25
|
||||||
|
#define FBM_GAIN 1.0
|
||||||
|
|
||||||
|
float hash11(float n){ return fract(sin(n)*43758.5453); }
|
||||||
|
|
||||||
|
float vnoise(vec3 p){
|
||||||
|
vec3 ip = floor(p);
|
||||||
|
vec3 fp = fract(p);
|
||||||
|
float n000 = hash11(dot(ip + vec3(0.0,0.0,0.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n100 = hash11(dot(ip + vec3(1.0,0.0,0.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n010 = hash11(dot(ip + vec3(0.0,1.0,0.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n110 = hash11(dot(ip + vec3(1.0,1.0,0.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n001 = hash11(dot(ip + vec3(0.0,0.0,1.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n101 = hash11(dot(ip + vec3(1.0,0.0,1.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n011 = hash11(dot(ip + vec3(0.0,1.0,1.0), vec3(1.0,57.0,113.0)));
|
||||||
|
float n111 = hash11(dot(ip + vec3(1.0,1.0,1.0), vec3(1.0,57.0,113.0)));
|
||||||
|
vec3 w = fp*fp*fp*(fp*(fp*6.0-15.0)+10.0);
|
||||||
|
float x00 = mix(n000, n100, w.x);
|
||||||
|
float x10 = mix(n010, n110, w.x);
|
||||||
|
float x01 = mix(n001, n101, w.x);
|
||||||
|
float x11 = mix(n011, n111, w.x);
|
||||||
|
float y0 = mix(x00, x10, w.y);
|
||||||
|
float y1 = mix(x01, x11, w.y);
|
||||||
|
return mix(y0, y1, w.z) * 2.0 - 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fbm2(vec2 uv, float t){
|
||||||
|
vec3 p = vec3(uv * uScale, t);
|
||||||
|
float amp = 1.0;
|
||||||
|
float freq = 1.0;
|
||||||
|
float sum = 1.0;
|
||||||
|
for (int i = 0; i < FBM_OCTAVES; ++i){
|
||||||
|
sum += amp * vnoise(p * freq);
|
||||||
|
freq *= FBM_LACUNARITY;
|
||||||
|
amp *= FBM_GAIN;
|
||||||
|
}
|
||||||
|
return sum * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float maskCircle(vec2 p, float cov){
|
||||||
|
float r = sqrt(cov) * .25;
|
||||||
|
float d = length(p - 0.5) - r;
|
||||||
|
float aa = 0.5 * fwidth(d);
|
||||||
|
return cov * (1.0 - smoothstep(-aa, aa, d * 2.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
float maskTriangle(vec2 p, vec2 id, float cov){
|
||||||
|
bool flip = mod(id.x + id.y, 2.0) > 0.5;
|
||||||
|
if (flip) p.x = 1.0 - p.x;
|
||||||
|
float r = sqrt(cov);
|
||||||
|
float d = p.y - r*(1.0 - p.x);
|
||||||
|
float aa = fwidth(d);
|
||||||
|
return cov * clamp(0.5 - d/aa, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float maskDiamond(vec2 p, float cov){
|
||||||
|
float r = sqrt(cov) * 0.564;
|
||||||
|
return step(abs(p.x - 0.49) + abs(p.y - 0.49), r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
float pixelSize = uPixelSize;
|
||||||
|
vec2 fragCoord = gl_FragCoord.xy - uResolution * .5;
|
||||||
|
float aspectRatio = uResolution.x / uResolution.y;
|
||||||
|
|
||||||
|
vec2 pixelId = floor(fragCoord / pixelSize);
|
||||||
|
vec2 pixelUV = fract(fragCoord / pixelSize);
|
||||||
|
|
||||||
|
float cellPixelSize = 8.0 * pixelSize;
|
||||||
|
vec2 cellId = floor(fragCoord / cellPixelSize);
|
||||||
|
vec2 cellCoord = cellId * cellPixelSize;
|
||||||
|
vec2 uv = cellCoord / uResolution * vec2(aspectRatio, 1.0);
|
||||||
|
|
||||||
|
float base = fbm2(uv, uTime * 0.05);
|
||||||
|
base = base * 0.5 - 0.65;
|
||||||
|
|
||||||
|
float feed = base + (uDensity - 0.5) * 0.3;
|
||||||
|
|
||||||
|
float speed = uRippleSpeed;
|
||||||
|
float thickness = uRippleThickness;
|
||||||
|
const float dampT = 1.0;
|
||||||
|
const float dampR = 10.0;
|
||||||
|
|
||||||
|
if (uEnableRipples == 1) {
|
||||||
|
for (int i = 0; i < MAX_CLICKS; ++i){
|
||||||
|
vec2 pos = uClickPos[i];
|
||||||
|
if (pos.x < 0.0) continue;
|
||||||
|
float cellPixelSize = 8.0 * pixelSize;
|
||||||
|
vec2 cuv = (((pos - uResolution * .5 - cellPixelSize * .5) / (uResolution))) * vec2(aspectRatio, 1.0);
|
||||||
|
float t = max(uTime - uClickTimes[i], 0.0);
|
||||||
|
float r = distance(uv, cuv);
|
||||||
|
float waveR = speed * t;
|
||||||
|
float ring = exp(-pow((r - waveR) / thickness, 2.0));
|
||||||
|
float atten = exp(-dampT * t) * exp(-dampR * r);
|
||||||
|
feed = max(feed, ring * atten * uRippleIntensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float bayer = Bayer8(fragCoord / uPixelSize) - 0.5;
|
||||||
|
float bw = step(0.5, feed + bayer);
|
||||||
|
|
||||||
|
float h = fract(sin(dot(floor(fragCoord / uPixelSize), vec2(127.1, 311.7))) * 43758.5453);
|
||||||
|
float jitterScale = 1.0 + (h - 0.5) * uPixelJitter;
|
||||||
|
float coverage = bw * jitterScale;
|
||||||
|
float M;
|
||||||
|
if (uShapeType == SHAPE_CIRCLE) M = maskCircle (pixelUV, coverage);
|
||||||
|
else if (uShapeType == SHAPE_TRIANGLE) M = maskTriangle(pixelUV, pixelId, coverage);
|
||||||
|
else if (uShapeType == SHAPE_DIAMOND) M = maskDiamond(pixelUV, coverage);
|
||||||
|
else M = coverage;
|
||||||
|
|
||||||
|
if (uEdgeFade > 0.0) {
|
||||||
|
vec2 norm = gl_FragCoord.xy / uResolution;
|
||||||
|
float edge = min(min(norm.x, norm.y), min(1.0 - norm.x, 1.0 - norm.y));
|
||||||
|
float fade = smoothstep(0.0, uEdgeFade, edge);
|
||||||
|
M *= fade;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 color = uColor;
|
||||||
|
fragColor = vec4(color, M);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MAX_CLICKS = 10;
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PixelBlastProps>(), {
|
||||||
|
variant: 'square',
|
||||||
|
pixelSize: 3,
|
||||||
|
color: '#B19EEF',
|
||||||
|
antialias: true,
|
||||||
|
patternScale: 2,
|
||||||
|
patternDensity: 1,
|
||||||
|
liquid: false,
|
||||||
|
liquidStrength: 0.1,
|
||||||
|
liquidRadius: 1,
|
||||||
|
pixelSizeJitter: 0,
|
||||||
|
enableRipples: true,
|
||||||
|
rippleIntensityScale: 1,
|
||||||
|
rippleThickness: 0.1,
|
||||||
|
rippleSpeed: 0.3,
|
||||||
|
liquidWobbleSpeed: 4.5,
|
||||||
|
autoPauseOffscreen: true,
|
||||||
|
speed: 0.5,
|
||||||
|
transparent: true,
|
||||||
|
edgeFade: 0.5,
|
||||||
|
noiseAmount: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const containerRef = useTemplateRef<HTMLDivElement>('containerRef');
|
||||||
|
const visibilityRef = ref({ visible: true });
|
||||||
|
const speedRef = ref(props.speed);
|
||||||
|
|
||||||
|
const threeRef = ref<{
|
||||||
|
renderer: THREE.WebGLRenderer;
|
||||||
|
scene: THREE.Scene;
|
||||||
|
camera: THREE.OrthographicCamera;
|
||||||
|
material: THREE.ShaderMaterial;
|
||||||
|
clock: THREE.Clock;
|
||||||
|
clickIx: number;
|
||||||
|
uniforms: {
|
||||||
|
uResolution: { value: THREE.Vector2 };
|
||||||
|
uTime: { value: number };
|
||||||
|
uColor: { value: THREE.Color };
|
||||||
|
uClickPos: { value: THREE.Vector2[] };
|
||||||
|
uClickTimes: { value: Float32Array };
|
||||||
|
uShapeType: { value: number };
|
||||||
|
uPixelSize: { value: number };
|
||||||
|
uScale: { value: number };
|
||||||
|
uDensity: { value: number };
|
||||||
|
uPixelJitter: { value: number };
|
||||||
|
uEnableRipples: { value: number };
|
||||||
|
uRippleSpeed: { value: number };
|
||||||
|
uRippleThickness: { value: number };
|
||||||
|
uRippleIntensity: { value: number };
|
||||||
|
uEdgeFade: { value: number };
|
||||||
|
};
|
||||||
|
resizeObserver?: ResizeObserver;
|
||||||
|
raf?: number;
|
||||||
|
quad?: THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial>;
|
||||||
|
timeOffset?: number;
|
||||||
|
composer?: EffectComposer;
|
||||||
|
touch?: ReturnType<typeof createTouchTexture>;
|
||||||
|
liquidEffect?: Effect;
|
||||||
|
} | null>(null);
|
||||||
|
const prevConfigRef = ref<any>(null);
|
||||||
|
|
||||||
|
let cleanup: (() => void) | null = null;
|
||||||
|
|
||||||
|
const setup = () => {
|
||||||
|
const container = containerRef.value;
|
||||||
|
if (!container) return;
|
||||||
|
speedRef.value = props.speed;
|
||||||
|
const needsReinitKeys = ['antialias', 'liquid', 'noiseAmount'];
|
||||||
|
const cfg = { antialias: props.antialias, liquid: props.liquid, noiseAmount: props.noiseAmount };
|
||||||
|
let mustReinit = false;
|
||||||
|
if (!threeRef.value) mustReinit = true;
|
||||||
|
else if (prevConfigRef.value) {
|
||||||
|
for (const k of needsReinitKeys)
|
||||||
|
if (prevConfigRef.value[k] !== (cfg as any)[k]) {
|
||||||
|
mustReinit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mustReinit) {
|
||||||
|
if (threeRef.value) {
|
||||||
|
const t = threeRef.value;
|
||||||
|
t.resizeObserver?.disconnect();
|
||||||
|
cancelAnimationFrame(t.raf!);
|
||||||
|
t.quad?.geometry.dispose();
|
||||||
|
t.material.dispose();
|
||||||
|
t.composer?.dispose();
|
||||||
|
t.renderer.dispose();
|
||||||
|
if (t.renderer.domElement.parentElement === container) container.removeChild(t.renderer.domElement);
|
||||||
|
threeRef.value = null;
|
||||||
|
}
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const gl = canvas.getContext('webgl2', { antialias: props.antialias, alpha: true });
|
||||||
|
if (!gl) return;
|
||||||
|
const renderer = new THREE.WebGLRenderer({
|
||||||
|
canvas,
|
||||||
|
context: gl as WebGL2RenderingContext,
|
||||||
|
antialias: props.antialias,
|
||||||
|
alpha: true
|
||||||
|
});
|
||||||
|
renderer.domElement.style.width = '100%';
|
||||||
|
renderer.domElement.style.height = '100%';
|
||||||
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
||||||
|
container.appendChild(renderer.domElement);
|
||||||
|
const uniforms = {
|
||||||
|
uResolution: { value: new THREE.Vector2(0, 0) },
|
||||||
|
uTime: { value: 0 },
|
||||||
|
uColor: { value: new THREE.Color(props.color) },
|
||||||
|
uClickPos: {
|
||||||
|
value: Array.from({ length: MAX_CLICKS }, () => new THREE.Vector2(-1, -1))
|
||||||
|
},
|
||||||
|
uClickTimes: { value: new Float32Array(MAX_CLICKS) },
|
||||||
|
uShapeType: { value: SHAPE_MAP[props.variant] ?? 0 },
|
||||||
|
uPixelSize: { value: props.pixelSize * renderer.getPixelRatio() },
|
||||||
|
uScale: { value: props.patternScale },
|
||||||
|
uDensity: { value: props.patternDensity },
|
||||||
|
uPixelJitter: { value: props.pixelSizeJitter },
|
||||||
|
uEnableRipples: { value: props.enableRipples ? 1 : 0 },
|
||||||
|
uRippleSpeed: { value: props.rippleSpeed },
|
||||||
|
uRippleThickness: { value: props.rippleThickness },
|
||||||
|
uRippleIntensity: { value: props.rippleIntensityScale },
|
||||||
|
uEdgeFade: { value: props.edgeFade }
|
||||||
|
};
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
||||||
|
const material = new THREE.ShaderMaterial({
|
||||||
|
vertexShader: VERTEX_SRC,
|
||||||
|
fragmentShader: FRAGMENT_SRC,
|
||||||
|
uniforms,
|
||||||
|
transparent: true,
|
||||||
|
glslVersion: THREE.GLSL3,
|
||||||
|
depthTest: false,
|
||||||
|
depthWrite: false
|
||||||
|
});
|
||||||
|
const quadGeom = new THREE.PlaneGeometry(2, 2);
|
||||||
|
const quad = new THREE.Mesh(quadGeom, material);
|
||||||
|
scene.add(quad);
|
||||||
|
const clock = new THREE.Clock();
|
||||||
|
const setSize = () => {
|
||||||
|
const w = container.clientWidth || 1;
|
||||||
|
const h = container.clientHeight || 1;
|
||||||
|
renderer.setSize(w, h, false);
|
||||||
|
uniforms.uResolution.value.set(renderer.domElement.width, renderer.domElement.height);
|
||||||
|
if (threeRef.value?.composer)
|
||||||
|
threeRef.value.composer.setSize(renderer.domElement.width, renderer.domElement.height);
|
||||||
|
uniforms.uPixelSize.value = props.pixelSize * renderer.getPixelRatio();
|
||||||
|
};
|
||||||
|
setSize();
|
||||||
|
const ro = new ResizeObserver(setSize);
|
||||||
|
ro.observe(container);
|
||||||
|
const randomFloat = () => {
|
||||||
|
if (typeof window !== 'undefined' && (window as any).crypto?.getRandomValues) {
|
||||||
|
const u32 = new Uint32Array(1);
|
||||||
|
window.crypto.getRandomValues(u32);
|
||||||
|
return u32[0] / 0xffffffff;
|
||||||
|
}
|
||||||
|
return Math.random();
|
||||||
|
};
|
||||||
|
const timeOffset = randomFloat() * 1000;
|
||||||
|
let composer: EffectComposer | undefined;
|
||||||
|
let touch: ReturnType<typeof createTouchTexture> | undefined;
|
||||||
|
let liquidEffect: Effect | undefined;
|
||||||
|
if (props.liquid) {
|
||||||
|
touch = createTouchTexture();
|
||||||
|
touch.radiusScale = props.liquidRadius;
|
||||||
|
composer = new EffectComposer(renderer);
|
||||||
|
const renderPass = new RenderPass(scene, camera);
|
||||||
|
liquidEffect = createLiquidEffect(touch.texture, {
|
||||||
|
strength: props.liquidStrength,
|
||||||
|
freq: props.liquidWobbleSpeed
|
||||||
|
});
|
||||||
|
const effectPass = new EffectPass(camera, liquidEffect);
|
||||||
|
effectPass.renderToScreen = true;
|
||||||
|
composer.addPass(renderPass);
|
||||||
|
composer.addPass(effectPass);
|
||||||
|
}
|
||||||
|
if (props.noiseAmount > 0) {
|
||||||
|
if (!composer) {
|
||||||
|
composer = new EffectComposer(renderer);
|
||||||
|
composer.addPass(new RenderPass(scene, camera));
|
||||||
|
}
|
||||||
|
const noiseEffect = new Effect(
|
||||||
|
'NoiseEffect',
|
||||||
|
`uniform float uTime; uniform float uAmount; float hash(vec2 p){ return fract(sin(dot(p, vec2(127.1,311.7))) * 43758.5453);} void mainUv(inout vec2 uv){} void mainImage(const in vec4 inputColor,const in vec2 uv,out vec4 outputColor){ float n=hash(floor(uv*vec2(1920.0,1080.0))+floor(uTime*60.0)); float g=(n-0.5)*uAmount; outputColor=inputColor+vec4(vec3(g),0.0);} `,
|
||||||
|
{
|
||||||
|
uniforms: new Map<string, THREE.Uniform>([
|
||||||
|
['uTime', new THREE.Uniform(0)],
|
||||||
|
['uAmount', new THREE.Uniform(props.noiseAmount)]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const noisePass = new EffectPass(camera, noiseEffect);
|
||||||
|
noisePass.renderToScreen = true;
|
||||||
|
if (composer && composer.passes.length > 0) composer.passes.forEach(p => ((p as any).renderToScreen = false));
|
||||||
|
composer.addPass(noisePass);
|
||||||
|
}
|
||||||
|
if (composer) composer.setSize(renderer.domElement.width, renderer.domElement.height);
|
||||||
|
const mapToPixels = (e: PointerEvent) => {
|
||||||
|
const rect = renderer.domElement.getBoundingClientRect();
|
||||||
|
const scaleX = renderer.domElement.width / rect.width;
|
||||||
|
const scaleY = renderer.domElement.height / rect.height;
|
||||||
|
const fx = (e.clientX - rect.left) * scaleX;
|
||||||
|
const fy = (rect.height - (e.clientY - rect.top)) * scaleY;
|
||||||
|
return {
|
||||||
|
fx,
|
||||||
|
fy,
|
||||||
|
w: renderer.domElement.width,
|
||||||
|
h: renderer.domElement.height
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const onPointerDown = (e: PointerEvent) => {
|
||||||
|
const { fx, fy } = mapToPixels(e);
|
||||||
|
const ix = threeRef.value?.clickIx ?? 0;
|
||||||
|
uniforms.uClickPos.value[ix].set(fx, fy);
|
||||||
|
uniforms.uClickTimes.value[ix] = uniforms.uTime.value;
|
||||||
|
if (threeRef.value) threeRef.value.clickIx = (ix + 1) % MAX_CLICKS;
|
||||||
|
};
|
||||||
|
const onPointerMove = (e: PointerEvent) => {
|
||||||
|
if (!touch) return;
|
||||||
|
const { fx, fy, w, h } = mapToPixels(e);
|
||||||
|
touch.addTouch({ x: fx / w, y: fy / h });
|
||||||
|
};
|
||||||
|
renderer.domElement.addEventListener('pointerdown', onPointerDown, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
|
renderer.domElement.addEventListener('pointermove', onPointerMove, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
|
let raf = 0;
|
||||||
|
const animate = () => {
|
||||||
|
if (props.autoPauseOffscreen && !visibilityRef.value.visible) {
|
||||||
|
raf = requestAnimationFrame(animate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uniforms.uTime.value = timeOffset + clock.getElapsedTime() * speedRef.value;
|
||||||
|
if (liquidEffect) (liquidEffect as any).uniforms.get('uTime').value = uniforms.uTime.value;
|
||||||
|
if (composer) {
|
||||||
|
if (touch) touch.update();
|
||||||
|
composer.passes.forEach(p => {
|
||||||
|
const effs = (p as any).effects;
|
||||||
|
if (effs)
|
||||||
|
effs.forEach((eff: any) => {
|
||||||
|
const u = eff.uniforms?.get('uTime');
|
||||||
|
if (u) u.value = uniforms.uTime.value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
composer.render();
|
||||||
|
} else renderer.render(scene, camera);
|
||||||
|
raf = requestAnimationFrame(animate);
|
||||||
|
};
|
||||||
|
raf = requestAnimationFrame(animate);
|
||||||
|
threeRef.value = {
|
||||||
|
renderer,
|
||||||
|
scene,
|
||||||
|
camera,
|
||||||
|
material,
|
||||||
|
clock,
|
||||||
|
clickIx: 0,
|
||||||
|
uniforms,
|
||||||
|
resizeObserver: ro,
|
||||||
|
raf,
|
||||||
|
quad,
|
||||||
|
timeOffset,
|
||||||
|
composer,
|
||||||
|
touch,
|
||||||
|
liquidEffect
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const t = threeRef.value!;
|
||||||
|
t.uniforms.uShapeType.value = SHAPE_MAP[props.variant] ?? 0;
|
||||||
|
t.uniforms.uPixelSize.value = props.pixelSize * t.renderer.getPixelRatio();
|
||||||
|
t.uniforms.uColor.value.set(props.color);
|
||||||
|
t.uniforms.uScale.value = props.patternScale;
|
||||||
|
t.uniforms.uDensity.value = props.patternDensity;
|
||||||
|
t.uniforms.uPixelJitter.value = props.pixelSizeJitter;
|
||||||
|
t.uniforms.uEnableRipples.value = props.enableRipples ? 1 : 0;
|
||||||
|
t.uniforms.uRippleIntensity.value = props.rippleIntensityScale;
|
||||||
|
t.uniforms.uRippleThickness.value = props.rippleThickness;
|
||||||
|
t.uniforms.uRippleSpeed.value = props.rippleSpeed;
|
||||||
|
t.uniforms.uEdgeFade.value = props.edgeFade;
|
||||||
|
if (props.transparent) t.renderer.setClearAlpha(0);
|
||||||
|
else t.renderer.setClearColor(0x000000, 1);
|
||||||
|
if (t.liquidEffect) {
|
||||||
|
const uStrength = (t.liquidEffect as any).uniforms.get('uStrength');
|
||||||
|
if (uStrength) uStrength.value = props.liquidStrength;
|
||||||
|
const uFreq = (t.liquidEffect as any).uniforms.get('uFreq');
|
||||||
|
if (uFreq) uFreq.value = props.liquidWobbleSpeed;
|
||||||
|
}
|
||||||
|
if (t.touch) t.touch.radiusScale = props.liquidRadius;
|
||||||
|
}
|
||||||
|
prevConfigRef.value = cfg;
|
||||||
|
|
||||||
|
cleanup = () => {
|
||||||
|
if (threeRef.value && mustReinit) return;
|
||||||
|
if (!threeRef.value) return;
|
||||||
|
const t = threeRef.value;
|
||||||
|
t.resizeObserver?.disconnect();
|
||||||
|
cancelAnimationFrame(t.raf!);
|
||||||
|
t.quad?.geometry.dispose();
|
||||||
|
t.material.dispose();
|
||||||
|
t.composer?.dispose();
|
||||||
|
t.renderer.dispose();
|
||||||
|
if (t.renderer.domElement.parentElement === container) container.removeChild(t.renderer.domElement);
|
||||||
|
threeRef.value = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
cleanup?.();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
props,
|
||||||
|
() => {
|
||||||
|
cleanup?.();
|
||||||
|
setup();
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
</script>
|
||||||
198
src/demo/Backgrounds/PixelBlastDemo.vue
Normal file
198
src/demo/Backgrounds/PixelBlastDemo.vue
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
<template>
|
||||||
|
<TabbedLayout>
|
||||||
|
<template #preview>
|
||||||
|
<div class="relative p-0 h-[600px] overflow-hidden demo-container">
|
||||||
|
<PixelBlast
|
||||||
|
:variant="variant"
|
||||||
|
:pixel-size="pixelSize"
|
||||||
|
:color="color"
|
||||||
|
:pattern-scale="patternScale"
|
||||||
|
:pattern-density="patternDensity"
|
||||||
|
:pixel-size-jitter="pixelSizeJitter"
|
||||||
|
:enable-ripples="enableRipples"
|
||||||
|
:liquid="liquid"
|
||||||
|
:speed="speed"
|
||||||
|
:edge-fade="edgeFade"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BackgroundContent pill-text="New Background" headline="It's dangerous to go alone! Take this." />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Customize>
|
||||||
|
<PreviewColor title="Color" v-model="color" />
|
||||||
|
<PreviewSelect title="Variant" v-model="variant" :options="variantOptions" />
|
||||||
|
<PreviewSlider title="Pixel Size" v-model="pixelSize" :min="1" :max="5" :step="1" />
|
||||||
|
<PreviewSlider title="Pattern Scale" v-model="patternScale" :min="0.25" :max="8" :step="0.25" />
|
||||||
|
<PreviewSlider title="Pattern Density" v-model="patternDensity" :min="0" :max="2" :step="0.05" />
|
||||||
|
<PreviewSlider title="Pixel Jitter" v-model="pixelSizeJitter" :min="0" :max="2" :step="0.05" />
|
||||||
|
<PreviewSlider title="Speed" v-model="speed" :min="0" :max="3" :step="0.05" />
|
||||||
|
<PreviewSlider title="Edge Fade" v-model="edgeFade" :min="0" :max="0.5" :step="0.01" />
|
||||||
|
<PreviewSwitch title="Ripples" v-model="enableRipples" />
|
||||||
|
<PreviewSwitch title="Liquid" v-model="liquid" />
|
||||||
|
</Customize>
|
||||||
|
|
||||||
|
<PropTable :data="propData" />
|
||||||
|
<Dependencies :dependency-list="['three', 'postprocessing']" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #code>
|
||||||
|
<CodeExample :code-object="pixelBlast" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cli>
|
||||||
|
<CliInstallation :command="pixelBlast.cli" />
|
||||||
|
</template>
|
||||||
|
</TabbedLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { pixelBlast } from '@/constants/code/Backgrounds/pixelBlastCode';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||||
|
import CodeExample from '../../components/code/CodeExample.vue';
|
||||||
|
import Dependencies from '../../components/code/Dependencies.vue';
|
||||||
|
import BackgroundContent from '../../components/common/BackgroundContent.vue';
|
||||||
|
import Customize from '../../components/common/Customize.vue';
|
||||||
|
import PreviewColor from '../../components/common/PreviewColor.vue';
|
||||||
|
import PreviewSelect from '../../components/common/PreviewSelect.vue';
|
||||||
|
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||||
|
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||||
|
import PropTable from '../../components/common/PropTable.vue';
|
||||||
|
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||||
|
import PixelBlast, { type PixelBlastVariant } from '../../content/Backgrounds/PixelBlast/PixelBlast.vue';
|
||||||
|
|
||||||
|
const variantOptions = [
|
||||||
|
{ label: 'Square', value: 'square' },
|
||||||
|
{ label: 'Circle', value: 'circle' },
|
||||||
|
{ label: 'Triangle', value: 'triangle' },
|
||||||
|
{ label: 'Diamond', value: 'diamond' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const variant = ref<PixelBlastVariant>('square');
|
||||||
|
const pixelSize = ref(4);
|
||||||
|
const patternScale = ref(2);
|
||||||
|
const patternDensity = ref(1);
|
||||||
|
const pixelSizeJitter = ref(0);
|
||||||
|
const enableRipples = ref(true);
|
||||||
|
const liquid = ref(false);
|
||||||
|
const speed = ref(0.5);
|
||||||
|
const edgeFade = ref(0.25);
|
||||||
|
const color = ref('#A7EF9E');
|
||||||
|
|
||||||
|
const propData = [
|
||||||
|
{
|
||||||
|
name: 'variant',
|
||||||
|
type: "'square'|'circle'|'triangle'|'diamond'",
|
||||||
|
default: "'square'",
|
||||||
|
description: 'Pixel shape variant.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pixelSize',
|
||||||
|
type: 'number',
|
||||||
|
default: '4',
|
||||||
|
description: 'Base pixel size (auto scaled for DPI).'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'color',
|
||||||
|
type: 'string',
|
||||||
|
default: "'#A7EF9E'",
|
||||||
|
description: 'Pixel color.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'patternScale',
|
||||||
|
type: 'number',
|
||||||
|
default: '2',
|
||||||
|
description: 'Noise/pattern scale.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'patternDensity',
|
||||||
|
type: 'number',
|
||||||
|
default: '1',
|
||||||
|
description: 'Pattern density adjustment.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pixelSizeJitter',
|
||||||
|
type: 'number',
|
||||||
|
default: '0',
|
||||||
|
description: 'Random jitter applied to coverage.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableRipples',
|
||||||
|
type: 'boolean',
|
||||||
|
default: 'true',
|
||||||
|
description: 'Enable click ripple waves.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rippleSpeed',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.3',
|
||||||
|
description: 'Ripple propagation speed.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rippleThickness',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.1',
|
||||||
|
description: 'Ripple ring thickness.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rippleIntensityScale',
|
||||||
|
type: 'number',
|
||||||
|
default: '1',
|
||||||
|
description: 'Ripple intensity multiplier.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'liquid',
|
||||||
|
type: 'boolean',
|
||||||
|
default: 'false',
|
||||||
|
description: 'Enable liquid distortion effect.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'liquidStrength',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.1',
|
||||||
|
description: 'Liquid distortion strength.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'liquidRadius',
|
||||||
|
type: 'number',
|
||||||
|
default: '1',
|
||||||
|
description: 'Liquid touch brush radius scale.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'liquidWobbleSpeed',
|
||||||
|
type: 'number',
|
||||||
|
default: '4.5',
|
||||||
|
description: 'Liquid wobble frequency.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'speed',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.5',
|
||||||
|
description: 'Animation time scale.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'edgeFade',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.25',
|
||||||
|
description: 'Edge fade distance (0-1).'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'noiseAmount',
|
||||||
|
type: 'number',
|
||||||
|
default: '0',
|
||||||
|
description: 'Post noise amount.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transparent',
|
||||||
|
type: 'boolean',
|
||||||
|
default: 'true',
|
||||||
|
description: 'Transparent background.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.demo-container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user