<div id="settings">
  <p><button id="reset">Reset defaults</button></p>
  <table >
    <tr>
      <td class="structure">
        <table id="settingsTable" >

          <tr>
            <th colspan="2" class="header" >
              Stage
            </th>
          </tr>
          <tr>
            <td>
              <label for="stageScale">Scale</label>
            </td>
            <td>
              <select id="stageScale">
                <option>1</option>
                <option selected>2</option>
                <option>3</option>
                <option>4</option>
                <option>5</option>
                <option>6</option>
                <option>7</option>
                <option>8</option>
                <option>9</option>
                <option>15</option>
                <option>20</option>
              </select>
            </td>
          </tr>

          <tr>
            <th colspan="2" class="header" >
              Text shape size
            </th>
          </tr>
          <tr>
            <td colspan="2">
              <label for="boxWidth">Width</label>
              <input id="boxWidth" type="range" min="0" max="150" value="20">
              <span class="rangeInfo" id="boxWidthVal">200</span>
            </td>
          </tr>
          <tr>
            <td colspan="2">
              <label for="boxHeight">Height</label>
              <input id="boxHeight" type="range" min="0" max="500" value="250">
              <span class="rangeInfo" id="boxHeightVal">200</span>
            </td>
          </tr>

        
          
          <tr>
            <th colspan="2" class="header">
              Word wrap
            </th>
          </tr>

          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="wrap-word" name="wordWrap" value="word" class="wrap" checked="checked" />
              <label for="wrap-word">Word</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="wrap-char" name="wordWrap" value="char" class="wrap" />
              <label for="wrap-char">Char</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="wrap-none" name="wordWrap" value="none" class="wrap" />
              <label for="wrap-none">None</label>
            </td>
          </tr>          
          
          <tr>
            <th colspan="2" class="header">
              Horizontal Align
            </th>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="halign-left" name="halign" value="left" class="halign" checked="checked" />
              <label for="halign-left">Left</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="halign-center" name="halign" value="center" class="halign" />
              <label for="halign-center">Center</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="halign-right" name="halign" value="right" class="halign" />
              <label for="halign-right">Right</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="halign-justify" name="halign" value="justify" class="halign" />
              <label for="halign-justify">Justify</label>
            </td>
          </tr>

          <tr>
            <th colspan="2" class="header">
              Vertical Align
            </th>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="valign-top" name="valign" value="top" class="valign" checked="checked" />
              <label for="valign-top">Top</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="valign-middle" name="valign" value="middle" class="valign" />
              <label for="valign-middle">Middle</label>
            </td>
          </tr>
          <tr>
            <td colspan="2" style="text-align: left;">
              <input type="radio" id="valign-bottom" name="valign" value="bottom" class="valign" />
              <label for="valign-bottom">Bottom</label>
            </td>
          </tr>
       
          
        </table>
      </td>
      <td class="structure">
        <table id="settingsTable1" >

            <tr>       
                <th colspan="2" class="header">
                Fonts
                </th>
            </tr>

            <tr>
                <td>
                <label for="fontName">Name</label>
                </td>
                <td>
                <select id="fontName">
                    <option >Arial</option>
                    <option selected>Georgia</option>
                </select>
                </td>
            </tr>  

            <tr>
                <td>
                <label for="fontSize">Size Px</label>
                </td>
                <td>
                <select id="fontSize">
                    <option>6</option>
                    <option >10</option>
                    <option>12</option>
                    <option selected>16</option>
                    <option>32</option>
                    <option>48</option>
                </select>
                </td>
            </tr> 
                
            <tr>
                <th colspan="2" class="header">
                    Font style
                    </th>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: left;">
                    <input type="checkbox" id="bold" class="fontstyle" value="bold" />
                    <label for="bold">Bold</label>
                    </td>
                </tr> 
                <tr>
                    <td colspan="2" style="text-align: left;">
                    <input type="checkbox" id="italic" class="fontstyle" value="italic" />
                    <label for="italic">Italic</label>
                    </td>
                </tr>               

                <tr>
                    <th colspan="2" class="header">
                    Text decoration
                    </th>
                </tr>        
                <tr>
                    <td colspan="2" style="text-align: left;">
                    <input type="checkbox" id="lineThrough" class="show" value="line-through" />
                    <label for="lineThrough">Line-through</label>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: left;">
                    <input type="checkbox" id="underline" class="show" value="underline" />
                    <label for="underline">Underline</label>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" style="text-align: left;">
                    <input type="checkbox" id="ellipsis" class="show" />
                    <label for="ellipsis">Ellipsis</label>
                    </td>
                </tr>   
            

                <tr>
                    <th colspan="2" class="header">
                    Padding
                    </th>
                </tr>
                <tr>
                    <td colspan="2">
                    <input id="boxPadding" type="range" min="0" max="20" value="0">
                    <span class="rangeInfo" id="boxPaddingVal">0</span>
                    </td>
                </tr>

                <tr>
                    <th colspan="2" class="header">
                    Line height
                    </th>
                </tr>
                <tr>
                    <td colspan="2">
                    <input id="boxLineHeight" type="range" min="0" max="30" value="10">
                    <span class="rangeInfo" id="boxLineHeightVal">10</span>
                    </td>
                </tr>             
            </table>
        </td>


      <td style="vertical-align: top;  width: 100%;" class="structure"  >
        <div id="container"></div>
      </td>
    </tr>
    
             


    
  </table>

  
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/konva@8/konva.min.js"></script>
   <script src="http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script> 
