伸缩框的设计(Semi design)

一、单个伸缩框的设计

1、设计步骤

        。从 @douyinfe/semi-ui 库中引入 Resizable 和 Toast 组件

        。定义函数组件

        。设计组件的 JSX 结构

        。导出组件

2、代码展示
// 从 @douyinfe/semi-ui 库中引入 Resizable 和 Toast 组件
import { Resizable, Toast } from '@douyinfe/semi-ui'; // 引入 Toast
// 从 react 库中引入 useState Hook
import { useState } from 'react';

/* 单个组件设计 */

// 定义一个名为 Single 的 React 函数组件
function Single() {
  // 使用 useState Hook 创建一个名为 text 的状态变量,并初始化为 '框的初始态'
  const [text, setText] = useState('框的初始态');

  // 定义 Toast 的配置选项 opts_1,用于 resize 开始时的提示
  const opts_1 = {
    content: '开始设置', // 提示内容
    duration: 1, // 提示显示时长(秒)
    stack: true, // 是否允许多个提示叠加显示
  };

  // 定义 Toast 的配置选项 opts_2,用于 resize 结束时的提示
  const opts_2 = {
    content: '设置结束', // 提示内容
    duration: 1, // 提示显示时长(秒)
    stack: true, // 是否允许多个提示叠加显示
  };

  // 返回组件的 JSX 结构
  return (
    <div style={
  
  { width: '500px', margin: '0 auto 0 70px' }}> {/*  外层容器*/}
      <Resizable // 使用 Resizable 组件
        style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)' }} // 设置 伸缩框 的背景颜色
        defaultSize={
  
  { // 设置 伸缩框 的默认大小
          width: '60%', // 宽度为父容器的 60%
          height: 300, // 高度为 300px
        }}
        onChange={() => { // 当 伸缩框 大小改变时触发的回调函数
          setText('开始设置尺寸'); // 将 text 状态更新为 '开始设置尺寸'
        }}
        onResizeStart={() => Toast.info(opts_1)} // 当 Resizable 开始调整大小时触发的回调函数,显示 opts_1 的提示
        onResizeEnd={() => { // 当 Resizable 调整大小结束时触发的回调函数
          Toast.info(opts_2); // 显示 opts_2 的提示
          setText('设置后框的尺寸'); // 将 text 状态更新为 '设置后框的尺寸'
        }}
      >
        <div style={
  
  { marginLeft: '20%' }}> {/*  内层容器,设置左边距为 20% */}
          {text} {/* 显示 text 状态的内容 */}
        </div>
      </Resizable>
    </div>
  );
}

// 导出 Single 组件,使其可以被其他文件导入使用
export default Single;
3、效果展示

 二、根据变化比例来设计伸缩框

        1、设计步骤和第一个伸缩框设计一样
        2、代码展示
import { Resizable } from '@douyinfe/semi-ui';

/* 单个按比例设计组件 */
function size() {
  // 返回一个包含可调整大小组件的 JSX 结构
  return (
    <div style={
  
  { width: '500px', height: '60%', margin: '0 auto 0 70px' }}>
      {/* 
        使用 Resizable 组件,允许用户调整其子元素的大小。
        属性说明:
        - style: 设置背景颜色为 rgba(var(--semi-grey-1), 1),使用 CSS 变量 --semi-grey-1 来定义颜色。
        - ratio: 设置宽高比为 2,即宽度是高度的两倍。
        - defaultSize: 设置初始尺寸,宽度为 200px,高度为 200px。
      */}
      <Resizable
        style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)' }}
        ratio={2}
        defaultSize={
  
  {
          width: 200,
          height: 200,
        }}
      >
        {/* 子元素,显示文本 "ratio=2",并设置左边距为 20% */}
        <div style={
  
  { marginLeft: '20%' }}>ratio=2</div>
      </Resizable>
    </div>
  );
}

// 导出 size 函数组件,使其可以在其他地方导入和使用
export default size;
        3、效果展示

 

 三、受控宽高(通过size的宽高来放大)

        1、代码展示
// 引入 React 的 useState 钩子,用于管理组件状态
import { useState } from 'react';
// 引入 Semi-UI 的 Resizable 和 Button 组件
import { Resizable, Button } from '@douyinfe/semi-ui';

