feat: ✨ Added transaprency to qr generator

This commit is contained in:
Noah Lancien 2026-04-10 17:07:47 +02:00
parent 2c86d0094e
commit fc49072916
5 changed files with 90 additions and 12 deletions

1
.gitignore vendored
View file

@ -18,3 +18,4 @@ yarn-error.log
/.idea /.idea
/.vscode /.vscode
auth.json auth.json
.npmrc

22
package-lock.json generated
View file

@ -7,6 +7,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.29.0", "@babel/core": "^7.29.0",
"@babel/types": "^7.29.0", "@babel/types": "^7.29.0",
"@cyhnkckali/vue3-color-picker": "^2.1.7",
"@erbelion/vite-plugin-laravel-purgecss": "^0.2.3", "@erbelion/vite-plugin-laravel-purgecss": "^0.2.3",
"@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.1", "@fortawesome/free-brands-svg-icons": "^6.5.1",
@ -31,6 +32,7 @@
"axios": "^1.5.1", "axios": "^1.5.1",
"bootstrap": "^5.3.2", "bootstrap": "^5.3.2",
"chart.js": "^2.0.0", "chart.js": "^2.0.0",
"colorjs.io": "^0.6.1",
"cropperjs": "^1.6.1", "cropperjs": "^1.6.1",
"eslint": "^8.23.0", "eslint": "^8.23.0",
"eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-alias": "^1.1.2",
@ -799,6 +801,15 @@
"postcss-selector-parser": "^6.0.13" "postcss-selector-parser": "^6.0.13"
} }
}, },
"node_modules/@cyhnkckali/vue3-color-picker": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/@cyhnkckali/vue3-color-picker/-/vue3-color-picker-2.1.7.tgz",
"integrity": "sha512-Vw4IM4aKHbJkNwuLsyVdfLm727uIkazpbFjHFOwsj03J2uZqy4TKwmX+83zHIXp2+ELCXFNULXgbETiFUzS+Eg==",
"dev": true,
"peerDependencies": {
"vue": "^3.3.8"
}
},
"node_modules/@erbelion/vite-plugin-laravel-purgecss": { "node_modules/@erbelion/vite-plugin-laravel-purgecss": {
"version": "0.2.6", "version": "0.2.6",
"resolved": "https://registry.npmjs.org/@erbelion/vite-plugin-laravel-purgecss/-/vite-plugin-laravel-purgecss-0.2.6.tgz", "resolved": "https://registry.npmjs.org/@erbelion/vite-plugin-laravel-purgecss/-/vite-plugin-laravel-purgecss-0.2.6.tgz",
@ -3760,6 +3771,17 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/colorjs.io": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz",
"integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==",
"dev": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/color"
}
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",

View file

@ -16,6 +16,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.29.0", "@babel/core": "^7.29.0",
"@babel/types": "^7.29.0", "@babel/types": "^7.29.0",
"@cyhnkckali/vue3-color-picker": "^2.1.7",
"@erbelion/vite-plugin-laravel-purgecss": "^0.2.3", "@erbelion/vite-plugin-laravel-purgecss": "^0.2.3",
"@fortawesome/fontawesome-svg-core": "^6.5.1", "@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.1", "@fortawesome/free-brands-svg-icons": "^6.5.1",
@ -40,6 +41,7 @@
"axios": "^1.5.1", "axios": "^1.5.1",
"bootstrap": "^5.3.2", "bootstrap": "^5.3.2",
"chart.js": "^2.0.0", "chart.js": "^2.0.0",
"colorjs.io": "^0.6.1",
"cropperjs": "^1.6.1", "cropperjs": "^1.6.1",
"eslint": "^8.23.0", "eslint": "^8.23.0",
"eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-alias": "^1.1.2",

View file

@ -97,16 +97,36 @@
id="margin" id="margin"
> >
<label <div class="row">
for="backgroundOptions-color" <div class="col-12 my-3">
class="form-label" <div class="form-check">
>Couleur du fond</label> <label
<input for="backgroundOptions-transparency"
v-model="options.backgroundOptions.color" class="form-check-label"
placeholder="Add data" >Transparent ?</label>
class="form-control" <input
id="backgroundOptions-color" v-model="isTransparent"
> class="form-check-input"
type="checkbox"
id="backgroundOptions-transparency"
>
</div>
</div>
<div class="col-12 d-flex justify-content-center">
<Vue3ColorPicker
v-show="!isTransparent"
v-model="pickerColor"
mode="solid"
type="HEX"
input-type="RGB"
:show-input-menu="false"
:show-picker-mode="false"
:show-color-list="false"
:show-alpha="false"
@on-change="changeColor"
/>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -368,6 +388,8 @@ import type {
import trans from "../../modules/trans"; import trans from "../../modules/trans";
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import ImageInputComponent from "../../bo/components/ImageInputComponent.vue"; import ImageInputComponent from "../../bo/components/ImageInputComponent.vue";
import {Vue3ColorPicker} from "@cyhnkckali/vue3-color-picker";
import "@cyhnkckali/vue3-color-picker/dist/style.css";
export default defineComponent({ export default defineComponent({
name: "QrCodeComponent", name: "QrCodeComponent",
@ -396,9 +418,11 @@ export default defineComponent({
this.imageLoaded = true; this.imageLoaded = true;
this.qrCode = new QRCodeStyling(this.options); this.qrCode = new QRCodeStyling(this.options);
this.qrCode.append(this.$refs.div as HTMLElement); this.qrCode.append(this.$refs.div as HTMLElement);
this.isTransparent = this.options.backgroundOptions.color === "transparent";
}, },
components: { components: {
ImageInputComponent ImageInputComponent,
Vue3ColorPicker
}, },
methods: { methods: {
download() { download() {
@ -412,6 +436,18 @@ export default defineComponent({
this.qrCode.update(this.options); this.qrCode.update(this.options);
} }
}, },
changeColor(color: string) {
if (!this.isTransparent) {
this.options.backgroundOptions.color = color;
}
},
toggleTransparency() {
if (this.isTransparent) {
this.options.backgroundOptions.color = "transparent";
} else {
this.options.backgroundOptions.color = this.pickerColor;
}
}
}, },
props: { props: {
id: { id: {
@ -465,6 +501,8 @@ export default defineComponent({
}, },
extension: FileExtension, extension: FileExtension,
qrCode: QRCodeStyling, qrCode: QRCodeStyling,
isTransparent: boolean,
pickerColor: string,
} { } {
return { return {
baseUrl: "", baseUrl: "",
@ -507,7 +545,9 @@ export default defineComponent({
} }
}, },
extension: "png", extension: "png",
qrCode: new QRCodeStyling() qrCode: new QRCodeStyling(),
isTransparent: false,
pickerColor: "#ffffff",
}; };
}, },
watch: { watch: {
@ -554,6 +594,13 @@ export default defineComponent({
}); });
this.qrCode.update(this.options); this.qrCode.update(this.options);
}, },
isTransparent(newVal) {
if (newVal) {
this.options.backgroundOptions.color = "transparent";
} else {
this.options.backgroundOptions.color = this.pickerColor;
}
},
"options.data"() { "options.data"() {
this.qrCode.update(this.options); this.qrCode.update(this.options);
}, },
@ -622,4 +669,8 @@ export default defineComponent({
} }
} }
#qr-code {
// Apply a color to keep the dots visible when the background is transparent.
background-color: #aaa;
}
</style> </style>

View file

@ -6,5 +6,7 @@ const sassSafelist: UserDefinedSafelist = [
/^bs-popover/, /^popover/, /^modal-/, /^bg-/, /^accordion-/, /^bs-popover/, /^popover/, /^modal-/, /^bg-/, /^accordion-/,
// Vue // Vue
/-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/, /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/,
// Color Picker
/^ck-cp-/, /^cp-/, /^picker-hue-/, /^colour-/
]; ];
export { sassSafelist }; export { sassSafelist };