Flip.js is a HTML element for flipping child nodes.
Sets flip properties of duration, direction, and mode.
Flips items of list, you can arrange, add, and remove items.
Flips canvas candidates.
<script defer src="https://unpkg.com/@lf2com/flip.js@latest/dist/flip.min.js"></script>
<!-- or -->
<script defer src="https://cdn.jsdelivr.net/gh/lf2com/flip.js@latest/dist/flip.min.js"></script>
Use flip in HTML:
<flip-pack direction="down" mode="random">
<div class="candidate">1</div>
<div class="candidate">2</div>
<div class="candidate">3</div>
<div class="candidate">4</div>
<div class="candidate">5</div>
</flip-pack>
Or in JavaScript code:
const flip = document.createElement('flip-pack');
flip.setAttribute('direction', 'down');
flip.setAttribute('mode', 'random');
// or
flip.direction = 'down';
flip.mode = 'random';
for (let i = 0; i < 5; i += 1) {
const candidate = document.createElement('div');
candidate.classList.add('candidate');
candidate.innerText = `${i + 1}`;
flip.append(candidate);
}
document.body.append(flip);
As flip.js is an element, we can code in jQuery:
$('<flip-pack>')
.attr({
direction: 'down',
mode: 'random',
})
.append(new Array(5)
.fill(0)
.map((_, i) => (
$('<div>')
.addClass('candidate')
.html(`${i + 1}`)
))
)
.appendTo($('body'));
Or in React:
const Flip = () => (
<flip-pack
direction="down"
mode="random"
>
{(new Array(5)
.fill(0)
.map((_, i) => (
<div key={i} className="candidate">
{i + 1}
</div>
))
)}
</flip-pack>
);
⚠️ On flipping, we clone the last and next candidate children for displaying flipping animation. So if the child nodes are styled by CSS, we need to let the cloned nodes styled as the same so that them can be displayed correctly. As a result, there are some rules for preventing from issues of flipping animation.
Selectors such as flip-pack > {selector}
define those styles directly belong to flip-pack
, causing missing the styles of cloned elements. It is recommended to use flip-pack.some-class {selector}
instead.
/*
* [DO NOT USE]: flip-pack > {selector}
*/
flip-pack > .candidate {
width: 100px;
height: 150px;
border-radius: 10px;
background: #eee;
font-size: 30px;
color: #000;
}
/*
* [BETTER TO USE]: flip-pack {selector}
*/
flip-pack.candidate-set-1 .candidate {
width: 100px;
height: 150px;
border-radius: 10px;
background: #eee;
font-size: 30px;
color: #000;
}
<flip-pack class="candidate-set-1">
<div class="candidate">A</div>
<div class="candidate">B</div>
<div class="candidate">C</div>
<div class="candidate">D</div>
</flip-pack>
Selectors specifying the n-th node such as :nth-child()
cause the cloned element being applied unexpected styles due to the cloned element would be the last child of flip-pack
.
/*
* [DO NOT USE]: flip-pack :nth-child()
*/
flip-pack .candidate:nth-child(odd) {
background: #fee;
}
/*
* [BETTER TO USE]: flip-pack {selector}
*/
flip-pack .candidate.odd {
background: #fee;
}
<flip-pack id="candidate-pack">
<div class="candidate" value="a">A</div>
<div class="candidate" value="b">B</div>
<div class="candidate" value="c">C</div>
<div class="candidate" value="d">D</div>
</flip-pack>
document
.getElementById('candidate-pack')
.querySelectorAll('.candidate')
.forEach((candidate, candidateIndex) => {
if (candidateIndex % 2 === 0) {
candidate.classList.add('odd');
}
});
Build flip.js with the command:
npm run build
And get the built file at ./dist/flip.min.js
.
Use <flip-pack>
to wrap those child nodes for flipping:
<flip-pack>
<div value="a">A</div>
<div value="b">B</div>
<div value="c">C</div>
<div value="d">D</div>
</flip-pack>
Properties for setting the animation and current status of flip element.
Type of value:
HTMLElement
[]
Returns the candidate elements that we can flip to.
console.log('Candidates:', flip.candidates);
Type of value:
string
Default:
'loop'
Mode of picking the next child element to show:
Name | Description |
---|---|
loop | Pick the next candidate right after the current one |
random | Pick candidate randomly |
<!-- set mode -->
<flip-pack mode="random">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set mode of picking the next candidate
flip.mode = 'random';
// or
flip.setAttribute('mode', 'random');
// get mode of picking the next candidate
console.log('Mode:', flip.mode);
// or
console.log('Mode:', flip.getAttribute('mode'));
Type of value:
number
Default:
400
Duration of animation flipping per candidate in milliseconds.
<!-- set duration -->
<flip-pack duration="200">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set duration of animation
flip.duration = 200;
// or
flip.setAttribute('duration', '200');
// get duration in number
console.log('Duration:', flip.duration);
// or in string
console.log('Duration:', flip.getAttribute('duration'));
Type of value:
string
Default:
'down'
Direction of flipping candidates:
Name | Description |
---|---|
down | Flipping down from the top side |
up | Flipping up from the bottom side |
left | Flipping left from the right side |
right | Flipping right from the left side |
<!-- set direction -->
<flip-pack direction="left">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set direction
flip.direction = 'left';
// or
flip.setAttribute('direction', 'left');
// get direction
console.log('Direction:', flip.direction);
// or
console.log('Direction:', flip.getAttribute('direction'));
Type of value:
number
Default:
0
forminFlips
;Infinity
formaxFlips
Minimum or maximum times of flipping candidates on random
mode.
<!-- set min/max flips -->
<flip-pack mode="random" min-flips="5" max-flips="8">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set min/max flips
flip.minFlips = 5;
flip.maxFlips = 8;
// or
flip.setAttribute('min-flips', '5');
flip.setAttribute('max-flips', '8');
// get min/max flips in number
console.log('Min flips:', flip.minFlips);
console.log('Max flips:', flip.maxFlips);
// or in string
console.log('Min flips:', flip.getAttribute('minFlips'));
console.log('Max flips:', flip.getAttribute('maxFlips'));
Type of value:
string
Default:
2 * Math.max({width_of_candidate}, {height_of_candidate})
CSS 3D perspective of flipping animation.
<!-- set perspective -->
<flip-pack perspective="50vmin">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set perspective
flip.perspective = '50vmin';
// or
flip.setAttribute('perspective', '50vmin');
// get perspective
console.log('CSS perspective:', flip.perspective);
// or
console.log('CSS perspective:', flip.getAttribute('perspective'));
Type of value:
number
Default:
0
if there is at least 1 candidate. Otherwise-1
.
Index of current candidate. Set index to change the current displayed candidate without flipping animation.
⚠️ If we assign bothindex
andvalue
on HTML attributes, we would apply the value ofindex
instead ofvalue
.
<!-- initial index -->
<flip-pack index="2">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</flip-pack>
// set index
flip.index = 2;
// or
flip.setAttribute('index', '2');
// get index in number
console.log('Current index:', flip.index);
// or in string
console.log('Current index:', flip.getAttribute('index'));
Type of value:
string
|null
Value of current candidate. Set value of candidate candidates to change the current displayed candidate without flipping animation.
⚠️ If we assign bothindex
andvalue
on HTML attributes, we would apply the value ofindex
instead ofvalue
.
<!-- set value -->
<flip-pack value="c">
<div value="a">A</div>
<div value="b">B</div>
<div value="c">C</div>
<div value="d">D</div>
</flip-pack>
// set value
flip.value = 'c';
// or
flip.setAttribute('value', 'c');
// get value
console.log('Current value:', flip.value);
// or
console.log('Current value:', flip.getAttribute('value'));
Type of value:
HTMLElement
|null
Current displayed candidate. Set an candidate element to change the current displayed candidate without flipping.
<flip-pack>
<div value="a">A</div>
<div value="b">B</div>
<div value="c">C</div>
<div value="d">D</div>
</flip-pack>
// set candidate
flip.candidate = flip.querySelector('[value="d"]');
// get candidate
console.log('Current candidate:', flip.candidate);
Flip methods deal with those related to flip.
Argument | Type | Description |
---|---|---|
candidate | HTMLElement | Candidate element |
Returns the value of candidate element. The value is the same as the attribute value of value
.
<flip-pack>
<div value="a">A</div>
<div value="b">B</div>
<div value="c">C</div>
<div value="d">D</div>
</flip-pack>
// get candidate value: 'a'
console.log('Value:', Flip.getCandidateValue(flip.firstElementChild()));
Applies flipping animation based on options
.
Properties of options
:
Name | Type | Description |
---|---|---|
direction | Direction | Direction of flipping animation |
duration | number | Duration of flipping per candidate |
minFlips | number | Minimum times of flipping passed candidates |
maxFlips | number | Maximum times of flipping passed candidates |
perspective | string | CSS 3D perspective value for flipping animation |
lastCandidateInfo | CandidateInfo | Object of current candidate info |
nextCandidateInfo | CandidateInfo | Object of target candidate info |
tempCandidateNode | HTMLElement | Temporary element for handling flipping animation |
Returns the candidate element by any of the following types:
Type | Description |
---|---|
number | Index of candidate |
string | Value of candidate |
Returns the candidate index by any of the following types:
Type | Description |
---|---|
string | Value of candidate |
HTMLElement | Element of candidate |
Returns the candidate value by any of the following types:
Type | Description |
---|---|
number | Index of candidate |
HTMLElement | Element of candidate |
Returns the object of candidate info by any of the following types:
Type | Description |
---|---|
number | Index of candidate |
string | Value of candidate |
HTMLElement | Element of candidate |
Properties of candidate info:
Argument | Type | Description |
---|---|---|
index | number | Index of candidate |
value | string | null | Value of candidate |
node | HTMLElement | null | Element of candidate |
Returns the next candidate index with options
:
Name | Type | Description |
---|---|---|
mode? | Mode | Mode of picking candidate |
Returns the next candidate element with options
. The properties of options
are the same as .getNextCandidateIndex
.
Returns the next candidate value with options
. The properties of options
are the same as .getNextCandidateIndex
.
Returns the object of next candidate info with options
. The properties of options
are the same as .getNextCandidateIndex
.
Flips to the specific candidate by any of the following types:
Type | Description |
---|---|
number | Index of candidate |
string | Value of candidate |
HTMLElement | Element of candidate |
Properties of options
extend that of .getNextCandidateIndex
:
Name | Type | Description |
---|---|---|
direction? | Direction | Direction of flipping animation |
duration? | number | Duration of flipping per candidate |
minFlips? | number | Minimum times of flipping passed candidates |
maxFlips? | number | Maximum times of flipping passed candidates |
perspective? | string | CSS 3D perspective value for flipping animation |
// use await to wait until flipping animation ends
await flip.flip({
maxFlips: 0,
});
Flips to the defaul next candidate with the same options
as .flip
.
Events for flip elements:
Cancelable:
true
Would not switch to target candidate if the event is canceled.
Dispatches on starting of switching candidate.
Values of event.detail
:
Name | Type | Description |
---|---|---|
mode | Mode | Mode of flipping |
direction | Direction | Direction of flipping animation |
duration | number | Duration of flipping per candidate |
minFlips | number | Minimum times of flipping passed candidates |
maxFlips | number | Maximum times of flipping passed candidates |
perspective | string | CSS 3D perspective value for flipping animation |
lastCandidateInfo | CandidateInfo | Object of current candidate info |
targetCandidateInfo | CandidateInfo | Object of target candidate info |
Cancelable:
false
Dispatches on the end of switching candidate.
Properties of event.detail
is the same as flipstart.
Cancelable:
true
Would not display flipping animation if the event is canceled.
Dispatches on starting of flipping animation.
Properties of event.detail
extend that of flipstart:
Name | Type | Description |
---|---|---|
tempCandidateNode | HTMLElement | Temporary element for handleing animation of flipping |
Cancelable:
false
Dispatchse on the end of flipping animation.
Properties of event.detail
is the same as flipcandidatestart.
Flip.js is MIT licensed.