Build a React.js Pixel Art Text Generator in Browser Using HTML5 CSS3 and Javascript Full Project For Beginners

Build a React.js Pixel Art Text Generator in Browser Using HTML5 CSS3 and Javascript Full Project For Beginners

 

Welcome folks today in this blog post we will be building a react.js pixel art text generator in browser using html5 css3 and javascript.All the full source code of the application is shown below.

 

 

 

Get Started

 

 

 

In order to get started you need to make an index.html file and copy paste the following code

 

 

 

index.html

 

 

 

<!--
  Pixel art text generator.

  Inspired by http://pixelspeechbubble.com/, which in turn
  was inspired by the style of Diesel Sweeties by R. Stevens.

  Character data is stored in PXON format (http://jennmoney.biz/pxon/)
  and rendered as SVG using React.
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

 

 

And now make a style.css file and copy paste the following code

 

 

style.css

 

 

html {
     box-sizing: border-box;
}
 *, *:before, *:after {
     box-sizing: inherit;
}
 html, body, .app {
     width: 100%;
     height: 100%;
     overflow: hidden;
}
 .app {
     display: flex;
     flex-direction: column;
}
 .pane {
     flex: 1 1 auto;
}
 .pane--top {
     padding: 1rem;
     overflow: auto;
}
 .pane--bottom {
     height: 250px;
     flex: 0 1 250px;
}
 .input {
     border: none;
     background: #eee;
     width: 100%;
     height: 100%;
}

 

 

And now make a script.js file and copy paste the following code

 

 

script.js

 

 

"use strict";

/* jshint esnext: true */
$.getJSON('https://rawgit.com/andybluntish/0aaa7f5a6eb1fa5c9799/raw/44207085dd993d34914cf3f9341877cfc5cb5342/alphabet.json').then(PXON => {
  /** Class representing a cursor, used to place each text character. */
  class Cursor {
    /**
     * Create a cursor.
     *
     * @public
     * @param {number} [x = 0] - The initial `x` position (horizontal) of the cursor.
     * @param {number} [y = 0] - The initial `y` position (vertical) of the cursor.
     */
    constructor(x = 0, y = 0) {
      this.x = x;
      this.y = y;
    }
    /**
     * Get the x value.
     *
     * @public
     * @return {Number} - The current x value.
     */


    get x() {
      return this._x;
    }
    /**
     * Set the x value.
     *
     * @public
     * @param {Number} value - The new x value. String and float values will be converted to a base 10 integer.
     * @throws {Error} - Argument x must be an integer.
     */


    set x(value) {
      const int = parseInt(value, 10);

      if (typeof int !== 'number' || isNaN(int)) {
        throw new Error('Invalid value for x. Please supply a Number');
      } else {
        this._x = int;
      }
    }
    /**
     * Get the y value.
     *
     * @public
     * @return {Number} - The current y value.
     */


    get y() {
      return this._y;
    }
    /**
     * Set the y value.
     *
     * @public
     * @param {Number} value - The new y value. String and float values will be converted to a base 10 integer.
     * @throws {Error} - Argument y must be an integer.
     */


    set y(value) {
      const int = parseInt(value, 10);

      if (typeof int !== 'number' || isNaN(int)) {
        throw new Error('Invalid value for y. Please supply a Number');
      } else {
        this._y = int;
      }
    }
    /**
     * Move cursor to an absolute x and y position.
     *
     * @public
     * @param {Number} x - The new x value. String and float values will be converted to a base 10 integer.
     * @param {Number} y - The new y value. String and float values will be converted to a base 10 integer.
     */


    move(x, y) {
      if (typeof x === 'number') {
        this.x = x;
      }

      if (typeof y === 'number') {
        this.y = y;
      }
    }

  } // <Document />


  class Document extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        message: props.message
      };
    }

    handleChange(event) {
      this.setState({
        message: event.target.value
      });
    }

    render() {
      const {
        state: {
          message
        }
      } = this;
      return /*#__PURE__*/React.createElement("div", {
        className: "app"
      }, /*#__PURE__*/React.createElement("div", {
        className: "pane pane--top"
      }, /*#__PURE__*/React.createElement(Canvas, {
        message: message
      })), /*#__PURE__*/React.createElement("div", {
        className: "pane pane--bottom"
      }, /*#__PURE__*/React.createElement("textarea", {
        className: "input",
        value: message,
        onChange: this.handleChange.bind(this)
      })));
    }

  } // <Canvas message="Hello world" />


  class Canvas extends React.Component {
    render() {
      const {
        props: {
          message = ''
        }
      } = this;
      const cursor = new Cursor(); // hard-coded to the size of the characters in the PXON font data

      const lineHeight = 70; // Track the number of lines, and length of the longest line

      let lines = 1;
      let maxWidth = 0;
      const characters = message.split('').map(char => {
        const character = char.toLowerCase(); // If its a line-break character, reset the cursor position
        // to the left and increment the line counter.

        if (character === '\n') {
          cursor.move(0, lines * lineHeight);
          lines++;
        } else {
          // Render a character
          const pxon = PXON[character] || PXON['?'];
          const {
            pxif: {
              pixels
            }
          } = pxon;
          const {
            width,
            size
          } = this.getCharacterDimensions(pxon);
          const {
            x,
            y
          } = cursor; // Move the cursor the width of this character, plus some letter spacing

          cursor.move(x + width + size); // Keep track of the widest line of text

          if (cursor.x > maxWidth) {
            // we already added the size (letter-spacing), but don't need it
            // cos its the end of the line, so take it off
            maxWidth = cursor.x - size;
          }

          return /*#__PURE__*/React.createElement(Character, {
            name: character,
            x: x,
            y: y,
            pixels: pixels
          });
        }
      }); // Set the viewBox attribute on the <svg> element to the max width/height of the characters

      const viewBox = `0 0 ${maxWidth} ${lineHeight * lines}`;
      return /*#__PURE__*/React.createElement("svg", {
        xmlns: "http://www.w3.org/2000/svg",
        version: "1.1",
        viewBox: viewBox,
        preserveAspectRatio: "xMidYMid meet",
        "aria-labelledby": "title",
        role: "img"
      }, /*#__PURE__*/React.createElement("title", null, message.replace(/\n/, ' ')), characters);
    } // Get the max width/height/size values for the pixels in this character
    // so we know the outer dimensions


    getCharacterDimensions(pxon) {
      const {
        pxif: {
          pixels
        }
      } = pxon;
      let width = 0;
      let height = 0;
      let size = 0;
      pixels.forEach(pixel => {
        const {
          x,
          y,
          size: s
        } = pixel;

        if (x > width) {
          width = x;
        }

        if (y > height) {
          height = y;
        }

        if (s > size) {
          size = s;
        }
      });
      width += size;
      height += size;
      return {
        width,
        height,
        size
      };
    }

  } // <Character name="a" x="0" y="0" pixels=[{x: 10, y: 10, size: 10, color: "black" }] />


  class Character extends React.Component {
    render() {
      const {
        props: {
          name,
          x = 0,
          y = 0,
          pixels = []
        }
      } = this;
      const transform = `translate(${x}, ${y})`;
      const pixelComponents = pixels.map(pixel => {
        const {
          x,
          y,
          size,
          color
        } = pixel;
        return /*#__PURE__*/React.createElement(Pixel, {
          x: x,
          y: y,
          size: size,
          color: color
        });
      });
      return /*#__PURE__*/React.createElement("g", {
        className: "character",
        "data-character": name,
        transform: transform
      }, pixelComponents);
    }

  } // <Pixel x="0" y="0" size="10" color="black" />


  class Pixel extends React.Component {
    render() {
      const {
        props: {
          x = 0,
          y = 0,
          size = 10,
          color = 'black'
        }
      } = this;
      return /*#__PURE__*/React.createElement("rect", {
        x: x,
        y: y,
        width: size,
        height: size,
        fill: color
      });
    }

  }

  const defaultMessage = "Hello world!\n\
\n\
abcdefghijklm\n\
nopqrstuvwxyz\n\
1234567890\n\
-=[]{}\|;':\",./<>?\n\
`~!@#$%^&*()";
  React.render( /*#__PURE__*/React.createElement(Document, {
    message: defaultMessage
  }), document.body);
});

 

See also  React.js Building a Tic Tac Toe Computer AI Single or MultiPlayer Board Game Using react-tic-tac-toe Library in Javascript Full Project For Beginners

 

And now if you open the index.html file inside the browser you will see the below screenshot

 

 

Leave a Reply