• [XState] Drag and Drop example (data-state, attr in css)


    import { createMachine, assign, interpret } from "xstate";
    
    const elBox = document.querySelector("#box");
    const elBody = document.body;
    
    const assignPoint = assign({
      px: (context, event) => event.clientX,
      py: (context, event) => event.clientY,
    });
    
    const assignPosition = assign({
      x: (context, event) => {
        return context.x + context.dx;
      },
      y: (context, event) => {
        return context.y + context.dy;
      },
      dx: 0,
      dy: 0,
      px: 0,
      py: 0,
    });
    
    const assignDelta = assign({
      dx: (context, event) => {
        return event.clientX - context.px;
      },
      dy: (context, event) => {
        return event.clientY - context.py;
      },
    });
    
    const showDelta = (context) => {
      elBox.dataset.delta = `delta: ${context.dx}, ${context.dy}`;
    };
    
    const resetPosition = assign({
      dx: 0,
      dy: 0,
      px: 0,
      py: 0,
    });
    
    const machine = createMachine({
      initial: "idle",
      context: {
        x: 0,
        y: 0,
        dx: 0,
        dy: 0,
        px: 0,
        py: 0,
      },
      states: {
        idle: {
          on: {
            mousedown: {
              actions: assignPoint,
              target: "dragging",
            },
          },
        },
        dragging: {
          on: {
            mousemove: {
              actions: [assignDelta, showDelta],
              // no target!
            },
            mouseup: {
              actions: assignPosition,
              target: "idle",
            },
          },
        },
      },
    });
    
    const service = interpret(machine);
    
    service.onTransition((state) => {
      if (state.changed) {
        console.log(state.context);
    
        elBox.dataset.state = state.value;
    
        elBox.style.setProperty("--dx", state.context.dx);
        elBox.style.setProperty("--dy", state.context.dy);
        elBox.style.setProperty("--x", state.context.x);
        elBox.style.setProperty("--y", state.context.y);
      }
    });
    
    service.start();
    
    elBox.addEventListener("mousedown", (event) => {
      service.send(event);
    });
    
    elBody.addEventListener("mousemove", (event) => {
      service.send(event);
    });
    
    elBody.addEventListener("mouseup", (event) => {
      service.send(event);
    });

    Css:

    It uses many [data-state] selector

    #box[data-state^='dragging'] {
      opacity: 0.8;
      box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.4);
    }
    
    #box[data-state='idle'] {
      transition: all 0.3s ease-in-out;
    }
    
    @import '../../styles/index.scss';
    
    
    #box {
      opacity: 0.5;
    
      &[data-state='active'] {
        opacity: 1;
      }
    
      &:before {
        content: attr(data-delta);
        position: absolute;
        bottom: 100%;
        margin-bottom: 0.5rem;
        left: 0;
        background: black;
        padding: 0.25rem;
        color: white;
        font-family: monospace;
        border-radius: inherit;
        white-space: nowrap;
      }
    }
  • 相关阅读:
    web service
    常用的正则表达式
    xml
    sql helper
    sql server 表连接
    asp.net页面生命周期
    创建简单的ajax对象
    checkbox选中问题
    ES6之扩展运算符 三个点(...)
    Object.assign()的用法 -- 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,返回目标对象
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13356804.html
Copyright © 2020-2023  润新知