// 定义 ControllerWidth 组件
function ControllerWidth() {
  // 使用 useState 初始化组件的尺寸状态,默认宽度为 200,高度为 100
  const [size, setSize] = useState({ width: 200, height: 100 });

  // 定义按钮点击事件处理函数
  const onButtonClick = () => {
    // 计算新的尺寸,宽度和高度各增加 10
    let realSize = { width: size.width + 10, height: size.height + 10 };
    // 更新状态,触发组件重新渲染
    setSize(realSize);
  };

  // 定义 Resizable 组件尺寸变化时的回调函数
  const onChange = (s) => {
    // 当用户拖动调整大小时,更新尺寸状态
    setSize(s);
  };

  // 返回组件的 JSX 结构
  return (
    // 外层容器,设置固定宽度和高度
    <div style={
  
  { width: '500px', height: '60%', margin: '0 auto 0 70px' }}>
      {/* 按钮组件,点击时触发 onButtonClick 函数 */}
      <Button onClick={onButtonClick}>set += 10</Button>

      {/* Resizable 组件,允许用户拖动调整大小 */}
      <Resizable
        // 设置 Resizable 组件的样式,背景色为 Semi-UI 的设计系统灰色
        style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)', marginTop: '10px' }}
        // 绑定当前尺寸状态
        size={size}
        // 绑定尺寸变化时的回调函数
        onChange={onChange}
      >
        {/* Resizable 组件的内容区域 */}
        <div style={
  
  { marginLeft: '20%' }}>
          增大
        </div>
      </Resizable>
    </div>
  );
}

// 导出 ControllerWidth 组件
export default ControllerWidth;
2、效果展示

 

四、嵌套伸缩框

        1、代码展示
// 引入 React 的 useState 钩子,用于管理组件状态
import { useState } from 'react';
// 引入 Semi-UI 的 ResizeItem、ResizeHandler 和 ResizeGroup 组件
import { ResizeItem, ResizeHandler, ResizeGroup } from '@douyinfe/semi-ui';

// 定义 Qiantao 组件
function Qiantao() {
  // 使用 useState 初始化文本状态,默认值为 'Drag to resize'
  const [text, setText] = useState('Drag to resize');

  // 返回组件的 JSX 结构
  return (
    // 外层容器,设置固定宽度和高度
    <div style={
  
  { width: '1000px', height: '600px', margin: '0 auto 0 70px' }}>
      {/* 外层垂直方向的 ResizeGroup */}
      <ResizeGroup direction="vertical">
        {/* 外层 ResizeItem,默认占父容器高度的 80% */}
        <ResizeItem defaultSize={'80%'}>
          {/* 内层水平方向的 ResizeGroup */}
          <ResizeGroup direction="horizontal">
            {/* 左侧 ResizeItem,默认占父容器宽度的 25%,最小 10%,最大 30% */}
            <ResizeItem
              style={
  
  {
                backgroundColor: 'rgba(var(--semi-grey-1), 1)', // 背景色为 Semi-UI 的设计系统灰色
                border: 'var(--semi-color-border) 1px solid', // 边框颜色为 Semi-UI 的设计系统边框色
              }}
              defaultSize={'25%'}
              min={'10%'}
              max={'30%'}
            >
              {/* 内容区域,显示当前文本和尺寸限制 */}
              <div style={
  
  { marginLeft: '20%' }}>{text + ' min:10% max:30%'}</div>
            </ResizeItem>

            {/* 水平方向的 ResizeHandler,用于调整左右 ResizeItem 的大小 */}
            <ResizeHandler />

            {/* 中间 ResizeItem,默认占父容器宽度的 50% */}
            <ResizeItem style={
  
  { border: 'var(--semi-color-border) 1px solid' }} defaultSize={'50%'}>
              {/* 内层垂直方向的 ResizeGroup */}
              <div style={
  
  { height: '100%' }}>
                <ResizeGroup direction="vertical">
                  {/* 上部 ResizeItem,默认占父容器高度的 33%,最小 10% */}
                  <ResizeItem
                    style={
  
  {
                      backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                      border: 'var(--semi-color-border) 1px solid',
                    }}
                    defaultSize={'33%'}
                    min={'10%'}
                    // 调整大小时更新文本状态
                    onChange={() => {
                      setText('resizing');
                    }}
                    // 调整结束时恢复文本状态
                    onResizeEnd={() => {
                      setText('Drag to resize');
                    }}
                  >
                    {/* 内容区域,显示当前文本和尺寸限制 */}
                    <div style={
  
  { marginLeft: '20%' }}>{text + ' min:10%'}</div>
                  </ResizeItem>

                  {/* 垂直方向的 ResizeHandler,用于调整上下 ResizeItem 的大小 */}
                  <ResizeHandler />

                  {/* 中部 ResizeItem,默认占父容器高度的 33%,最小 10%,最大 40% */}
                  <ResizeItem
                    style={
  
  {
                      backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                      border: 'var(--semi-color-border) 1px solid',
                    }}
                    defaultSize={'33%'}
                    min={'10%'}
                    max={'40%'}
                  >
                    {/* 内容区域,显示当前文本和尺寸限制 */}
                    <div style={
  
  { marginLeft: '20%' }}>{text + ' min:10% max:40%'}</div>
                  </ResizeItem>

                  {/* 垂直方向的 ResizeHandler,用于调整上下 ResizeItem 的大小 */}
                  <ResizeHandler />

                  {/* 下部 ResizeItem,无默认尺寸限制 */}
                  <ResizeItem
                    style={
  
  {
                      backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                      border: 'var(--semi-color-border) 1px solid',
                    }}
                  >
                    {/* 内容区域,显示当前文本 */}
                    <div style={
  
  { marginLeft: '20%' }}>{text}</div>
                  </ResizeItem>
                </ResizeGroup>
              </div>
            </ResizeItem>

            {/* 水平方向的 ResizeHandler,用于调整左右 ResizeItem 的大小 */}
            <ResizeHandler />

            {/* 右侧 ResizeItem,默认占父容器宽度的 1 单位,最大 30% */}
            <ResizeItem
              style={
  
  {
                backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                border: 'var(--semi-color-border) 1px solid',
              }}
              defaultSize={'1'}
              max={'30%'}
            >
              {/* 内容区域,显示当前文本和尺寸限制 */}
              <div style={
  
  { marginLeft: '20%' }}>{text + ' max:30%'}</div>
            </ResizeItem>
          </ResizeGroup>
        </ResizeItem>

        {/* 垂直方向的 ResizeHandler,用于调整上下 ResizeItem 的大小 */}
        <ResizeHandler />

        {/* 底部 ResizeItem,默认占父容器高度的 20% */}
        <ResizeItem
          defaultSize={'20%'}
          // 调整大小时更新文本状态
          onChange={() => {
            setText('resizing');
          }}
        >
          {/* 内层水平方向的 ResizeGroup */}
          <ResizeGroup direction="horizontal">
            {/* 左侧 ResizeItem,默认占父容器宽度的 50% */}
            <ResizeItem
              style={
  
  {
                backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                border: 'var(--semi-color-border) 1px solid',
              }}
              defaultSize={'50%'}
            >
              {/* 内容区域,显示文本 'tab' */}
              <div style={
  
  { marginLeft: '20%' }}>tab</div>
            </ResizeItem>

            {/* 水平方向的 ResizeHandler,用于调整左右 ResizeItem 的大小 */}
            <ResizeHandler />

            {/* 右侧 ResizeItem,默认占父容器宽度的 50% */}
            <ResizeItem
              style={
  
  {
                backgroundColor: 'rgba(var(--semi-grey-1), 1)',
                border: 'var(--semi-color-border) 1px solid',
              }}
              defaultSize={'50%'}
            >
              {/* 内容区域,显示文本 'content' */}
              <div style={
  
  { marginLeft: '20%' }}>content</div>
            </ResizeItem>
          </ResizeGroup>
        </ResizeItem>
      </ResizeGroup>
    </div>
  );
}

