9am / 9am.github.io

9am Blog 🕘 ㍡
https://9am.github.io/
MIT License
3 stars 0 forks source link

Every Animation Lover Needs A Control Panel #10

Open 9am opened 1 year ago

9am commented 1 year ago
A simple ctrl-panel I made for myself.
ctrl-panel hits
9am commented 1 year ago

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

flat1 flat2 neu oldschool

ctrl-panel

GitHub npm npm npm bundle size

Install

npm install @9am/ctrl-panel

Features

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 🕘