@lf2com/flip.js
v1.2.0
Published
Flip.js is an element for flipping effect for wrapped card elements
Downloads
1
Readme
flip.js
Flip.js is a HTML element for flipping child nodes.
Demo
Sets flip properties of duration, direction, and mode.
Flips items of list, you can arrange, add, and remove items.
Flips canvas candidates.
Get Started
<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>
);
Styling Child Nodes
:warning: 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.
Specific Selector of Parent
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>
Nth Selector
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
Build flip.js with the command:
npm run build
And get the built file at ./dist/flip.min.js
.
Nodes of Flip.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
Properties for setting the animation and current status of flip element.
.candidates
Type of value:
HTMLElement
[]
Returns the candidate elements that we can flip to.
console.log('Candidates:', flip.candidates);
.mode
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'));
.duration
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'));
.direction
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'));
.minFlips/.maxFlips
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'));
.perspective
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'));
.index
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.
:warning: If we assign both
index
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'));
.value
Type of value:
string
|null
Value of current candidate. Set value of candidate candidates to change the current displayed candidate without flipping animation.
:warning: If we assign both
index
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'));
.candidate
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);
Methods
Flip methods deal with those related to flip.
Static
Flip.getCandidateValue(candidate)
| 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()));
.flipAnimation(options)
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 |
Instance
.getCandidateNode(source)
Returns the candidate element by any of the following types:
| Type | Description | | :-: | :- | | number | Index of candidate | | string | Value of candidate |
.getCandidateIndex(source)
Returns the candidate index by any of the following types:
| Type | Description | | :-: | :- | | string | Value of candidate | | HTMLElement | Element of candidate |
.getCandidateValue(source)
Returns the candidate value by any of the following types:
| Type | Description | | :-: | :- | | number | Index of candidate | | HTMLElement | Element of candidate |
.getCandidateInfo(source)
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 |
.getNextCandidateIndex(options?)
Returns the next candidate index with options
:
| Name | Type | Description | | -: | :-: | :- | | mode? | Mode | Mode of picking candidate |
.getNextCandidateNode(options?)
Returns the next candidate element with options
. The properties of options
are the same as .getNextCandidateIndex
.
.getNextCandidateValue(options?)
Returns the next candidate value with options
. The properties of options
are the same as .getNextCandidateIndex
.
.getNextCandidateInfo(options?)
Returns the object of next candidate info with options
. The properties of options
are the same as .getNextCandidateIndex
.
.flip(source?, options?)
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,
});
.flip(options?)
Flips to the defaul next candidate with the same options
as .flip
.
Events
Events for flip elements:
flipstart
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 |
flipend
Cancelable:
false
Dispatches on the end of switching candidate.
Properties of event.detail
is the same as flipstart.
flipcandidatestart
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 |
flipcandidateend
Cancelable:
false
Dispatchse on the end of flipping animation.
Properties of event.detail
is the same as flipcandidatestart.
License
Flip.js is MIT licensed.