-
Notifications
You must be signed in to change notification settings - Fork 0
/
qr.html
107 lines (97 loc) · 3.53 KB
/
qr.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<style>
table { border-collapse: collapse; margin: 1em; }
td { border: 1px solid lightgray; width: 10px; height: 10px; display: inline-block; }
.x { background: black; }
.err { border-color: red; }
</style>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://jeromeetienne.github.io/jquery-qrcode/src/qrcode.js"></script>
<script src="https://cozmo.github.io/jsQR/jsQR.js"></script>
<input value="https://habr.com/ru/post/518476/"/>
<select><option>0</option><option>1</option><option>2</option><option>3</option><option>4</option><option selected>5</option><option>6</option></select>
<table></table>
<div></div>
<script>
var size;
$(document).on('dragstart', function(e){e.preventDefault();})
.on("mouseenter", "td", function(e){if(e.buttons) handler.call(this);})
.on("mousedown", "td", handler);
function handler(){ $(this).toggleClass('x'); update(); }
var timeouts = [];
function update() {
timeouts.forEach(clearTimeout);
timeouts = [];
var big = size + 2;
if (big < 33) big = 33;
var binaryData = new Uint8ClampedArray(4*big*big);
binaryData.fill(255);
for(let y=0; y<size; y++)
for(let x=0; x<size; x++) {
const pos = ((y+1)*big + x+1) * 4;
const cell = $("table").children().eq(y).children().eq(x).hasClass("x");
binaryData[pos] = binaryData[pos+1] = binaryData[pos+2] = (1-cell)*255;
}
const result = jsQR(binaryData, big, big);
if (result) {
$("div").text(result.data);
timeouts = $("td").map(function(){
const $this = $(this);
const x = $this.prevAll().length;
const y = $this.parent().prevAll().length;
const pos = ((y+1)*big + x+1) * 4;
let modified = new Uint8ClampedArray(binaryData)
modified[pos] = modified[pos+1] = modified[pos+2] = 255 - modified[pos];
return setTimeout(function() {
if (jsQR(modified, big, big)) {
$this.removeClass("err");
} else {
$this.addClass("err");
}
});
}).get();
} else {
$("div").text("error");
$("td").removeClass("err");
}
}
function makeCode() {
const text = $("input").val();
if (text) {
var qrcode = new QRCode(0, QRErrorCorrectLevel.H);
qrcode.addData(text);
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, qrcode.errorCorrectLevel);
var buffer = new QRBitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < qrcode.dataList.length; i++) {
var data = qrcode.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) );
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
qrcode.typeNumber = typeNumber;
qrcode.makeImpl(false, +$("select").val());
size = qrcode.getModuleCount();
$("table").html('<table></table>');
for(let y=0; y<size; y++) {
let row = "<tr>";
for(let x=0; x<size; x++)
row += "<td" + (qrcode.isDark(y, x) ? ' class="x"' : "") + "></td>";
$("table").append(row);
}
update();
}
}
makeCode();
$("input").on("blur", makeCode)
.keydown(function(e) {
if (e.keyCode == 13) makeCode();
});
$("select").change(makeCode);
</script>