nazca - Introduction tutorial
Tags: javascript, css, html, webdev
Published: 2021-11-03 08:05:41

Nazca is a new GUI programming language. It is based on CSS. If you describe the style (CSS) that has functions (JavaScript) and the ability to define page structure (HTML), you'll get [nazca](https://github.com/Qinti/nazca). Another way to imagine it - the syntactic sugar that converts a single UI code into CSS, JavaScript, and HTML.

Let's see how easily we can create web applications with it.
## Install and init first nazca project
It is better to install it globally
```
npm i -g nazca
```
Now you have a tool installed that can initialize the project for you, compile it and analyze if there are any errors.
Let's create a new project
```
mkdir firstProject
cd firstProject
nazca init
```
This creates a new folder, called "firstProject", it adds the default .nazca configuration to it and some folder structure for you. It also creates the default `*.nazca` file.

You can easily compile it
```
nazca
```

Nazca does not serve files. It is up to you what you want to use, will it be the nodeJS app, or simple nginx serving static files - it does not matter. Nazca is just a front-end compiler that takes the sources and converts them to `*.css`, `*.js`, and `.html` for your browser to understand.
For this tutorial, we will use a simple HTTP nodeJS server.
```
npm i -g http-server
cd www
http-server -c-1
```
We installed `http-server` package, which will serve the files, then changed to the output directory (check `.nazca` settings file) and ran it with the cache living for 1 second.
Open your browser and go to `http://localhost:8080`, you'll see the compiled default nazca code.

## Import existing JS code
The easiest way to do something is to import the module intended to be used on the browser side. I have one useful module just for the sake of the tutorial, but you can import any existing modules you would like. During the compile nazca searches the module you specified in the `node_modules` directory, puts the script inside the `modules` directory, and imports it with `import` of the ES6.

Let's install it first
```
npm i nazca-logo-3d
```
You should install it locally for nazca to be able to search `node_modules`.

Let's modify `nazca/index.nazca` we created previously.
```
*import: Logo = nazca-logo-3d;

.html {
    .head {
        .title {
            text: Nazca 3D logo;
        };
    };
    
    .body {
        constructor: () {
            new Logo(native);
        };
    };
};
```
Here we have a few elements without the names, but with the defined classes. Nazca has pre-defined classes for all html elements. If you define `.head` it is compiled as an html element `<head></head>`.
The body element has `constructor()` method. This method is executed, when all the elements are loaded (`DOMContentLoaded` event).
At the beginning of the file, we used `import directive`. It defines a new global variable, called "Logo", which is imported from the module we installed. In the constructor, the new instance of the `Logo` is created. Because the code is inside the constructor of the body, to access its properties you don't have to specify `this`, but use the property instead. All nazca elements have default `native` property. It allows you to access the native element. It is useful in this case to pass it to the constructor of the module.

Compile it and refresh it in the browser.

## Adding the loader
Your program uses the `nazca-logo-3d` module that loads the models from the web and renders them. What if you have a slow connection and can't load the models quickly? Let's create a loader for it.
Let's imitate the loading process by adding 5s timeout before adding the `Logo` to the page

Replace contents of `nazca/index.nazca` with this code
```
*import: Logo = nazca-logo-3d;

.html {
    .head {
        .title {
            text: Nazca 3D logo;
        };
    };

    .body {
        constructor: () {
            setTimeout(() => {
                new Logo(native);
            }, 5000);
        };

        .div {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%,-50%);
            z-index: -1;

            .div {
                -maxCounter: 45;
                -counter: 0;
                -increment: 1;

                constructor: () {
                    animate();
                };

                -animate: () {
                    counter += increment;

                    if (counter >= maxCounter) {
                        increment = -1;
                    } else if (counter < 0) {
                        increment = 1;
                    }

                    point.left = `${counter}px`;
                    requestAnimationFrame(animate);
                };

                point.div {
                    background-color: #80e780;
                    position: absolute;
                    left: 0;
                    top: 0;
                    width: 1px;
                    height: 1px;
                    box-shadow: 1px 0 10px 3px #2c9d2c;
                };
            };

            .div {
                text: Loading;
                text-transform: uppercase;
                font-family: sans-serif;
                font-size: 10px;
                padding-top: 15px;
            };
        };
    };
};
```
Nazca has 3 types of accessors. Private properties and methods are accessible only by the instance of the class, where they are declared. Protected can be accessible by the instance of any class extended from that one and the public, accessible by anyone. In nazca they are specified by a special prefix. `-` means private methods and properties. If no properties are specified, it is public. See [full nazca README](https://github.com/Qinti/nazca/blob/master/README.md) for more details.

Here we added a new element, called `point`, so later we can access it in the parent element in the hierarchy. The code in `animate()` moves it by one pixel every frame, making running animation. All public properties that are named as CSS parameters are treated by the compiler as CSS properties.

## Conclusion
In this tutorial I covered a small portion of what nazca can do. Check the project's [GitHub page and see the full README](https://github.com/Qinti/nazca/blob/master/README.md) to learn more features.