// 导出 Qiantao 组件
export default Qiantao;
        2、效果展示(按照里面固定的比例可以灵活的拉动边框)

五、动态伸缩框 

        1、代码展示
// 引入 React 的 useState 钩子,用于管理组件状态
import { useState } from 'react';
// 引入 Semi-UI 的 ResizeItem、ResizeHandler、ResizeGroup 和 Button 组件
import { ResizeItem, ResizeHandler, ResizeGroup, Button } from '@douyinfe/semi-ui';

// 定义 Dongtai 组件
function Dongtai() {
  // 使用 useState 初始化文本状态,默认值为 'drag to resize'
  const [text, setText] = useState('drag to resize');
  // 使用 useState 初始化方向状态,默认值为 'horizontal'(水平方向)
  const [direction, setDirection] = useState('horizontal');

  // 定义切换方向的函数
  const changeDirection = () => {
    // 切换方向:如果当前是水平方向,则改为垂直方向,反之亦然
    setDirection((prev) => (prev === 'horizontal' ? 'vertical' : 'horizontal'));
  };

  // 定义调整大小时的回调函数
  const handleResize = (isResizing) => {
    // 根据是否正在调整大小,更新文本状态
    setText(isResizing ? 'resizing' : 'drag to resize');
  };

  // 返回组件的 JSX 结构
  return (
    // 外层容器,设置固定宽度和高度
    <div style={
  
  { width: '400px', height: '300px' }}>
      {/* 按钮组件,点击时切换方向 */}
      <Button onClick={changeDirection}>{direction}</Button>

      {/* ResizeGroup 组件,根据 direction 状态设置方向 */}
      <ResizeGroup direction={direction}>
        {/* 第一个 ResizeItem,默认占父容器尺寸的 50% */}
        <ResizeItem
          // 调整大小时触发回调函数
          onChange={() => handleResize(true)}
          // 调整结束时触发回调函数
          onResizeEnd={() => handleResize(false)}
          // 设置默认尺寸为父容器的 50%
          defaultSize="50%"
        >
          {/* 内层水平方向的 ResizeGroup */}
          <ResizeGroup direction="horizontal">
            {/* 左侧 ResizeItem */}
            <ResizeItem
              // 设置背景色为 Semi-UI 的设计系统灰色
              style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)' }}
              // 调整大小时触发回调函数
              onChange={() => handleResize(true)}
              // 调整结束时触发回调函数
              onResizeEnd={() => handleResize(false)}
            >
              {/* 内容区域,显示当前文本 */}
              <div style={
  
  { marginLeft: '20%', padding: '5px' }}>{text}</div>
            </ResizeItem>

            {/* ResizeHandler,用于调整左右 ResizeItem 的大小 */}
            <ResizeHandler style={
  
  { backgroundColor: 'var(--semi-color-border)' }} />

            {/* 右侧 ResizeItem */}
            <ResizeItem
              // 设置背景色为 Semi-UI 的设计系统灰色
              style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)' }}
              // 调整大小时触发回调函数
              onChange={() => handleResize(true)}
            >
              {/* 内容区域,显示当前文本 */}
              <div style={
  
  { marginLeft: '20%', padding: '5px' }}>{text}</div>
            </ResizeItem>
          </ResizeGroup>
        </ResizeItem>

        {/* ResizeHandler,用于调整上下 ResizeItem 的大小 */}
        <ResizeHandler style={
  
  { backgroundColor: 'var(--semi-color-border)' }} />

        {/* 第二个 ResizeItem,默认占父容器尺寸的 30% */}
        <ResizeItem
          // 设置背景色为 Semi-UI 的设计系统灰色
          style={
  
  { backgroundColor: 'rgba(var(--semi-grey-1), 1)' }}
          // 设置默认尺寸为父容器的 30%
          defaultSize="30%"
          // 调整大小时触发回调函数
          onChange={() => handleResize(true)}
        >
          {/* 内容区域,显示当前文本 */}
          <div style={
  
  { marginLeft: '20%', padding: '5px' }}>{text}</div>
        </ResizeItem>
      </ResizeGroup>
    </div>
  );
}

