Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
wikiphp

Resize element in X axis with specific measures as defined columns

Go to solution Solved by GreenSock,

Recommended Posts

Hi.

I have a resizable and draggable element that I want to resize width of that container in X axis for predefined columns. I mean user just can resize width of element until feeling a column from #1 to #12.

 

In tne uploaded image row container filled column #2 to #7.

 

It's my code and for my purpose I need your help.

 

import React, { FC, useContext, useEffect } from 'react';

import gsap from 'gsap';
import { Draggable } from 'gsap/dist/Draggable';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';

import { layoutDndGroupName } from '$components/pageLayouts/LayoutModal';
import { LayoutContext } from '$components/pageLayouts/LayoutModal/LayoutContext';
import { Header } from '$components/shared';
import { DragAndDropZones } from '$components/shared/modules/DragAndDrop';
import { getDnDId } from '$lib/utils';

const PlaygroundContainer = styled.div`
  width: 100%;
  height: 200px;
  position: relative;
  overflow: visible;
  background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
  background-position: -1px -1px, -1px -1px, -1px -1px, -1px -1px;
  background-image: linear-gradient(rgba(0, 0, 0, 0.3) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 0, 0, 0.3) 1px, transparent 1px),
    linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
`;

export const Playground: FC = () => {
  const { t } = useTranslation();
  const { playgroundFields } = useContext(LayoutContext);

  const clamp = (value, min, max) => (value < min ? min : value > max ? max : value);

  const createResizable = (draggableRowElement) => {
    const dropzoneContainer = document.querySelector(
      `[data-zone-id="${DragAndDropZones.dropZone}-${layoutDndGroupName}"]`,
    ) as HTMLElement;

    const handle = document.createElement('div');
    handle.className = 'resize-handle';
    draggableRowElement.appendChild(handle);

    const draggableElementRect = draggableRowElement.getBoundingClientRect();

    gsap.set(handle, { x: draggableElementRect.width, y: draggableElementRect.height });

    const rect2 = handle.getBoundingClientRect();

    const offset = {
      x1: rect2.left - draggableElementRect.right,
      y1: rect2.top - draggableElementRect.bottom,
      x2: rect2.right - draggableElementRect.right,
      y2: rect2.bottom - draggableElementRect.bottom,
    };

    Draggable.create(draggableRowElement, {
      bounds: dropzoneContainer,
      autoScroll: 1,
      type: 'x',
    });

    Draggable.create(handle, {
      bounds: dropzoneContainer,
      autoScroll: 1,
      type: 'x',
      onPress(e) {
        e.stopPropagation();
      },
      onDrag() {
        gsap.set(draggableRowElement, { width: this.x + 0, height: this.y + 0 });
      },
      liveSnap: {
        x: (x) => clamp(x, -offset.x1, x + offset.x2),
        y: (y) => clamp(y, -offset.y1, y + offset.y2),
      },
    });
  };

  useEffect(() => {
    const draggableRowsContainer = document.querySelectorAll('.rowContainer');
    for (const draggableRowElement of draggableRowsContainer) {
      createResizable(draggableRowElement);
    }
  }, [playgroundFields]);

  return (
    <>
      <Header
        title={t('Playground')}
        subtitle={t('You can resize any section by select corners')}
      />

      <PlaygroundContainer data-zone-id={getDnDId('dropZone', layoutDndGroupName)}>
        {playgroundFields.map((field) => {
          return field.element;
        })}
      </PlaygroundContainer>
    </>
  );
};

export default Playground;

 

image.thumb.png.e1c048b584ecb0d7e6a4da2160936ac9.png

See the Pen by s (@s) on CodePen

Link to comment
Share on other sites

  • wikiphp changed the title to Resize element in X axis with specific measures as defined columns

Hi there wikiPhp - We can usually help more effectively if you provide a minimal demo, codepen is great for this.
 

Link to comment
Share on other sites

  • Solution

I'm not sure I really understand what you're asking here, but maybe you just need to adjust your liveSnap x value like:

liveSnap: {x: (value) => gsap.utils.snap(100, value)},

And do that for your draggableRowElement Draggable too. 

  • Like 2
Link to comment
Share on other sites

4 hours ago, GreenSock said:

I'm not sure I really understand what you're asking here, but maybe you just need to adjust your liveSnap x value like:

liveSnap: {x: (value) => gsap.utils.snap(100, value)},

And do that for your draggableRowElement Draggable too. 

It's exactly what I wanted. Thank you

It affect suddenly between columns but has gsap any animation for increase or decrease row width smoothly?

Link to comment
Share on other sites

13 hours ago, wikiphp said:

It affect suddenly between columns but has gsap any animation for increase or decrease row width smoothly?

No, there's not an automatic setting for that. But you can do almost anything with custom logic and GSAP. We don't have the bandwidth to build that for you for free, though. You'd need to craft that logic on your own or hire someone to do it for you. 

 

Good luck!

  • Like 1
Link to comment
Share on other sites

Just one quick [untested] idea: 

liveSnap: {x: (value) => {
  // animate to the snapped value
  gsap.to(target, {x: gsap.utils.snap(100, value), duration: 0.3, overwrite: true});
  // but return the unsnapped value
  return value;
}},

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×