body {
  overflow: scroll;
  background-color: #f0f0f0;
  font-family: Arial;  
  font-size: 10pt;
  font-weight: 'normal';
}
#settingsTable {
  width: 200px;
}
#settings {
  display: inline-block;
  height: 100%;
  padding: 2px;  
  overflow: scroll;
}
#container {
  height: 100%;
  width: 100%;
  padding: 2px;
}
th {
  text-align: left;
  padding-top: 5px;
  background-color: silver;
}
td {
  padding-left:15px;
}
td.structure {
  padding: 0;
  vertical-align: top;
}
#phrase {
  width: 120px;
  height: 200px;
}
input[type=range] {
  width: 100px;
}
.rangeInfo {
  font-size: 0.8em;
  font-family: Arial;
  position: relative;
  top: -4px;
}
.header {
  padding-left:5px;
  padding-top: 5px;
  padding-bottom: 5px;
  font-size: 12pt;
  background-color: silver;

}
// no protect
const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight
});

const layer = new Konva.Layer();
stage.add(layer);

let ipsumShortString = `Lorem ipsum dolor sit amet, consectetur adipis-cing elit. Nulla non wombat sem, quis scelerisque augue.\n\nPellentesque porttitor augue vel justo efficitur malesuada. Aliquam tempor congue eleifend. Maecenas erat orci, aliquam vel nunc ut, gravida gravida magna.\n\nSed a laoreet urna. Cras non metus rhoncus, convallis erat sed, cursus nisl. Donec dolor enim, mollis id rutrum eu, tincidunt nec erat.`;

// Add some simple text
let t = new Konva.Text({
      //  x: 20, y: 20,
        text: ipsumShortString,
        fontFamily: 'Georgia',
        fontSize: 16,
        fontStyle: '',
        width: 448,
     //   height: 95,
  draggable: true
      }),
    r = new Konva.Rect({
   //   x: 20, y: 20,
      width: t.width(),
      height: t.height(),
      strokeWidth: 0.5,
      stroke: 'blue'
      })
layer.add(r, t);

layer.draw();

