Skip to content

lostinmind-dev/c3react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

31 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

C3React

Construct 3 Tool Kit for fast AND easy scripting

Usage

πŸ’ͺ Advantages

Construct 3.

  • ⚑️ Using the powerful JavaScript Runtime Deno.
  • πŸ“ Typescript oriented tool
  • πŸš€ Fast build using Vite
  • πŸ” Availability to use NPM and JSR packages

PRINCIPLES

  • public methods are for using ONLY outside component
  • protected methods are for using ONLY inside component
  • get/set without public/protected are for using BOTH inside and outside component
  • setState() component's method must be using ONLY outside

Project Structure

project/
β”œβ”€β”€ project.c3proj
└── ...
scripts/
β”œβ”€β”€ components/
β”‚   └── *.ts
β”œβ”€β”€ layouts/
β”‚   └── *.layout.ts
└── main.ts

πŸš€ Quickstart

deno install -f -A -g -n jsr:@lostinmind/c3react/cli
  • Open C3 Template project in VSCode ./template/
  • Install dependencies
npm install
  • Open C3 project ./project/
  • Run following command:
deno task dev

πŸš€ "C3React" Template project

Template is using GSAP tool for small beautiful animations (NPM module)

main.ts

import app from 'c3react';

/** You can use NPM modules! */
import gsap from 'gsap';

import Main from '@/layouts/main.layout.ts';

app.init({
    /** Enter types of inputs that your app's using */
    inputs: ['pointer', 'mouse', 'keyboard'],
    layouts: [
        /** Import your layouts here... */
        Main,
    ],
    beforeStart: async () => {
        /** Do something it's like runOnStartup() inside block  */
        /** Also here you already can use global 'runtime' variable */
        console.log('Before start!', runtime);
    },
});

/** Avoid errors with active GSAP animations when changing layout */
app.on('afteranylayoutend', () => gsap.globalTimeline.clear());

layouts/main.layout.ts

import { Layout, utils } from 'c3react';

import C3React from '@/components/c3react.ts';
import Button from '@/components/button.ts';

export class MainLayout extends Layout {
    private readonly c3react = new C3React();
    private readonly button = new Button('c3react');

    protected override onStart = () => {
        const onClicked = () => {
            this.c3react.play();

            this.button.setState({
                color: [
                    utils.random(0, 255),
                    utils.random(0, 255),
                    utils.random(0, 255),
                ],
            });
        };

        this.button.setState({
            label: 'C3React :>',
            color: [0, 225, 199],
            onClicked,
        });
    };
}

const layout = new MainLayout('main');
export default layout;

components/c3react.ts

import { Component } from 'c3react';
import gsap from 'gsap';

export default class C3React extends Component<{}, 'c3react'> {
    constructor() {
        super({}, 'c3react');
    }

    protected override onReady(): void {
        const root = this.getRoot();

        root.setSize(0, 0);

        gsap.to(root, {
            width: 428,
            height: 428,

            duration: 1.25,
            ease: 'back.out',
        });
    }

    protected override onDestroyed(): void {
        gsap.killTweensOf(this.getRoot());
        console.log('C3React component was destroyed :3');
    }

    play() {
        gsap.to(this.getRoot(), {
            angleDegrees: 360,

            duration: 1,
            ease: 'power3.out',
            overwrite: true,
        });
    }
}

components/button.ts

import { Component, useChild, useTouched, utils } from 'c3react';
import gsap from 'gsap';

export default class Button extends Component<{
    onClicked?: () => void;
    label: string;
    color: Vec3Arr;
}, 'button'> {
    private readonly useLabel = useChild(() => this.getRoot(), 'text');

    private initialSize: C3React.Size = {
        width: 0,
        height: 0,
    };

    constructor(id: 'c3react') {
        super(
            { color: [0, 225, 199], label: 'C3React' },
            'button',
            (i) => i.instVars.id === id,
        );
    }

    protected override onReady(): void {
        const { label, color } = this.getState();
        const { width, height } = this.getRoot();
        this.initialSize = { width, height };

        this.useLabel().text = label;
        this.changeColor(color);

        useTouched(() => this.getRoot(), (type) => {
            switch (type) {
                case 'start':
                    {
                        this.animateIn();
                    }
                    break;
                case 'end':
                    {
                        const { onClicked } = this.getState();

                        this.animateOut();
                        onClicked?.();
                    }
                    break;
            }
        });
    }

    protected override onStateChanged(): void {
        const { label, color } = this.getState();

        if (this.getPreviousState().label !== label) {
            this.useLabel().typewriterText(label, 0.5);
        }

        this.changeColor(color);
    }

    private changeColor(color: Vec3Arr) {
        const root = this.getRoot();

        const [r, g, b] = root.colorRgb;
        const rgb = utils.rgbToVec3(color);

        const $ = { r, g, b };
        gsap.to($, {
            r: rgb[0],
            g: rgb[1],
            b: rgb[2],

            duration: 1,
            ease: 'power4.out',
            overwrite: true,
            onUpdate: () => {
                root.colorRgb = [$.r, $.g, $.b];
            },
        });
    }

    private animateIn() {
        gsap.to(this.getRoot(), {
            width: this.initialSize.width / 1.2,
            height: this.initialSize.height / 1.2,

            duration: 0.2,
            ease: 'power4.out',
            overwrite: true,
        });
    }

    private animateOut() {
        gsap.to(this.getRoot(), {
            width: this.initialSize.width,
            height: this.initialSize.height,

            duration: 0.2,
            ease: 'power4.out',
            overwrite: true,
        });
    }
}

About

πŸš€ Construct 3 Tool Kit for fast AND easy scripting

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published