SquircleKeycap
A key drawn as a superellipse and extruded, which travels when you press it.
Options
-
plate#efece3 -
css colour
The surface the key sits on. Slightly darker than the cap, because a key is lighter than the thing it is set into and that difference is most of what says it stands up.
-
cap#fbfaf6 -
css colour
The top of the key.
-
side#d6d1c4 -
css colour
The sides, which are what makes it a solid rather than a sticker. It wants to be a clear step darker than the cap: this is a facet turned away from the light, not a shadow.
-
ink#2b2a26 -
css colour
The legend, and the contact shadow under the key.
-
legendK -
What is printed on the key. One or two characters: it is set at under a third of the key's width, and a word at that size is a label on a key rather than a key.
-
corner4.2 -
2 to 16, good: 3 to 6
The superellipse exponent. 2 is an ellipse, 4 is the shape everybody means by a squircle, and by 12 it is a rectangle with a hint of a corner. The useful range is narrow and the difference inside it is the whole item.
-
size0.56 -
0.15 to 0.9
How much of the shorter side of the element the key takes up.
-
depth0.16 -
0.02 to 0.4, good: 0.1 to 0.24
How tall the key stands, as a share of its width. This is the thing the press has to eat into, so a flat key has nowhere to travel and reads as a flicker.
-
travel0.62 -
0.1 to 1, good: 0.5 to 0.8
How far down it goes when pressed, as a share of its height. At 1 it bottoms out flush with the plate, which reads as broken rather than as pressed.
-
snap0.13 -
0.03 to 0.6, good: 0.08 to 0.2
Seconds the key takes to come back up. The way down is fixed and fast, because that is a key hitting a stop; this is the rubber dome, and it is the only half with any character in it.
What it needs
- Category
- Surfaces, an effect
- Dependencies
- None at all
- Browser
- No WebGL
- Frame budget
- ~0.5 ms · 0 context
- Pinned to
- v0.14.0
- The shape is the point. A border-radius is a rectangle with circular arcs stuck on the corners, and the join between the straight edge and the arc is continuous in position and direction but not in curvature: it jumps from zero to one over the radius, instantly. A superellipse has no join at all, because it is one equation the whole way round
- Walked as a path rather than approximated, so the exponent is a real control: 2 is an ellipse, 4 is the shape everybody means, and by 12 it is a rectangle with a suggestion of a corner. No value of border-radius lands on any of them
- The exponent is applied to the absolute value of the cosine and the sign put back, because a fractional power of a negative number is not a number and the left half of the shape would simply not be drawn
- The travel is a closed form of the time since the press, so renderAtTime is pure in t. A key is state between frames by nature, which is the one thing this library will not have: the resolution is to keep the list of presses rather than the position and work the displacement out from the clock. Seeking backwards unpresses the key, which a spring integrated frame by frame can never do
- An attack and a decay, not a spring. A keycap does not oscillate: it goes down against a stop, fast and ending abruptly, and comes back on a rubber dome, slower and settling without overshoot
- The side is drawn as its own extrusion rather than as a drop shadow, which is the difference between a key and a sticker. It is also what makes the travel legible: the side gets shorter as the key goes down, and that is the part anyone actually reads
- The top is dished rather than domed. A keycap is concave so a fingertip sits in it, and what reports that is a soft dark edge at the top of the face, not a highlight in the middle
- A press anywhere on the element counts rather than only inside the drawn shape. A click two pixels outside the edge is a click the reader believes they made
- 2D rather than WebGL. A key is something you want several of on a page, and the budget is one WebGL context
- It is a drawing of a control, not a control. There is no role, no focus and no keyboard handling, because a canvas cannot carry them. Put it behind a real button if it is going to do something
- Two filled paths of a hundred and twenty points, a clipped gradient and one glyph