Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Every Animation Lover Needs A Control Panel #10

Open
9am opened this issue Nov 29, 2022 · 1 comment
Open

Every Animation Lover Needs A Control Panel #10

9am opened this issue Nov 29, 2022 · 1 comment
Assignees
Labels
javascript JavaScript web component Web Component

Comments

@9am
Copy link
Owner

9am commented Nov 29, 2022

A simple ctrl-panel I made for myself.

ctrl-panel

hits

@9am
Copy link
Owner Author

9am commented Nov 29, 2022

I'm a big fan of doing animation with codes, it's part of the reason I choose front-end to start my career years ago. In every stage of the coding, there will always be a bunch of parameters to adjust, with a control panel on the screen, we could check out the output without changing the codes now and then.

Check out the articles related to animation in this blog:

  1. <img-victor> How to create a web component that draws an image with lines using LSD & web worker.
  2. How to make a minimization effect with canvas.
  3. Light a 'Fire' with Canvas and Particles.

There are so many wheels in this area, I'll show you why and how I did this one.

The Problem

I built a library called fire-flame which will generate a flame animation on canvas. And it supports many parameters including a 2d vector which indicates the wind force applied to the flame. To control the wind, I build this panel.

cp-old

1. No <input type="?"> for complicated value (tuple, map...).

The old <input type="*"> works fine. (most of the time), As you can see, the wind is controlled by two separated <input type="range">, but things got tricky when we need complicated data(tuple, map) out of a <input>.

To solve this, we need to expand the types of input. Make new <input> element to our needs, like <input type="vector2d"> for the wind in fire-flame.

2. The 'value' of <input> needs transcoding.

The input.value is confusing sometimes, for example, most of it's a string, but for range or number we probably need a number. But for checkbox, input.value doesn't work, instead input.checked is the right way.

To solve this, we'd better implement our version of <input>, and involve TypeScript to make the types right.

3. Collect values from inputs.

Even if we add a whole bunch of new <input>, we can not include all possible data structures that the developers need. It's better to offer a way to compose and shape the value with the simple elements we offer.

To solve this, we need a logical element that doesn't hold value, it collects values from the children instead. It works like a group of values, so it's a recursive idea. We'll have two kinds of <input>: <input-item> and <input-group>. And to shape the value of <input-group>, we'll support attributes like data-type=(array|object|...).

4. Limitation on style customization.

If we use <input> directly, the style can be tricky to override, since every browser has its implementation and pseudo-element naming. And for some deeper customization, we can not do, for example, a <input type="range"> in a knob shape. Even with the new <input> we defined, we still need to consider the style customization to make the lib more versatile.

To solve this, we can use CSS Custom Properties and part from custom elements to expose the ability to customize the style to developers. Throw some pre-defined themes with the lib maybe :)

The Goal

All right, the lib will be like this:

  1. Web Components(Custom Elements) and TypeScript.
  2. <input-*> to offer the basic UI of different types of value.
  3. Wrap <input-*> with <ctrl-*>, add name, label, detail.
  4. <ctrl-group> to hold <ctrl-*>, collect values from the children.
<ctrl-group name="g1" data-type="map">
    <ctrl-text name="text">text:</ctrl-text>
    <ctrl-group name="g2" data-type="array">
        <ctrl-color>color:</ctrl-color>
        <ctrl-switch>switch:</ctrl-switch>
    </ctrl-group>
</ctrl-group>
document.querySelector('ctrl-group').value
/*
 * {
 *     g1: '', // ctrl-text
 *     g2: [
 *         '#000000', // ctrl-color
 *         false, // ctrl-switch
 *     ]
 * }
 */

Check out the ctrl-panel

Install

npm install @9am/ctrl-panel

Features

  • 9 custom elements to choose.
  • 3 themes out of the box.
  • Control the value shape with the template.
  • Customize or make your own theme with CSS properties.

Elements

Element Screenshot Varient Description Live Demo
ctrl-panel ------- ------- The root element. demo
ctrl-group ------- ------- Group ctrl-* together to shape the value. demo
ctrl-slider slider-1 slider-2 A numblic slider. demo
ctrl-clamp clamp-1 clamp-2 Select a tuple low-high value. demo
ctrl-switch switch-1 switch-2 A ON/OFF switch. demo
ctrl-radio radio-1 radio-2 Multiple/Single switch. demo
ctrl-vector vector Select a tuple vector on a 2D surface. demo
ctrl-text text Text input. demo
ctrl-color color Color picker. demo

Well, hope you enjoy it. I'll see you next time.


@9am 🕘

@9am 9am added web component Web Component javascript JavaScript labels Nov 29, 2022
@9am 9am self-assigned this Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
javascript JavaScript web component Web Component
Projects
None yet
Development

No branches or pull requests

1 participant