@@ -6,6 +6,10 @@ canvas.height = 720;
66
77const DNA_WIDTH = 50 ;
88
9+ const DNA_SIDE_WIDTH = 15 ;
10+
11+ let SPLINE_SIZE = 2 ;
12+
913
1014var segments = [
1115 new Bézier (
@@ -22,7 +26,7 @@ var segments = [
2226 )
2327] ;
2428
25- var code = "ACTGATAGCTAATCGTACCA" ;
29+ var code = 'ACTAGCTGTACTGATC' ;
2630
2731var showBézier = true ;
2832var showDNA = true ;
@@ -39,8 +43,16 @@ document.getElementById("toggleDNA").addEventListener("change", (e) => {
3943document . getElementById ( "toggleBézier" ) . checked = true ;
4044document . getElementById ( "toggleDNA" ) . checked = true ;
4145
46+ document . getElementById ( "textin" ) . value = '' ;
47+ document . getElementById ( "spline-size" ) . value = '2' ;
48+
4249document . 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
132232function 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
157277function 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 ) ) ] ;
0 commit comments