@@ -27,6 +27,7 @@ const Controls = {
27
27
COLOR : "COLOR" ,
28
28
OBJECT : "OBJECT" ,
29
29
PATHTIPSYMBOL : "PATHTIPSYMBOL" ,
30
+ TEXT : "TEXT" ,
30
31
}
31
32
32
33
const LAYER_TOOL_COMPATIBILITY = {
@@ -42,7 +43,7 @@ const LAYER_CONTROL_COMPATIBILITY = {
42
43
[ Layers . OBJECT ] : [ Controls . OBJECT ] ,
43
44
[ Layers . PATH ] : [ Controls . COLOR , Controls . PATHTIPSYMBOL ] ,
44
45
[ Layers . BOUNDARY ] : [ Controls . COLOR ] ,
45
- [ Layers . TEXT ] : [ Controls . COLOR ] ,
46
+ [ Layers . TEXT ] : [ Controls . COLOR , Controls . TEXT ] ,
46
47
} ;
47
48
48
49
/****************
@@ -97,6 +98,9 @@ const GLOBAL_STATE = {
97
98
TEXT : {
98
99
primaryColor : "#b8895f" ,
99
100
secondaryColor : "#7eaaad" ,
101
+ bold : false ,
102
+ italics : false ,
103
+ underline : false ,
100
104
}
101
105
} ,
102
106
}
@@ -113,9 +117,17 @@ const OBJECT_BUTTONS = document.querySelectorAll(".object-btn");
113
117
const PATH_TIP_SYMBOL_BUTTONS = document . querySelectorAll ( ".path-tip-symbol-btn" ) ;
114
118
const CHOSEN_PRIMARY_COLOR_DIV = document . getElementById ( "chosenPrimaryColor" ) ;
115
119
const CHOSEN_SECONDARY_COLOR_DIV = document . getElementById ( "chosenSecondaryColor" ) ;
120
+ const TEXT_INPUT_DIV = document . getElementById ( "textInput" ) ;
121
+ const TEXT_FONT_SIZE_DIV = document . getElementById ( "textFontSize" ) ;
122
+ const TEXT_BOLD_DIV = document . getElementById ( "textBold" ) ;
123
+ const TEXT_ITALICS_DIV = document . getElementById ( "textItalics" ) ;
124
+ const TEXT_UNDERLINE_DIV = document . getElementById ( "textUnderline" ) ;
116
125
117
126
// keyboard shortcuts
118
127
document . addEventListener ( "keydown" , e => {
128
+ if ( document . activeElement . tagName == "INPUT" ) {
129
+ return ;
130
+ }
119
131
switch ( e . code ) {
120
132
case "Digit1" :
121
133
switchToLayer ( Layers . BASE ) ;
@@ -224,6 +236,22 @@ PATH_TIP_SYMBOL_BUTTONS.forEach(btn => {
224
236
} ) ;
225
237
} ) ;
226
238
239
+ TEXT_BOLD_DIV . addEventListener ( "click" , ( e ) => {
240
+ TEXT_BOLD_DIV . classList . toggle ( "selected" ) ;
241
+ GLOBAL_STATE . layers . TEXT . bold = ! GLOBAL_STATE . layers . TEXT . bold ;
242
+ } ) ;
243
+
244
+ TEXT_ITALICS_DIV . addEventListener ( "click" , ( e ) => {
245
+ TEXT_ITALICS_DIV . classList . toggle ( "selected" ) ;
246
+ GLOBAL_STATE . layers . TEXT . italics = ! GLOBAL_STATE . layers . TEXT . italics ;
247
+ } ) ;
248
+
249
+ TEXT_UNDERLINE_DIV . addEventListener ( "click" , ( e ) => {
250
+ TEXT_UNDERLINE_DIV . classList . toggle ( "selected" ) ;
251
+ GLOBAL_STATE . layers . TEXT . underline = ! GLOBAL_STATE . layers . TEXT . underline ;
252
+ } ) ;
253
+
254
+
227
255
document . getElementById ( "rotateAxesBtn" ) . addEventListener ( "click" , ( e ) => {
228
256
GLOBAL_STATE . useVerticalAxes = ! GLOBAL_STATE . useVerticalAxes ;
229
257
svgInit ( ) ;
@@ -598,6 +626,32 @@ function drawPath(hexEntry) {
598
626
SVG . appendChild ( pathTip ) ;
599
627
}
600
628
629
+ function placeTextAtPoint ( pt ) {
630
+ const textbox = document . createElementNS ( "http://www.w3.org/2000/svg" , "text" ) ;
631
+ textbox . setAttribute ( "font-size" , TEXT_FONT_SIZE_DIV . value ) ;
632
+ if ( GLOBAL_STATE . layers . TEXT . bold ) {
633
+ textbox . setAttribute ( "stroke-width" , "0.5" ) ;
634
+ }
635
+ if ( GLOBAL_STATE . layers . TEXT . italics ) {
636
+ textbox . setAttribute ( "font-style" , "italic" ) ;
637
+ }
638
+ if ( GLOBAL_STATE . layers . TEXT . underline ) {
639
+ textbox . setAttribute ( "text-decoration" , "underline" ) ;
640
+ }
641
+
642
+ textbox . setAttribute ( "x" , pt . x ) ;
643
+ textbox . setAttribute ( "y" , pt . y ) ;
644
+ textbox . setAttribute ( "fill" , GLOBAL_STATE . layers . TEXT . primaryColor ) ;
645
+ textbox . textContent = TEXT_INPUT_DIV . value ;
646
+ textbox . classList . add ( "no-pointer-events" ) ;
647
+ textbox . classList . add ( "in-image-text" ) ;
648
+ textbox . addEventListener ( "click" , e => {
649
+ if ( GLOBAL_STATE . currentTool == Tools . ERASER ) SVG . removeChild ( textbox ) ;
650
+ } ) ;
651
+ SVG . appendChild ( textbox ) ;
652
+ makeEraseable ( textbox ) ;
653
+ }
654
+
601
655
function handleHexInteraction ( c , r , mouseX , mouseY , isClick ) {
602
656
const hexEntry = GLOBAL_STATE . hexes [ `${ c } ,${ r } ` ] ;
603
657
const { hex, x, y} = hexEntry ;
@@ -636,19 +690,8 @@ function handleHexInteraction(c, r, mouseX, mouseY, isClick) {
636
690
}
637
691
} else if ( GLOBAL_STATE . currentLayer == Layers . TEXT ) {
638
692
if ( GLOBAL_STATE . currentTool == Tools . BRUSH ) {
639
- const textbox = document . createElementNS ( "http://www.w3.org/2000/svg" , "text" ) ;
640
693
const pt = new DOMPoint ( mouseX , mouseY ) . matrixTransform ( SVG . getScreenCTM ( ) . inverse ( ) ) ;
641
- textbox . setAttribute ( "x" , pt . x ) ;
642
- textbox . setAttribute ( "y" , pt . y ) ;
643
- textbox . setAttribute ( "fill" , GLOBAL_STATE . layers . TEXT . primaryColor ) ;
644
- textbox . textContent = "Here be dragons" ;
645
- textbox . classList . add ( "no-pointer-events" ) ;
646
- textbox . classList . add ( "in-image-text" ) ;
647
- textbox . addEventListener ( "click" , e => {
648
- if ( GLOBAL_STATE . currentTool == Tools . ERASER ) SVG . removeChild ( textbox ) ;
649
- } ) ;
650
- SVG . appendChild ( textbox ) ;
651
- makeEraseable ( textbox ) ;
694
+ placeTextAtPoint ( pt ) ;
652
695
}
653
696
} else if ( GLOBAL_STATE . currentLayer == Layers . PATH ) {
654
697
if ( GLOBAL_STATE . currentTool == Tools . BRUSH ) {
@@ -743,7 +786,10 @@ function svgInit() {
743
786
* EXTRA FUNCTIONALITIES *
744
787
*************************/
745
788
function saveSvg ( ) {
746
- const svgData = SVG . outerHTML ;
789
+ const clonedSvg = SVG . cloneNode ( true ) ;
790
+ const bbox = SVG . getBBox ( ) ;
791
+ clonedSvg . setAttribute ( "viewBox" , `${ bbox . x } ${ bbox . y } ${ bbox . width } ${ bbox . height } ` ) ;
792
+ const svgData = clonedSvg . outerHTML ;
747
793
const preface = '<?xml version="1.0" standalone="no"?>\r\n' ;
748
794
const svgBlob = new Blob ( [ preface , svgData ] , { type :"image/svg+xml;charset=utf-8" } ) ;
749
795
const svgUrl = URL . createObjectURL ( svgBlob ) ;
0 commit comments