// 导出 Dongtai 组件
export default Dongtai;
        2、效果展示(在框内可以随意的改变小框的大小)

 

六、区别 

1. Single 组件

  • 功能:实现了一个简单的可调整大小的框,并在调整过程中通过 Toast 提示用户操作状态。

  • 交互:在调整大小开始时显示“开始设置”的提示,结束时显示“设置结束”的提示,同时更新框内的文本内容。

2. size 组件

  • 功能:实现了一个按比例调整大小的伸缩框,宽度是高度的两倍。

  • 交互:用户只能按比例调整框的大小,无法单独调整宽度或高度。

  • 设计原因

    • 比例控制:通过 ratio 属性固定宽高比,适用于需要保持特定比例的布局场景,如图片或视频的展示。

    • 简洁性:组件设计简单,适合不需要复杂交互的场景,用户只需拖动即可按比例调整大小。

3. ControllerWidth 组件

  • 功能:通过按钮控制伸缩框的大小,每次点击按钮,框的宽度和高度各增加 10px。

  • 交互:用户可以通过按钮或直接拖动来调整框的大小。

  • 设计原因

    • 动态控制:通过按钮动态调整框的大小,适合需要精确控制尺寸的场景。

    • 双重交互:既支持手动拖动调整,也支持通过按钮调整,提供更灵活的操作方式。

    • 状态管理:使用 useState 管理尺寸状态,确保组件状态的实时更新和同步。

4. Qiantao 组件

  • 功能:实现了一个复杂的嵌套伸缩框布局,包含多个水平和垂直方向的伸缩区域。

  • 交互:用户可以在多个方向上调整各个区域的大小,且每个区域有最小和最大尺寸限制。

  • 设计原因

    • 复杂布局:适用于需要多区域、多方向调整的复杂布局场景,如仪表盘或编辑器界面。

    • 尺寸限制:通过 min 和 max 属性限制每个区域的最小和最大尺寸,确保布局的合理性和可用性。

    • 动态反馈:在调整过程中实时更新文本内容,提供操作反馈,增强用户体验。

5. Dongtai 组件

  • 功能:实现了一个动态切换方向的伸缩框布局,用户可以通过按钮切换水平或垂直方向。

  • 交互:用户可以在不同方向上调整框的大小,且调整过程中有实时反馈。

  • 设计原因

    • 方向切换:通过按钮动态切换布局方向,适合需要灵活调整布局方向的场景,如响应式设计。

    • 实时反馈:在调整过程中实时更新文本内容,帮助用户理解当前操作状态。

    • 灵活性:支持水平和垂直两种布局方向,提供更灵活的布局选择,适应不同的使用场景。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值