naughty-button

by shan10213223

HTML

<div class="form-container">
<form action="#" method="GET" class="example-form">
  <div class="form-item username">
    <label for="username">Username</label>
    <input type="text" name="username" id="username" />
  </div>
  <div class="form-item password">
    <label for="password">Password</label>
    <input type="password" name="password" id="password" />
  </div>
  <div class="form-item submit-box">
  <button type="button" value="placeholder" class="placeholder-btn" disabled></button>
  <button type="submit" value="submit" class="submit-btn" disabled>Submit</button>
  </div>
</form>
</div>

CSS

.form-container {
  height: 200px;
  border: 1px solid #CCE3DE;
  font-size: 14px;
  color: #3C3C43;
  font-family: "Noto Sans TC", Inter, "ui-sa";
}

.example-form {
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.form-item {
  margin: 5px 0;
}
input {
  border-radius: 10px;
  border: 1px solid #888888;
}
.submit-box {
  position: relative;
}
.submit-btn, .placeholder-btn {
  padding: 8px 12px;
  border-radius: 20px;
  width: 84px;
  height: 36px;
}
.placeholder-btn {
  border: 1px dotted grey;
  background-color: transparent;
}
.submit-btn {
  background-color: #f4a261;
  color: #ffffff;
  border: none;
  cursor: pointer;
  position: absolute;
  left: 0;
  transition: all var(--move-duration) var(--move-easing);
  will-change: transform;
  transform: translate(var(--x-move, 0), var(--y-move, 0));
}
.submit-btn.moving {
  cursor: not-allowed;
  animation: jellyBounce var(--move-duration) var(--move-easing);
  transform: scale(1)
}

@keyframes jellyBounce {
  0%, 100% {
    transform: scale(1) translate(var(--x-move), var(--y-move));
  }
  50% {
    transform: scale(1.2, .8) translate(var(--x-move), var(--y-move));
  }
  80% {
    transform: scale(.9, 1.1) translate(var(--x-move), var(--y-move));
  }
}

JavaScript

// Configuration
const CONFIG = {
  movement: {
    baseX: 84,
    baseY: 36,
    animationDuration: 600
  },
  cssProperties: {
    buttonMovement: {
      xMove: '--x-move',
      yMove: '--y-move'
    },
    animation: {
      duration: '--move-duration',
      easing: '--move-easing'
    }
  }
};

// Form state
const formState = {
  username: '',
  password: '',
  isReadyToSubmit: false
};

// DOM Elements
const elements = {
  form: document.querySelector('.example-form'),
  username: document.querySelector('.username'),
  password: document.querySelector('.password'),
  submitBtn: document.querySelector('.submit-btn')
};

function initializeCSSProperties() {
  const { submitBtn } = elements;
  const { buttonMovement, animation } = CONFIG.cssProperties;
  
  // Initialize movement properties
  submitBtn.style.setProperty(buttonMovement.xMove, '0px');
  submitBtn.style.setProperty(buttonMovement.yMove, '0px');
  
  // Initialize animation properties
  submitBtn.style.setProperty(animation.duration, `${CONFIG.movement.animationDuration}ms`);
  submitBtn.style.setProperty(animation.easing, 'cubic-bezier(0.04, 0.43, 0.025, 1.07)');
}

function handleFormInput(event) {
  const target = event.target;
  if (!target.name) return;
  
  updateFormState(target);
  updateButtonState();
}

function updateFormState(inputElement) {
  const validInputNames = Object.keys(formState).filter(key => key !== 'isReadyToSubmit');
  if (!validInputNames.includes(inputElement.name)) return;

  formState[inputElement.name] = inputElement.value;
  formState.isReadyToSubmit = formState.username && formState.password;
}

function updateButtonState() {
  const { submitBtn } = elements;
  
  // Update disabled state
  submitBtn.disabled = !formState.isReadyToSubmit;
  
  // Update position/animation state
  if (formState.isReadyToSubmit) {
    resetButtonPosition();
  } else {
    resetButtonPosition(true);
 ...