Quick Start
- JavaScript
- React
- Vue@2
- Vue@3
- Angular
- Preact
- Svelte
Add the script/CSS to the page.
<script src="https://unpkg.com/@egjs/flicking/dist/flicking.pkgd.min.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://unpkg.com/@egjs/flicking/dist/flicking.css" crossorigin="anonymous" />
Or, you can rather import them if you're using a bundler like webpack or rollup.
import Flicking from "@egjs/flicking";
import "@egjs/flicking/dist/flicking.css";
Then, add some basic HTML layout of Flicking to your page.
<!-- Viewport element -->
<div id="carousel" class="flicking-viewport">
<!-- Camera element -->
<div class="flicking-camera">
<!-- Panels, class names are your choice -->
<div class="panel"></div>
<div class="panel"></div>
<div class="panel"></div>
</div>
</div>
You should add the vertical
class to viewport element, if you're making a vertical carousel.
<div class="flicking-viewport vertical">
Then initialize Flicking instance with JavaScript after.
const flicking = new Flicking("#carousel", {
align: "center",
circular: true,
bound: true,
renderOnlyVisible: true
});
You can import & use Flicking as a React Component.
import Flicking from "@egjs/react-flicking";
import "@egjs/react-flicking/dist/flicking.css";
// Or, if you have to support IE9
import "@egjs/react-flicking/dist/flicking-inline.css";
export default () => (
<Flicking
align="prev"
circular={true}
onMoveEnd={e => {
console.log(e);
}}>
<div className="panel">1</div>
<div className="panel">2</div>
<div className="panel">3</div>
</Flicking>
)
React exclusive options
- viewportTag: HTML tag for
.flicking-viewport
element. (default: "div") - cameraTag: HTML tag for
.flicking-camera
element. (default: "div") - cameraClass:
className
for.flicking-camera
element. (default: "") - renderOnSameKey: Whether to always render children even they have the same keys (default: false)
- Flicking doesn't rerender when children have same length & keys for performance by default.
- If you have to bypass this behavior, like when you have to update panel's innerHTML without changing the list of child elements, you can either set this option to
true
, or you can call Flicking component'sforceUpdate()
.
Using the components as a panel
If you're using the React Component as a panel, it should use a ref forwarding
<Flicking>
<Panel index={1} />
<Panel index={2} />
<Panel index={3} />
</Flicking>
// If you're using a functional component
export default React.forwardRef(({ index }, ref) => (<div ref={ref}>{ index + 1 }</div>));
// Or... if you're using a class-based React component
class Panel extends React.Component {
public render() {
return <div ref={this.props.elRef}>{ index + 1 }</div>;
}
}
export default React.forwardRef((props, ref) => <Panel elRef={ref} {...props} />);
You can't use a React component that renders multiple elements
<Flicking>
<Panels /> // This won't work
</Flicking>
const Panels = () => <>
<div key={0}>0</div>
<div key={1}>1</div>
<div key={2}>2</div>
</>;
Bypassing ref forwarding
If you don't like this behavior, there's a few ways to avoid it.
The easiest way is wrapping each Panel
component with another element tag.
<Flicking>
<div><Panel index={1} /></div>
<div><Panel index={2} /></div>
<div><Panel index={3} /></div>
</Flicking>
Or, you can use the useFindDOMNode
option of Flicking.
<Flicking useFindDOMNode={true}>
<Panel index={1} />
<Panel index={2} />
<Panel index={3} />
</Flicking>
Flicking will use findDOMNode instead of using refs when the useFindDOMNode
option is enabled.
So, if you're using the Strict Mode, Flicking can show warning about deprecated findDOMNode usage at the developer console.
And also, be aware that the component should always return a single DOM that never changes.
Therefore findDOMNode only worked if components always return a single DOM node that never changes.
You can register Flicking either locally...
import { Flicking } from "@egjs/vue-flicking";
export default {
components: {
Flicking: Flicking
}
}
@import url("node_modules/@egjs/vue-flicking/dist/flicking.css");
// Or, if you have to support IE9
@import url("node_modules/@egjs/vue-flicking/dist/flicking-inline.css");
or globally.
import Flicking from "@egjs/vue-flicking";
import "@egjs/vue-flicking/dist/flicking.css";
// Or, if you have to support IE9
import "@egjs/vue-flicking/dist/flicking-inline.css";
Vue.use(Flicking);
Then use Flicking like the other Vue components.
<Flicking :options="{ align: 'prev', circular: true }" @move-end="onMoveEnd">
<div class="panel">1</div>
<div class="panel">2</div>
<div class="panel">3</div>
</Flicking>
You can register Flicking either locally...
import Flicking from "@egjs/vue3-flicking";
export default {
components: {
Flicking: Flicking
}
}
@import url("node_modules/@egjs/vue3-flicking/dist/flicking.css");
// Or, if you have to support IE9
@import url("node_modules/@egjs/vue3-flicking/dist/flicking-inline.css");
or globally.
import { createApp } from "vue"
import App from "./App.vue"
import Flicking from "../dist/flicking.esm";
import "@egjs/vue3-flicking/dist/flicking.css";
// Or, if you have to support IE9
import "@egjs/vue3-flicking/dist/flicking-inline.css";
const app = createApp(App);
app.component("Flicking", Flicking);
app.mount("#app");
Then use Flicking like the other Vue components.
<Flicking :options="{ align: 'prev', circular: true }" @move-end="onMoveEnd">
<div class="panel">1</div>
<div class="panel">2</div>
<div class="panel">3</div>
</Flicking>
You can't use a Vue component that uses fragments(a.k.a. multi-root node components) as a panel
<Flicking>
<Panels /> // This won't work
</Flicking>
<template>
<div :key="0">0</div>
<div :key="1">1</div>
<div :key="2">2</div>
</template>
You can add NgxFlickingModule
at imports
of your app module to use Flicking.
import { NgxFlickingModule } from '@egjs/ngx-flicking';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgxFlickingModule /* Add in imports */
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { } /* Your app */
Now you can use the component ngx-flicking
and the directive flicking-panel
in your templates.
You should add directive flicking-panel
to the panel elements you use
<ngx-flicking
[options]="{ circular: true, duration: 500 }"
[plugins]="plugins"
(needPanel)="onNeedPanel($event)"
(moveEnd)="onMoveEnd($event)"
>
<div flicking-panel class="panel">
<img src="https://naver.github.io/egjs-flicking/images/bg01.jpg" />
</div>
<div flicking-panel class="panel">
<img src="https://naver.github.io/egjs-flicking/images/bg02.jpg" />
</div>
<div flicking-panel class="panel">
<img src="https://naver.github.io/egjs-flicking/images/bg03.jpg" />
</div>
</ngx-flicking>
You can import & use Flicking as a Preact Component.
import Flicking from "@egjs/preact-flicking";
import "@egjs/preact-flicking/dist/flicking.css";
// Or, if you have to support IE9
import "@egjs/preact-flicking/dist/flicking-inline.css";
export default () => (
<Flicking
align="prev"
circular={true}
onMoveEnd={e => {
console.log(e);
}}>
<div className="panel">1</div>
<div className="panel">2</div>
<div className="panel">3</div>
</Flicking>
)
Using the components as a panel
If you're using the React Component as a panel, it should use a ref forwarding
<Flicking>
<Panel index={1} />
<Panel index={2} />
<Panel index={3} />
</Flicking>
// If you're using a functional component
export default React.forwardRef(({ index }, ref) => (<div ref={ref}>{ index + 1 }</div>));
// Or... if you're using a class-based React component
class Panel extends React.Component {
public render() {
return <div ref={this.props.elRef}>{ index + 1 }</div>;
}
}
export default React.forwardRef((props, ref) => <Panel elRef={ref} {...props} />);
You can't use a React component that renders multiple elements
<Flicking>
<Panels /> // This won't work
</Flicking>
const Panels = () => <>
<div key={0}>0</div>
<div key={1}>1</div>
<div key={2}>2</div>
</>;
Bypassing ref forwarding
If you don't like this behavior, there's a few ways to avoid it.
The easiest way is wrapping each Panel
component with another element tag.
<Flicking>
<div><Panel index={1} /></div>
<div><Panel index={2} /></div>
<div><Panel index={3} /></div>
</Flicking>
Or, you can use the useFindDOMNode
option of Flicking.
<Flicking useFindDOMNode={true}>
<Panel index={1} />
<Panel index={2} />
<Panel index={3} />
</Flicking>
Flicking will use findDOMNode instead of using refs when the useFindDOMNode
option is enabled.
So, if you're using the Strict Mode, Flicking can show warning about deprecated findDOMNode usage at the developer console.
And also, be aware that the component should always return a single DOM that never changes.
Therefore findDOMNode only worked if components always return a single DOM node that never changes.
You can import Flicking
and FlickingPanel
from the "@egjs/svelte-flicking" package.
<script lang="ts">
import Flicking, { FlickingPanel } from "@egjs/svelte-flicking";
import "@egjs/svelte-flicking/dist/flicking.css";
// Or, if you have to support IE9
import "@egjs/svelte-flicking/dist/flicking-inline.css";
</script>
<Flicking options={{ align: "center", circular: true }}>
<!-- Those will render "div" element -->
<FlickingPanel>0</FlickingPanel>
<FlickingPanel>1</FlickingPanel>
<FlickingPanel>2</FlickingPanel>
</Flicking>