Text arranger made up of numerous html5 API components. Play with the final app, and see how the different options interact with one another. Here are a couple things you might find interesting: Increasing the text size with a pattern that is the size of the canvas changes the pattern on the text. (It acts like a mask or window into the pattern itself.) Canvas width and height are affected by the style width and height (scaling). We will utilize a JavaScript library named modernizr.js that will help us figure out which browsers support which Canvas features. ```html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CH3EX3: Text Arranger 3.0</title> <script src="modernizr.js"></script> <script type="text/javascript" src="jscolor/jscolor.js"></script> <script src="script.js"> </head> <body> <div style="position: absolute; top: 50px; left: 50px;"> <canvas id="canvasOne" width="500" height="300"> Your browser does not support HTML5 Canvas. </canvas> <form> Text: <input id="textBox" placeholder="your text" /> <br> Text Font: <select id="textFont"> <option value="serif">serif</option> <option value="sans-serif">sans-serif</option> <option value="cursive">cursive</option> <option value="fantasy">fantasy</option> <option value="monospace">monospace</option> </select> <br> Font Weight: <select id="fontWeight"> <option value="normal">normal</option> <option value="bold">bold</option> <option value="bolder">bolder</option> <option value="lighter">lighter</option> </select> <br> Font Style: <select id="fontStyle"> <option value="normal">normal</option> <option value="italic">italic</option> <option value="oblique">oblique</option> </select> <br> Text Size: <input type="range" id="textSize" min="0" max="200" step="1” value="50"/> <br> Fill Type: <select id="fillType"> <option value="colorFill">Color Fill</option> <option value="linearGradient">Linear Gradient</option> <option value="radialGradient">Radial Gradient</option> <option value="pattern">pattern</option> </select> <br> Text Color: <input class="color" id="textFillColor" value="FF0000"/> <br> Text Color 2: <input class="color" id="textFillColor2" value ="000000"/> <br> Fill Or Stroke: <select id="fillOrStroke"> <option value="fill">fill</option> <option value="stroke">stroke</option> <option value="both">both</option> </select> <br> Text Baseline <select id="textBaseline"> <option value="middle">middle</option> <option value="top">top</option> <option value="hanging">hanging</option> <option value="alphabetic">alphabetic</option> <option value="ideographic">ideographic</option> <option value="bottom">bottom</option> </select> <br> Text Align <select id="textAlign"> <option value="center">center</option> <option value="start">start</option> <option value="end">end</option> <option value="left">left</option> <option value="right">right</option> </select> <br> Alpha: <input type="range" id="textAlpha" min="0.0" max="1.0" step="0.01" value="1.0"/> <br> Shadow X:<input type="range" id="shadowX" min="−100" max="100" step="1" value="1"/> <br> Shadow Y:<input type="range" id="shadowY" min="−100" max="100" step="1" value="1"/> <br> Shadow Blur: <input type="range" id="shadowBlur" min="1" max="100" step="1" value="1" /> <br> Shadow Color: <input class="color" id="shadowColor" value="707070"/> <br> Canvas Width: <input type="range" id="canvasWidth" min="0" max="1000" step="1" value="500"/> <br> Canvas Height: <input type="range" id="canvasHeight" min="0" max="1000" step="1" value="300"/> <br> Canvas Style Width: <input type="range" id="canvasStyleWidth" min="0" max="1000" step="1" value="500"/> <br> Canvas Style Height: <input type="range" id="canvasStyleHeight" min="0" max="1000" step="1" value="300"/> <br> <input type="button" id="createImageData" value="Create Image Data"> <br> <br> <textarea id="imageDataDisplay" rows=10 cols=30></textarea> </form> </div> </body> </html> ``` Now we are going to add all the logical part of the application. ```js windows.addEventListener("Load", eventWindowLoaded, false); function eventWindowLoaded(){ canvasApp(); } function canvasSupport(){ return Modernizr.canvas; } function eventWindowLoaded(){ let patternPreload = new Image(); paternPreload.onload = eventAssetsLoaded; patternPreloade.src = "texture.jpg"; } function eventAssetsLoaded(){ canvasApp(); } function canvasApp(){ let message = "your text"; let fontSize = "50"; let fontFace = "serif"; let textFillColor = "#ff0000"; let textAlpha = 1; let shadowX = 1; let shadowY = 1; let shadowBlur = 1; let shadowColor = "#707070"; let textBaseline = "middle"; let textAlign = "center"; let fillOrStroke = "fill"; let fontWeight = "normal"; let fontStyle = "normal"; let fillType = "colorFill"; let textFillColor2 = "#000000"; let pattern = new Image(); if(!canvasSupport()){ return; } let theCanvas = document.querySelector("#canvasOne"); let context = theCanvas.getContext("2d"); let formElement = document.querySelector("#textBox"); formElement.addEventListener("keyup", textBoxChanged, false); formElement = document.querySelector("#fillOrStroke"); formElement.addEventListener("change", fillOrStrokeChanged, false); formElement = document.querySelector("#textSize"); formElement.addEventListener("change", textSizeChanged, false); formElement = document.querySelector("#textFillColor"); formElement.addEventListener("change", textFillColorChanged, false); formElement = document.querySelector("#textFont"); formElement.addEventListener("change", textFontChanged, false); formElement = document.querySelector("#textBaseline"); formElement.addEventListener("change", textBaselineChanged, false); formElement = document.querySelector("#textAlign"); formElement.addEventListener("change", textAlignChanged, false); formElement = document.querySelector("#fontWeight"); formElement.addEventListener("change", fontWeightChanged, false); formElement = document.querySelector("#fontStyle"); formElement.addEventListener("change", fontStyleChanged, false); formElement = document.querySelector("#shadowX"); formElement.addEventListener("change", shadowXChanged, false); formElement = document.querySelector("#shadowY"); formElement.addEventListener("change", shadowYChanged, false); formElement = document.querySelector("#shadowBlur"); formElement.addEventListener("change", shadowBlurChanged, false); formElement = document.querySelector("#shadowColor"); formElement.addEventListener("change", shadowColorChanged, false); formElement = document.querySelector("#textAlpha"); formElement.addEventListener("change", textAlphaChanged, false); formElement = document.querySelector("#textFillColor2"); formElement.addEventListener("change", textFillColor2Changed, false); formElement = document.querySelector("#fillType"); formElement.addEventListener("change", fillTypeChanged, false); formElement = document.querySelector("#canvasWidth"); formElement.addEventListener("change", canvasWidthChanged, false); formElement = document.querySelector("canvasHeight"); formElement.addEventListener("change", canvasHeightChanged, false); formElement = document.querySelector("#canvasStyleWidth"); formElement.addEventListener("change", canvasStyleSizeChanged, false); formElement = document.querySelector("#canvasStyleHeight"); formElement.addEventListener("change", canvasStyleSizeChanged, false); formElement = document.querySelector("#createImageData"); formElement.addEventListener("change", createImageDataPressed, false); pattern.src = "texture.jpg"; drawScren(); // Background context.globalAlpha = 1; context.shadowColor = "#707070"; context.shadowOffsetX = 0; context.shodowOffsetY = 0; context.shadowBlur = 0; context.fillStyle = "#ffffaa"; context.fillRect(0, 0, theCanvas.width, theCanvas.height); context.strokeStyle = "#000000"; context.strokeRect(5, 5, theCanvas.width-10, theCanvas.height-10); //Text context.textBaseline = textBaseline; context.textAlign = textAlign; context.font = fontWeight + " " + fontStyle + " " + fontSize + "px " + fontFace; context.shadowColor = shadowColor; context.shadowOffsetX = shadowX; context.shadowOffsetY = shadowY; context.shadowBlur = shadowBlur; context.globalAlpha = textAlpha; let xPosition = (theCanvas.width/2); let yPosition = (theCanvas.height/2); let metrics = context.measureText(message); let textWidth = metrics.width; let tempColor; if(fillType == "colorFill"){ tempColor = textFillColor; }else if(fillType == "linearGradient"){ let gradient = context.createLinearGadient(xPosition-textWidth/2, yPosition, textWidth, yPosition); gradient.addColorStop(0,textFillColor); gradient.addColorStop(.6,textFillColor2); tempColor = gradient; }else if(fillType == "radialGradient"){ let gradient = context.createRadialGradient(xPosition, yPosition, fontSize, xPosition+textWidth, yPosition, 1); gradient.addColorStop(0,textFillColor); gradient.addColorStop(6,textFillColor2); tempColor = gradient; }else if(fillType == "pattern"){ let tempColor = context.createPattern(pattern, "repeat"); }else{ tempColor = textFillColor; } switch(fillOrStroke){ case "fill": context.fillStyle = tempColor; context.fillText(message, xPosition,yPosition) break; case "stroke": context.strokeStyle = tempColor; context.strokeText(message, xPosition,yPosition); break; case "both": context.fillStyle = tempColor; context.fillText(message, xPosition,yPosition); cotext.strokeStyle = "#000000"; context.strokeText(message, xPosition,yPosition); break; } } function textBoxChanged(e){ let target = e.target; message = target.value; drawScreen(); } function textBaselineChanged(e){ let target = e.target; textBaseline = target.value; drawScreen(); } function textAlignChanged(e){ let target = e.target; textAlign = target.value; drawScreen(); } function fillOrStrokeChanged(e){ let target = e.target; fillOrStroke = target.value; drawScreen(); } function textSizeChanged(e){ let target = e.target; fontSize = target.value; drawScreen(); } function textFillColorChanged(e){ let target = e.target; textFillColor = "#" + target.value; drawScreen(); } function textFontChenged(e){ let target = e.target; fontFace = target.value; drawScreen(); } function fontWeigthChanged(e){ let target = e.target; fontWeight = target.value; drawScreen(); } function fontStyleChanged(e){ let target = e.target; fontStyle = target.value; drawScreen(); } function shadowXChanged(e){ let target = e.target; shadowX = target.value; drawScreen(); } function shadowYChanged(e){ let target = e.target; shadowY = target.value; drawScreen(); } function shadowBlurChanged(e){ let target = e.target; shadowBlur = target.value; drawsScreen(); } function shadowColorChanged(e){ let target = e.target; shadowColor = target.value; drawScreen(); } function textAlphaChanged(e){ let target = e.target; textAlpha = (target.value); drawScreen(); } function textFillColor2Changed(e){ let target = e.target; textFillColor2 = "#" + target.value; drawScreen(); } function fillTypeChanged(e){ let target = e.target; fillType = target.value; drawScreen(); } function canvasWidthChanged(e){ let target = e.target; theCanvas.width = target.value; drawScreen(); } ``` [conclusion here](https://chat-to.dev/post?id=53)