function go(opts){
  
  // Interpret the sliders for width and height into usable values.
  let bw = $('#boxWidth').val() * 10;
  bw = (bw === 0 ? undefined : bw);  
  $('#boxWidthVal').html(bw);
  $('#boxHeightVal').html($('#boxHeight').val());

  let bh = parseInt($('#boxHeight').val());
  bh = (bh === 0 ? undefined : bh);
  
  // Get the padding and line height values
  $('#boxPaddingVal').html($('#boxPadding').val());
  let lh = parseInt($('#boxLineHeight').val()) / 10;
  $('#boxLineHeightVal').html(lh);
 
  // Get the line-thru, underline and ellipsis values
  let lt = $("#lineThrough:checked").val() ? $("#lineThrough").val() : '';
  let ul = $("#underline:checked").val() ? $("#underline").val() : '';
  let ellipsis = $("#ellipsis:checked").val() ? $("#ellipsis").val() : '';
  
  // Get the bold and italic values
  let fontStyleBold, fontStyleItalic = '';
  fontStyleBold = $("#bold:checked").val() ? $("#bold:checked").val() : '';
  fontStyleItalic = $("#italic:checked").val() ? '' + $("#italic:checked").val() : '';  
  
  
  // Set Konva stage scale
  stage.scale({x: $("#stageScale").val(), y: $("#stageScale").val()});
  
  // Set Konva.Text font parameters
  t.fontFamily($("#fontName").val());
  t.fontSize($("#fontSize").val());
  
  // Set Konva.Text size parameters
  t.width(bw);
  t.height(bh);

  // Set Konva.Text padding & line height parameters
  t.padding(parseInt($('#boxPadding').val()));
  t.lineHeight(lh);

  // Set Konva.Text align and wrap parameters
  t.align($(".halign:checked").val());
  t.verticalAlign($(".valign:checked").val());
  t.wrap($(".wrap:checked").val());
  
  // Set Konva.Text line-thru, underline and ellipsis parameters 
  t.textDecoration(lt + ' ' + ul)
  t.ellipsis(ellipsis);
  

  // Set  Konva.Text fontStyle parameter for bold & italic  
  t.fontStyle(fontStyleBold + ' ' + fontStyleItalic)

  // Set the blue boundary rect size - note there is no automatic border for a Konva.Text object.  
  r.setAttrs({
    width: t.width(),
    height: t.height()
  });
  
  // Ask for an efficient redraw with all changes applied.
  layer.batchDraw();
  
}

// Event listener for sliders - refresh parameters when change occurs.
$('input[type=range]').on('mouseup input', function(e){

  go();
    
})

// Event listener for other inputs - refresh parameters when change occurs.
$('select,input').on('change', function(){
  go();
});

// Event listener for click event of the reset button - reset to defaults.
$('#reset').on('click', function(){
  
  $("#stageScale").val(2);
  $('#boxWidth').val(20);
  $('#boxHeight').val(250);
  
  $("#bold").prop("checked", false);
  $("#italic").prop("checked", false);

  $("#lineThrough").prop("checked", false);
  $("#underline").prop("checked", false);
  $("#ellipsis").prop("checked", false);

  $("#wrap-word").prop("checked", true);
  
  $("#halign-left").prop("checked", true);
  $("#valign-top").prop("checked", true);
  
  $('#boxPadding').val(0);
  $('#boxLineHeight').val(10)
  
  $('#fontName').val('Georgia')
  $('#fontSize').val(16)
  
  go();
})

// Initial call to draw the output.
go();


// Load the web fonts from Google.
 WebFont.load({
    google: { 
      families: [
        'Anton',
        'Bad Script',
        'Catamaran', 
        'Droid Sans', 
        'Droid Serif', 
        'Hammersmith One',  
        'Hanalei', 
        'IM Fell Double Pica',
        'Lobster',
        'Merriweather',
        'Noto Sans JP', 
        'Open Sans', 
        'Pangolin',
        'Roboto', 
        'Shadows Into Light',
        'Stalinist One',
        'Ubuntu',
        'Ultra'
      ] 
    },
   // called when the load of an individual font commences.
    fontloading: function(familyName, fvd) {
      console.log('Loading font [' + familyName + ']')
    },
   // called when the load of an individual font completes.
    fontactive: function(familyName, fvd) {
      console.log('Loaded font [' + familyName + ']')
      $('#fontName').append('<option value="' + familyName + '">' + familyName + '</option>'); 
    },
  }); 
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js