feat(www): Init

This commit is contained in:
Tom Hubrecht 2024-01-24 20:17:20 +01:00
commit e6084bbbdc
9 changed files with 2737 additions and 0 deletions

4
README.md Normal file
View file

@ -0,0 +1,4 @@
QR
==
A simple application for creating qr codes.

230
www/css/qr-dgnum.css Normal file
View file

@ -0,0 +1,230 @@
body {
align-items: stretch;
background-color: #f5f5f5;
color: #4a4a4a;
display: flex;
flex-direction: column;
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1em;
font-weight: 400;
justify-content: space-between;
line-height: 1.5;
min-height: 100vh;
margin: 0 auto;
position: relative;
text-align: center;
width: auto;
}
figure {
display: block;
height: 256px;
margin-left: 122px;
margin-right: 122px;
max-width: 256px;
position: relative;
margin-bottom: .75rem;
}
img {
display: block;
height: auto;
max-width: 100%;
min-height: 256px;
min-width: 256px;
position: relative;
}
a {
color: #485fc7;
cursor: pointer;
text-decoration: none;
}
footer {
background-color: #fafafa;
display: block;
padding: 3rem 1.5rem 6rem;
}
section {
margin: auto;
width: 500px;
padding-top: 2.5rem;
margin-bottom: 2.5rem;
display: block;
}
h1 {
color: #363636;
font-size: 2rem;
font-weight: 600;
line-height: 1.125;
margin-bottom: 2.5rem;
margin-top: 0;
}
form {
text-align: left;
}
label {
color: #363636;
display: block;
font-size: 1rem;
font-weight: 700;
margin-bottom: .5em;
}
input::placeholder {
color: rgba(54, 54, 54, .3);
}
input:not(:last-child) {
margin-bottom: .75rem;
}
input:hover,
select:hover {
border-color: #b5b5b5;
}
input:active,
input:focus,
select:active,
select:focus {
border-color: #485fc7;
box-shadow: 0 0 0 .125em rgba(72, 95, 199, .25);
outline: 0;
}
input,
select {
-moz-appearance: none;
-webkit-appearance: none;
align-items: center;
appearance: none;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dbdbdb;
box-shadow: inset 0 .0625em .125em rgba(10, 10, 10, .05);
box-shadow: none;
box-sizing: border-box;
color: #363636;
display: inline-flex;
font-size: 1rem;
font-size: 1rem;
height: 2.5em;
justify-content: flex-start;
line-height: 1.5;
max-width: 100%;
padding-bottom: calc(.5em - 1px);
padding-left: calc(.75em - 1px);
padding-right: calc(.75em - 1px);
padding-top: calc(.5em - 1px);
position: relative;
vertical-align: top;
width: 100%;
}
select {
cursor: pointer;
display: block;
font-size: 1em;
max-width: 100%;
outline: 0;
padding-right: 2.5em;
width: 100%;
}
.select {
display: inline-block;
width: 100%;
position: relative;
vertical-align: top;
}
.select::after {
border: 3px solid;
border-right: 0;
border-top: 0;
border-color: #485fc7;
border-radius: 2px;
right: 1.125em;
z-index: 4;
content: " ";
display: block;
height: .625em;
margin-top: -.4375em;
pointer-events: none;
position: absolute;
top: 50%;
transform: rotate(-45deg);
transform-origin: center;
width: .625em;
}
.help {
display: block;
font-size: .75rem;
margin-top: .25rem;
margin-bottom: .75rem;
}
button {
-moz-appearance: none;
-webkit-appearance: none;
align-items: center;
background-color: #fff;
border: 1px solid transparent;
border-color: #dbdbdb;
border-radius: 4px;
border-width: 1px;
box-shadow: none;
color: #363636;
cursor: pointer;
display: inline-flex;
font-size: 1rem;
height: 2.5em;
justify-content: center;
line-height: 1.5;
margin-top: 0;
margin-bottom: .5rem;
margin-left: .5rem;
margin-right: .5rem;
padding-bottom: calc(.5em - 1px);
padding-left: 1em;
padding-right: 1em;
padding-top: calc(.5em - 1px);
position: relative;
text-align: center;
user-select: none;
white-space: nowrap;
}
button:hover {
border-color: #b5b5b5;
color: #363636;
}
button:active {
border-color: #4a4a4a;
color: #363636;
}
button:focus {
border-color: #485fc7;
color: #363636;
}
button:focus:not(:active) {
box-shadow: 0 0 0 .125em rgba(72,95,199,.25);
}
.buttons {
align-items: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 1rem;
}

