Skip to content

Commit 4ab9b55

Browse files
committed
Added spline length control!!
1 parent 787b626 commit 4ab9b55

4 files changed

Lines changed: 199 additions & 10 deletions

File tree

classes.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,10 @@ class Bézier {
144144
}
145145
this.inverseMap.push(1);
146146
}
147+
}
148+
149+
150+
151+
function toggleMenu() {
152+
document.getElementById("canvas-controls").style.width = (document.getElementById("stack-menu").style.width == "0") ? "350px" : "0";
147153
}

index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ <h1 id="htitle">DNA-cryption</h1>
2727
<canvas id="kansas"></canvas>
2828

2929
<div id="canvas-controls">
30+
<!--
31+
<label for="menu-close" id="close-button" class="btn">
32+
<i class="fa-solid fa-x"></i>
33+
</label>
34+
<button id="menu-close" style="display: none;" onclick="toggleMenu()"></button>
35+
-->
36+
37+
<span>
38+
<label for="spline-size">Spline Length</label>
39+
<input type="number" id="spline-size" max="3" min="1">
40+
</span>
41+
42+
<hr>
43+
3044
<label>
3145
<input type="checkbox" id="toggleBézier" checked>
3246
Show Bézier
@@ -35,6 +49,10 @@ <h1 id="htitle">DNA-cryption</h1>
3549
<input type="checkbox" id="toggleDNA" checked>
3650
Show DNA
3751
</label>
52+
53+
<hr>
54+
55+
<input type="text" id="textin" class="text-input" placeholder="Text to encode...">
3856

3957
<hr>
4058

index.js

Lines changed: 132 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ canvas.height = 720;
66

77
const DNA_WIDTH = 50;
88

9+
const DNA_SIDE_WIDTH = 15;
10+
11+
let SPLINE_SIZE = 2;
12+
913

