Skip to content

Commit

Permalink
fix: recalculate camera offset (#886)
Browse files Browse the repository at this point in the history
* fix: recalculate camera offset

* test: fix remove only

* fix: fix adaptive height

* fix: fix react firstPanelSize attr
  • Loading branch information
daybrush authored Sep 5, 2024
1 parent c83fc5e commit 3b18491
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/react-flicking/src/react-flicking/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const DEFAULT_PROPS: FlickingProps = {
viewportTag: "div",
cameraTag: "div",
cameraClass: "",
firstPanelSize: "",
renderOnSameKey: false,
plugins: [],
useFindDOMNode: false,
Expand Down
28 changes: 24 additions & 4 deletions src/camera/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Camera {
private _mode: CameraMode;
private _el: HTMLElement;
private _transform: string;
private _lookedOffset = 0;
private _position: number;
private _alignPos: number;
private _offset: number;
Expand Down Expand Up @@ -292,6 +293,8 @@ class Camera {
* @return {this}
*/
public lookAt(pos: number): void {
const prevOffset = this._offset;
const isChangedOffset = this._lookedOffset !== prevOffset;
const flicking = getFlickingAttached(this._flicking);
const prevPos = this._position;

Expand All @@ -304,7 +307,12 @@ class Camera {
if (toggled) {
void flicking.renderer.render().then(() => {
this.updateOffset();
this._lookedOffset = this._offset;
});
} else if (isChangedOffset) {
// sync offset for renderOnlyVisible on resize
this.updateOffset();
this._lookedOffset = this._offset;
} else {
this.applyTransform();
}
Expand Down Expand Up @@ -502,8 +510,8 @@ class Camera {
}

/**
* Update Viewport's height to active panel's height
* @ko 현재 선택된 패널의 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
* Update Viewport's height to visible panel's max height
* @ko 현재 활성화된 패널과 보이는 패널의 최대 높이와 동일하도록 뷰포트의 높이를 업데이트합니다
* @throws {FlickingError}
* {@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} When {@link Camera#init init} is not called before
* <ko>{@link ERROR_CODE NOT_ATTACHED_TO_FLICKING} {@link Camera#init init}이 이전에 호출되지 않은 경우</ko>
Expand All @@ -513,11 +521,22 @@ class Camera {
public updateAdaptiveHeight() {
const flicking = getFlickingAttached(this._flicking);
const activePanel = flicking.control.activePanel;
const visiblePanels = flicking.visiblePanels;

const selectedPanels = [...visiblePanels];

if (activePanel) {
selectedPanels.push(activePanel);
}

if (!flicking.horizontal || !flicking.adaptive || !selectedPanels.length) return;


const maxHeight = Math.max(...selectedPanels.map(panel => panel.height));

if (!flicking.horizontal || !flicking.adaptive || !activePanel) return;

flicking.viewport.setSize({
height: activePanel.height
height: maxHeight
});
}

Expand Down Expand Up @@ -599,6 +618,7 @@ class Camera {

private _resetInternalValues() {
this._position = 0;
this._lookedOffset = 0;
this._alignPos = 0;
this._offset = 0;
this._circularOffset = 0;
Expand Down
35 changes: 35 additions & 0 deletions test/unit/Flicking.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,7 @@ describe("Flicking", () => {
expect(flicking.panels.map(panel => panel.rendered))
.to.deep.equal([true, true, false, false, true]);
});

});

describe("Events", () => {
Expand Down Expand Up @@ -1359,6 +1360,40 @@ describe("Flicking", () => {
expect(event.height).to.equal(viewportSize.height);
});

it("should have correct offset on extream resize", async () => {
const viewportSize = {
width: 400,
height: 800
};

const flicking = await createFlicking(
El.viewport().setWidth(viewportSize.width).setHeight(viewportSize.height).add(
El.camera().add(
El.panel().setWidth("100%").setHeight(800),
El.panel().setWidth("100%").setHeight(800),
El.panel().setWidth("100%").setHeight(800),
El.panel().setWidth("100%").setHeight(800),
El.panel().setWidth("100%").setHeight(800)
)
),
{ renderOnlyVisible: true, defaultIndex: 3, horizontal: false }
);

const prevOffset = flicking.camera.offset;

// resize 1/4 height
flicking.panels.forEach(panel => {
panel.element.style.height = "200px";
});
flicking.element.style.height = "200px";

await flicking.resize();

// 800 * 3 2400 => 200 * 3 600
expect(prevOffset).to.be.equals(2400);
expect(flicking.camera.offset).to.be.equals(600);
});

it("should have size 0 on initialization", async () => {
const flicking = await createFlicking(El.DEFAULT_HORIZONTAL, { autoInit: false, preventEventsBeforeInit: false });
const resizeSpy = sinon.spy();
Expand Down

0 comments on commit 3b18491

Please sign in to comment.