123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import { render } from "./test-utils";
- import { API } from "./helpers/api";
- import { Excalidraw } from "../index";
- import { vi } from "vitest";
- const { h } = window;
- describe("fitToContent", () => {
- it("should zoom to fit the selected element", async () => {
- await render(<Excalidraw />);
- h.state.width = 10;
- h.state.height = 10;
- const rectElement = API.createElement({
- width: 50,
- height: 100,
- x: 50,
- y: 100,
- });
- expect(h.state.zoom.value).toBe(1);
- h.app.scrollToContent(rectElement, { fitToContent: true });
- // element is 10x taller than the viewport size,
- // zoom should be at least 1/10
- expect(h.state.zoom.value).toBeLessThanOrEqual(0.1);
- });
- it("should zoom to fit multiple elements", async () => {
- await render(<Excalidraw />);
- const topLeft = API.createElement({
- width: 20,
- height: 20,
- x: 0,
- y: 0,
- });
- const bottomRight = API.createElement({
- width: 20,
- height: 20,
- x: 80,
- y: 80,
- });
- h.state.width = 10;
- h.state.height = 10;
- expect(h.state.zoom.value).toBe(1);
- h.app.scrollToContent([topLeft, bottomRight], {
- fitToContent: true,
- });
- // elements take 100x100, which is 10x bigger than the viewport size,
- // zoom should be at least 1/10
- expect(h.state.zoom.value).toBeLessThanOrEqual(0.1);
- });
- it("should scroll the viewport to the selected element", async () => {
- await render(<Excalidraw />);
- h.state.width = 10;
- h.state.height = 10;
- const rectElement = API.createElement({
- width: 100,
- height: 100,
- x: 100,
- y: 100,
- });
- expect(h.state.zoom.value).toBe(1);
- expect(h.state.scrollX).toBe(0);
- expect(h.state.scrollY).toBe(0);
- h.app.scrollToContent(rectElement);
- // zoom level should stay the same
- expect(h.state.zoom.value).toBe(1);
- // state should reflect some scrolling
- expect(h.state.scrollX).not.toBe(0);
- expect(h.state.scrollY).not.toBe(0);
- });
- });
- const waitForNextAnimationFrame = () => {
- return new Promise((resolve) => {
- requestAnimationFrame(() => {
- requestAnimationFrame(resolve);
- });
- });
- };
- describe("fitToContent animated", () => {
- beforeEach(() => {
- vi.spyOn(window, "requestAnimationFrame");
- });
- afterEach(() => {
- vi.restoreAllMocks();
- });
- it("should ease scroll the viewport to the selected element", async () => {
- await render(<Excalidraw />);
- h.state.width = 10;
- h.state.height = 10;
- const rectElement = API.createElement({
- width: 100,
- height: 100,
- x: -100,
- y: -100,
- });
- h.app.scrollToContent(rectElement, { animate: true });
- expect(window.requestAnimationFrame).toHaveBeenCalled();
- // Since this is an animation, we expect values to change through time.
- // We'll verify that the scroll values change at 50ms and 100ms
- expect(h.state.scrollX).toBe(0);
- expect(h.state.scrollY).toBe(0);
- await waitForNextAnimationFrame();
- const prevScrollX = h.state.scrollX;
- const prevScrollY = h.state.scrollY;
- expect(h.state.scrollX).not.toBe(0);
- expect(h.state.scrollY).not.toBe(0);
- await waitForNextAnimationFrame();
- expect(h.state.scrollX).not.toBe(prevScrollX);
- expect(h.state.scrollY).not.toBe(prevScrollY);
- });
- it("should animate the scroll but not the zoom", async () => {
- await render(<Excalidraw />);
- h.state.width = 50;
- h.state.height = 50;
- const rectElement = API.createElement({
- width: 100,
- height: 100,
- x: 100,
- y: 100,
- });
- expect(h.state.scrollX).toBe(0);
- expect(h.state.scrollY).toBe(0);
- h.app.scrollToContent(rectElement, { animate: true, fitToContent: true });
- expect(window.requestAnimationFrame).toHaveBeenCalled();
- await waitForNextAnimationFrame();
- const prevScrollX = h.state.scrollX;
- const prevScrollY = h.state.scrollY;
- expect(h.state.scrollX).not.toBe(0);
- expect(h.state.scrollY).not.toBe(0);
- await waitForNextAnimationFrame();
- expect(h.state.scrollX).not.toBe(prevScrollX);
- expect(h.state.scrollY).not.toBe(prevScrollY);
- });
- });
|