1014
var segments = [
1115
new Bézier(
@@ -22,7 +26,7 @@ var segments = [
2226
)
2327
];
2428

25-
var code = "ACTGATAGCTAATCGTACCA";
29+
var code = 'ACTAGCTGTACTGATC';
2630

2731
var showBézier = true;
2832
var showDNA = true;
@@ -39,8 +43,16 @@ document.getElementById("toggleDNA").addEventListener("change", (e) => {
3943
document.getElementById("toggleBézier").checked = true;
4044
document.getElementById("toggleDNA").checked = true;
4145

46+
document.getElementById("textin").value = '';
47+
document.getElementById("spline-size").value = '2';
48+
4249
document.getElementById("datain").addEventListener("change", (e) => {
43-
encodeToDNA();
50+
encodeFileToDNA();
51+
wholeDraw();
52+
});
53+
54+
document.getElementById("textin").addEventListener("change", (e) => {
55+
encodeTextToDNA(document.getElementById("textin").value);
4456
wholeDraw();
4557
});
4658

@@ -54,7 +66,97 @@ document.getElementById("export").addEventListener("click", (e) => {
5466
});
5567

5668

57-
function encodeToDNA() {
69+
document.getElementById("spline-size").addEventListener("change", (e) => {
70+
switch (document.getElementById("spline-size").value) {
71+
case '1':
72+
segments = [
73+
new Bézier(
74+
new DraggablePoint(new Victor(200, 100)),
75+
new DraggablePoint(new Victor(400, 200)),
76+
new DraggablePoint(new Victor(700, 100)),
77+
new DraggablePoint(new Victor(700, 250))
78+
)
79+
];
80+
encodeTextToDNA("hello");
81+
break;
82+
case '2':
83+
segments = [
84+
new Bézier(
85+
new DraggablePoint(new Victor(200, 100)),
86+
new DraggablePoint(new Victor(400, 200)),
87+
new DraggablePoint(new Victor(700, 100)),
88+
new DraggablePoint(new Victor(700, 250))
89+
),
90+
new Bézier(
91+
new DraggablePoint(new Victor(700, 250)),
92+
new DraggablePoint(new Victor(700, 400)),
93+
new DraggablePoint(new Victor(300, 400)),
94+
new DraggablePoint(new Victor(100, 550))
95+
)
96+
];
97+
encodeTextToDNA("helloworld");
98+
break;
99+
case '3':
100+
segments = [
101+
new Bézier(
102+
new DraggablePoint(new Victor(450, 50)),
103+
new DraggablePoint(new Victor(500, 300)),
104+
new DraggablePoint(new Victor(750, 150)),
105+
new DraggablePoint(new Victor(800, 300))
106+
),
107+
new Bézier(
108+
new DraggablePoint(new Victor(800, 300)),
109+
new DraggablePoint(new Victor(850, 450)),
110+
new DraggablePoint(new Victor(625, 575)),
111+
new DraggablePoint(new Victor(450, 525))
112+
),
113+
new Bézier(
114+
new DraggablePoint(new Victor(450, 525)),
115+
new DraggablePoint(new Victor(256, 475)),
116+
new DraggablePoint(new Victor(425, 200)),
117+
new DraggablePoint(new Victor(75, 200))
118+
)
119+
];
120+
encodeTextToDNA("Hello, World!!!");
121+
break;
122+
default:
123+
break;
124+
}
125+
126+
document.getElementById("textin").value = '';
127+
SPLINE_SIZE = +document.getElementById("spline-size").value;
128+
});
129+
130+
// Debug Position Telling
131+
/*
132+
document.addEventListener("keydown", (e) => {
133+
if (e.key == 'p') {
134+
for (let i = 0; i < segments.length; i++) {
135+
console.log("Segment " + (i+1) + ":");
136+
for (pnt of segments[i].pnts) console.log(pnt.pos.toString());
137+
}
138+
}
139+
});
140+
*/
141+
142+
143+
function encodeTextToDNA(text) {
144+
let dataString = '';
145+
for (let i = 0; i < text.length; i++) {
146+
dataString += text.charCodeAt(i).toString(4).padStart(4, '0');
147+
}
148+
console.log(dataString);
149+
150+
let dnaString = '';
151+
for (let i = 0; i < dataString.length; i++) {
152+
dnaString += acidFromDigit(dataString[i]);
153+
}
154+
console.log(dnaString);
155+
156+
code = dnaString;
157+
}
158+
159+
function encodeFileToDNA() {
58160
const filesIn = document.getElementById("datain");
59161
const file = filesIn.files[0];
60162

@@ -70,16 +172,14 @@ function encodeToDNA() {
70172

71173
let dataString = '';
72174
for (let i = 0; i < uint8array.length; i++) {
73-
dataString += uint8array[i].toString(4);
175+
dataString += uint8array[i].toString(4).padStart(4, '0');
74176
}
75-
console.log("base4 string:", dataString);
76177

77178
let dnaString = '';
78179
for (let i = 0; i < dataString.length; i++) {
79180
dnaString += acidFromDigit(dataString[i]);
80181
}
81182

82-
console.log("DNA string:", dnaString);
83183
code = dnaString;
84184
};
85185

@@ -131,7 +231,8 @@ function acidFromDigit(digit) {
131231

132232
function drawDNALines(pnts) {
133233
ctx.strokeStyle = "blue";
134-
ctx.lineWidth = 10;
234+
ctx.fillStyle = "blue";
235+
ctx.lineWidth = DNA_SIDE_WIDTH;
135236

136237
ctx.beginPath();
137238
const pinit = BézierPoint(pnts, 0);
@@ -152,18 +253,39 @@ function drawDNALines(pnts) {
152253
ctx.lineTo(point.x - tant.y, point.y + tant.x);
153254
}
154255
ctx.stroke();
256+
257+
const pstart = BézierPoint(pnts, -0.02);
258+
const tstart = BézierTangent(pnts, -0.02).norm().multiply(new Victor(DNA_WIDTH, DNA_WIDTH));
259+
260+
const pend = BézierPoint(pnts, 1.03);
261+
const tend = BézierTangent(pnts, 1.03).norm().multiply(new Victor(DNA_WIDTH, DNA_WIDTH));
262+
263+
ctx.beginPath();
264+
ctx.arc(pstart.x + tstart.y, pstart.y - tstart.x, DNA_SIDE_WIDTH / 2, 0, 360);
265+
ctx.fill();
266+
ctx.beginPath();
267+
ctx.arc(pstart.x - tstart.y, pstart.y + tstart.x, DNA_SIDE_WIDTH / 2, 0, 360);
268+
ctx.fill();
269+
ctx.beginPath();
270+
ctx.arc(pend.x + tend.y, pend.y - tend.x, DNA_SIDE_WIDTH / 2, 0, 360);
271+
ctx.fill();
272+
ctx.beginPath();
273+
ctx.arc(pend.x - tend.y, pend.y + tend.x, DNA_SIDE_WIDTH / 2, 0, 360);
274+
ctx.fill();
155275
}
156276

157277
function drawATCG() {
158278
ctx.lineWidth = 10;
159279

160-
const strandPer = code.length / segments.length;
280+
const strandPer = Math.ceil(code.length / SPLINE_SIZE);
161281
for (let s = 0; s < segments.length; s++) {
162282
const bzr = segments[s];
163283
for (let i = 0; i <= strandPer; i++) {
164-
if (s > 0 && i == 0) continue;
284+
if (s > segments.length - 1 && i == 0) continue;
165285

166-
const clr = colorFromAcid(code[strandPer * s + i - s]);
286+
const acid = code[strandPer * s + i - s];
287+
const clr = colorFromAcid(acid);
288+
if (!clr) continue;
167289

168290
ctx.beginPath();
169291
const t = bzr.inverseMap[Math.floor(i * 100 / (strandPer))];

main.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,49 @@ canvas {
5757
border-radius: 10px;
5858
}
5959

60+
.text-input {
61+
background-color: #1e1e1e;
62+
color: #ffffff;
63+
border: none;
64+
border-radius: 10px;
65+
padding: 0.6em 1em;
66+
font-size: 1rem;
67+
outline: none;
68+
transition: background-color 0.3s, box-shadow 0.3s;
69+
}
70+
71+
.text-input::placeholder {
72+
color: #aaa;
73+
}
74+
75+
.text-input:focus {
76+
background-color: #2a2a2a;
77+
box-shadow: 0 0 0 2px #4A90E2;
78+
}
79+
80+
#spline-size {
81+
background-color: #1e1e1e;
82+
color: #ffffff;
83+
border: none;
84+
border-radius: 10px;
85+
padding: 0.6em 1em;
86+
outline: none;
87+
transition: background-color 0.3s, box-shadow 0.3s;
88+
}
89+
90+
#close-button {
91+
width: 25px;
92+
text-align: center;
93+
position: absolute;
94+
right: 10px;
95+
top: 10px;
96+
}
97+
98+
99+
hr {
100+
opacity: 0;
101+
}
102+
60103

61104

62105
#htitle {

0 commit comments

Comments
 (0)