1
www/css/qr-dgnum.min.css vendored Normal file
View file

@ -0,0 +1 @@
figure,footer,img,label,section{display:block}img,input,select{max-width:100%}.select,input,select{vertical-align:top;width:100%}a,button,select{cursor:pointer}body,button{text-align:center}body{align-items:stretch;background-color:#f5f5f5;color:#4a4a4a;display:flex;flex-direction:column;font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:1em;font-weight:400;justify-content:space-between;line-height:1.5;min-height:100vh;margin:0 auto;position:relative;width:auto}button,input,select{align-items:center;background-color:#fff;display:inline-flex;height:2.5em;line-height:1.5;padding-bottom:calc(.5em - 1px);padding-top:calc(.5em - 1px);position:relative}.help,figure,input:not(:last-child){margin-bottom:.75rem}figure{height:256px;margin-left:122px;margin-right:122px;max-width:256px;position:relative}img{height:auto;min-height:256px;min-width:256px;position:relative}a{color:#485fc7;text-decoration:none}footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}section{margin:auto auto 2.5rem;width:500px;padding-top:2.5rem}h1{color:#363636;font-size:2rem;font-weight:600;line-height:1.125;margin-bottom:2.5rem;margin-top:0}input,label,select{font-size:1rem;color:#363636}form{text-align:left}label{font-weight:700;margin-bottom:.5em}input::placeholder{color:rgba(54,54,54,.3)}input:hover,select:hover{border-color:#b5b5b5}input:active,input:focus,select:active,select:focus{border-color:#485fc7;box-shadow:0 0 0 .125em rgba(72,95,199,.25);outline:0}input,select{-moz-appearance:none;-webkit-appearance:none;appearance:none;border-radius:4px;border:1px solid #dbdbdb;box-shadow:inset 0 .0625em .125em rgba(10,10,10,.05);box-shadow:none;box-sizing:border-box;justify-content:flex-start;padding-left:calc(.75em - 1px);padding-right:calc(.75em - 1px)}select{display:block;font-size:1em;outline:0;padding-right:2.5em;width:100%}.select{display:inline-block;position:relative}.select::after{border:3px solid #485fc7;border-right:0;border-top:0;border-radius:2px;right:1.125em;z-index:4;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:.625em}.help{display:block;font-size:.75rem;margin-top:.25rem}button{-moz-appearance:none;-webkit-appearance:none;border:1px solid #dbdbdb;border-radius:4px;box-shadow:none;color:#363636;font-size:1rem;justify-content:center;margin:0 .5rem .5rem;padding-left:1em;padding-right:1em;user-select:none;white-space:nowrap}button:hover{border-color:#b5b5b5;color:#363636}button:active{border-color:#4a4a4a;color:#363636}button:focus{border-color:#485fc7;color:#363636}button:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:center;margin-bottom:1rem}

BIN
www/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

69
www/index.html Normal file
View file

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script defer src="/js/qrious.min.js"></script>
<script defer src="/js/qr-dgnum.min.js"></script>
<script defer data-domain="qr.dgnum.eu" src="https://analytics.dgnum.eu/js/script.js"></script>
<link rel="stylesheet" href="/css/qr-dgnum.min.css">
</link>
<title>QR - DGNum</title>
</head>
<body>
<section>
<h1>QR Code Generator</h1>
<figure>
<img>
</figure>
<div class="buttons">
<button class="button" name="png">Dowload as PNG</button>
<button class="button" name="jpeg">Download as JPEG</button>
</div>
<form autocomplete="off">
<label>Value</label>
<input type="text" name="value" spellcheck="false" placeholder="https://qr.dgnum.eu">
<label>Size</label>
<input class="input" type="number" name="size" min="100" max="1000" placeholder="100" value="250">
<label>Padding</label>
<input class="input" type="number" name="padding" min="0" placeholder="Auto">
<label>Error correction level</label>
<div class="select">
<select name="level">
<option value="L">Low 7%</option>
<option value="M">Medium 15%</option>
<option value="Q">Quartile 25%</option>
<option value="H">High 30%</option>
</select>
</div>
<p class="help">The amount of data that can be recovered</p>
<label>Background color</label>
<input class="input" type="color" name="background" value="#ffffff">
<label>Background opacity</label>
<input class="input" type="number" name="backgroundAlpha" placeholder="1" min="0" max="1" step="0.1" value="1">
<label>Foreground color</label>
<input class="input" type="color" name="foreground" value="#000000">
<label>Foreground opacity</label>
<input class="input" type="number" name="foregroundAlpha" placeholder="1" min="0" max="1" step="0.1" value="1">
</form>
</section>
<footer>Propulsé par la <a href="https://dgnum.eu">DGNum</a>.</footer>
</body>
</html>

32
www/js/qr-dgnum.js Normal file
View file

@ -0,0 +1,32 @@
const $ = s => document.querySelector(s);
const n = s => $(`[name=${s}]`);
const qr = new QRious({element: $('img'), size: 250});
const c = 'change';
const w = (i, e, f) => i.addEventListener(e, f);
['png', 'jpeg'].forEach(x => {
const e = n(x);
w(e, 'click', () => {
const a = document.createElement('a');
a.href = qr.toDataURL(`image/${x}`);
a.download = `qr-code.${x}`;
a.click();
setTimeout(() => a.remove(), 50);
});
});
const a = (e, b) => { const i = n(b); w(i, e, () => { qr[b] = i.value || null; }); };
['background', 'backgroundAlpha', 'foreground', 'foregroundAlpha', 'level'].forEach(e => a(c, e));
a('input', 'value')
const p = n('padding');
w(p, c, () => { if (p.validity.valid) { qr.padding = p.value !== '' ? p.value : null; } });
const s = n('size');
w(s, c, () => { if (s.validity.valid) { qr.size = s.value || null; } });

1
www/js/qr-dgnum.min.js vendored Normal file
View file

@ -0,0 +1 @@
const $=e=>document.querySelector(e),n=e=>$(`[name=${e}]`),qr=new QRious({element:$("img"),size:250}),c="change",w=(e,l,r)=>e.addEventListener(l,r);["png","jpeg"].forEach(e=>{let l=n(e);w(l,"click",()=>{let l=document.createElement("a");l.href=qr.toDataURL(`image/${e}`),l.download=`qr-code.${e}`,l.click(),setTimeout(()=>l.remove(),50)})});const a=(e,l)=>{let r=n(l);w(r,e,()=>{qr[l]=r.value||null})};["background","backgroundAlpha","foreground","foregroundAlpha","level"].forEach(e=>a(c,e)),a("input","value");const p=n("padding");w(p,c,()=>{p.validity.valid&&(qr.padding=""!==p.value?p.value:null)});const s=n("size");w(s,c,()=>{s.validity.valid&&(qr.size=s.value||null)});

2360
www/js/qrious.js Normal file

File diff suppressed because it is too large Load diff

40
www/js/qrious.min.js vendored Normal file

File diff suppressed because one or more lines are too long