PC 및 IT관련.

커서 실패기) 윈도우 URL 클리퍼 + 씹덕 디스플레이 윈도우 위젯

ジーエムクン지하블로그 2026. 3. 17. 06:27

딱 여기서 구현이 멈췃다. ㅋㅋㅎ;;

 

 

 

UI 디자인 초안 코드

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>윈도우 주소 아카이브 – 플로팅 UI 시안 v1.1</title>
<style>
  html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    background: radial-gradient(circle at 20% 20%, #f5f7ff 0, #e3e6f3 30%, #d4d8eb 55%, #c4c9dd 80%);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
    color: #111827;
  }

  .preview-wrap {
    display: flex;
    gap: 80px;
    padding: 40px 60px;
    backdrop-filter: blur(26px);
  }

  .master-frame {
    position: relative;
    width: 420px;
    height: 520px;
  }

  .frame-label {
    position: absolute;
    top: -32px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 13px;
    letter-spacing: 0.05em;
    color: rgba(15, 23, 42, 0.7);
  }

  /* 공통: 둥근 사각형 컨테이너 */
  .floating-shell,
  .popup-shell,
  .card,
  .mini-floating-preview,
  .mini-popup-header,
  .mini-popup-body {
    border-radius: 26px;
    border: none;
    overflow: hidden;
  }

  .window-controls {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .dot {
    width: 12px;
    height: 12px;
    border-radius: 999px;
    box-shadow: 0 0 0 2px rgba(15, 23, 42, 0.05);
  }

  .dot-red    { background: #ff5f57; }
  .dot-yellow { background: #ffbd2e; }

  /* ===== 아이콘 버튼(설정/사운드 공통) ===== */
  .icon-pill {
    height: 24px;
    padding: 0 12px;
    border-radius: 999px;
    background: rgba(15, 23, 42, 0.04);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 11px;
    color: rgba(15, 23, 42, 0.68);
    backdrop-filter: blur(14px);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.7);
    cursor: pointer;
    user-select: none;
    transition:
      background 160ms ease-out,
      transform 120ms ease-out,
      box-shadow 160ms ease-out,
      color 160ms ease-out;
  }

  .icon-pill-icon {
    font-size: 13px;
    line-height: 1;
  }

  .icon-pill-label {
    letter-spacing: 0.02em;
  }

  .icon-pill:active {
    transform: translateY(1px) scale(0.97);
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.9),
      0 1px 0 rgba(15,23,42,0.05);
  }

  /* 사운드 ON 상태 */
  .icon-pill.sound-on {
    background: rgba(56, 189, 248, 0.22);
    color: rgba(15, 23, 42, 0.95);
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.95),
      0 6px 14px rgba(56,189,248,0.45);
  }

  /* ===== 플로팅 위젯 (Idle) ===== */
  .floating-shell {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 260px;
    height: 260px;
    background: radial-gradient(circle at 20% 0, rgba(255,255,255,0.85), rgba(255,255,255,0.55));
    box-shadow:
      0 24px 60px rgba(15, 23, 42, 0.35),
      0 0 0 1px rgba(255,255,255,0.9);
    backdrop-filter: blur(22px) saturate(1.4);
    display: flex;
    flex-direction: column;
  }

  .floating-header {
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    background: linear-gradient(to bottom, rgba(255,255,255,0.72), rgba(255,255,255,0.32));
  }

  .floating-header-right {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .floating-media {
    position: relative;
    flex: 1;
    margin: 10px 12px 14px 12px;
    border-radius: 20px;
    overflow: hidden;
    background: radial-gradient(circle at 10% 0, #fef3c7 0, #fb7185 32%, #4f46e5 85%);
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.35),
      0 12px 32px rgba(15, 23, 42, 0.35);
  }

  .floating-media-crop {
    position: absolute;
    inset: 16% 10% 18% 26%;
    border-radius: 22px;
    overflow: hidden;
    box-shadow:
      0 0 0 1px rgba(255,255,255,0.35),
      0 18px 40px rgba(15,23,42,0.5);
    background-image: url("https://images.pexels.com/photos/7130555/pexels-photo-7130555.jpeg?auto=compress&cs=tinysrgb&w=800");
    background-size: cover;
    background-position: 40% 35%;
    filter: saturate(1.15);
  }

  .floating-media-overlay {
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 15% 0, rgba(255,255,255,0.20), transparent 55%);
    mix-blend-mode: screen;
  }

  .floating-caption {
    position: absolute;
    bottom: 12px;
    right: 16px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(15, 23, 42, 0.55);
    color: rgba(248, 250, 252, 0.92);
    font-size: 10px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  /* ===== 팝업 (카드 브라우저) ===== */
  .popup-shell {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 380px;
    height: 500px;
    background: radial-gradient(circle at 20% 0, rgba(255,255,255,0.88), rgba(255,255,255,0.7));
    box-shadow:
      0 28px 72px rgba(15,23,42,0.42),
      0 0 0 1px rgba(255,255,255,0.85);
    backdrop-filter: blur(26px) saturate(1.4);
    display: flex;
    flex-direction: column;
    padding: 16px 18px 20px 18px;
  }

  .popup-header {
    position: relative;
    height: 80px;
    border-radius: 22px;
    overflow: hidden;
    background: radial-gradient(circle at 0 0, rgba(254,249,195,0.9), rgba(248,113,113,0.75), rgba(37,99,235,0.65));
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.45),
      0 12px 28px rgba(15,23,42,0.35);
  }

  .popup-header-media {
    position: absolute;
    inset: -10% -6% 0 -12%;
    background-image: url("https://images.pexels.com/photos/7130555/pexels-photo-7130555.jpeg?auto=compress&cs=tinysrgb&w=1200");
    background-size: cover;
    background-position: 36% 25%;
    filter: saturate(1.1) contrast(1.02);
  }

  .popup-header-glass {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(15,23,42,0.12), rgba(15,23,42,0.52));
    mix-blend-mode: multiply;
  }

  .popup-header-content {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
  }

  .popup-header-right {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .pill-button {
    height: 26px;
    padding: 0 12px;
    border-radius: 999px;
    font-size: 11px;
    border: none;
    outline: none;
    background: rgba(15, 23, 42, 0.22);
    color: rgba(248, 250, 252, 0.95);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: default;
    backdrop-filter: blur(18px);
    box-shadow: 0 0 0 1px rgba(255,255,255,0.28);
  }

  .pill-button.secondary {
    background: rgba(15, 23, 42, 0.06);
    color: rgba(248, 250, 252, 0.9);
  }

  .pill-icon {
    width: 12px;
    height: 12px;
    border-radius: 999px;
    background: rgba(15,23,42,0.75);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    color: rgba(248,250,252,0.92);
  }

  .popup-body {
    margin-top: 16px;
    flex: 1;
    border-radius: 24px;
    overflow: hidden;
    position: relative;
    background: radial-gradient(circle at 10% 0, rgba(255,255,255,0.82), rgba(255,255,255,0.6));
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.5),
      0 16px 38px rgba(15,23,42,0.3);
    display: flex;
    flex-direction: column;
    padding: 18px 16px 18px 16px;
  }

  .popup-body-inner {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

  .scroll-indicator {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    width: 3px;
    height: 92px;
    border-radius: 999px;
    background: rgba(148, 163, 184, 0.28);
    overflow: hidden;
  }

  .scroll-indicator-thumb {
    position: absolute;
    top: 18px;
    left: 0;
    right: 0;
    height: 34px;
    margin: 0 auto;
    border-radius: 999px;
    background: linear-gradient(to bottom, rgba(248,250,252,0.9), rgba(226,232,240,0.9));
    box-shadow: 0 2px 8px rgba(15,23,42,0.35);
  }

  .card-track-viewport {
    position: relative;
    flex: 1;
    overflow: hidden;
    padding-right: 16px;
  }

  .card-track {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    transform: translateY(-8px);
    display: flex;
    flex-direction: column;
    gap: 18px;
  }

  .card-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
  }

  .card {
    position: relative;
    height: 132px;
    background: radial-gradient(circle at 0 0, rgba(255,255,255,0.65), rgba(148,163,184,0.10));
    box-shadow:
      0 14px 30px rgba(15,23,42,0.32),
      inset 0 0 0 1px rgba(255,255,255,0.6);
    opacity: 0.22;
    transform-style: preserve-3d;
    transform-origin: center;
    transition:
      opacity 260ms ease-out,
      transform 260ms ease-out,
      box-shadow 260ms ease-out,
      filter 260ms ease-out;
    cursor: default;
  }

  .card.is-center {
    opacity: 0.9;
    filter: saturate(1.02);
  }

  .card.is-side {
    opacity: 0.20;
    filter: blur(0.2px) saturate(0.9);
    transform: scale(0.96);
  }

  .card-media {
    position: absolute;
    inset: 14px 12px 28px 12px;
    border-radius: 18px;
    overflow: hidden;
    background-image: url("https://images.pexels.com/photos/7130555/pexels-photo-7130555.jpeg?auto=compress&cs=tinysrgb&w=800");
    background-size: cover;
    background-position: 40% 35%;
    box-shadow:
      inset 0 0 0 1px rgba(255,255,255,0.32),
      0 14px 30px rgba(15,23,42,0.42);
    filter: brightness(1.05);
  }

  .card-overlay-fade {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(15,23,42,0.0), rgba(15,23,42,0.6));
  }

  .card-meta {
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 10px;
    border-radius: 14px;
    padding: 4px 9px;
    background: rgba(15,23,42,0.46);
    color: rgba(248,250,252,0.94);
    display: flex;
    flex-direction: column;
    gap: 2px;
    opacity: 0;
    transform: translateY(4px);
    transition:
      opacity 220ms ease-out,
      transform 220ms ease-out;
    font-size: 10px;
  }

  .card-title {
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .card-desc {
    opacity: 0.78;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .card:hover {
    opacity: 0.85;
    transform: translateY(-4px) rotate3d(1, -1.2, 0, 6deg) scale(1.03);
    box-shadow:
      0 18px 44px rgba(15,23,42,0.46),
      inset 0 0 0 1px rgba(255,255,255,0.7);
  }

  .card:hover .card-meta {
    opacity: 1;
    transform: translateY(0);
  }

  .card.is-center:hover {
    transform: translateY(-6px) rotate3d(1, -1.2, 0, 7deg) scale(1.05);
  }

  .settings-strip {
    display: flex;
    gap: 10px;
    margin-top: 2px;
    font-size: 10px;
    color: rgba(15,23,42,0.6);
  }

  .settings-chip {
    padding: 4px 9px;
    border-radius: 999px;
    background: rgba(148,163,184,0.12);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.6);
  }

  .mini-custom-preview {
    display: flex;
    gap: 10px;
    margin-top: 2px;
  }

  .mini-floating-preview,
  .mini-popup-header,
  .mini-popup-body {
    flex: 1;
    height: 30px;
    background: rgba(148,163,184,0.16);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.6);
  }

  .mini-floating-preview { border-radius: 12px; }
  .mini-popup-header    { border-radius: 12px; }
  .mini-popup-body      { border-radius: 16px; }

</style>
</head>
<body>

<div class="preview-wrap">

  <!-- 플로팅 위젯 -->
  <div class="master-frame">
    <div class="frame-label">플로팅 위젯 (바탕화면 Idle 상태)</div>

    <div class="floating-shell">
      <div class="floating-header">
        <div class="window-controls">
          <div class="dot dot-red"></div>
          <div class="dot dot-yellow"></div>
        </div>
        <div class="floating-header-right">
          <!-- 설정: 톱니 아이콘 -->
          <div class="icon-pill" data-role="settings">
            <span class="icon-pill-icon">⚙</span>
            <span class="icon-pill-label">설정</span>
          </div>
          <!-- 사운드: 스피커 아이콘 + 토글 -->
          <div class="icon-pill sound-toggle" data-sound="off">
            <span class="icon-pill-icon" data-sound-icon>🔈</span>
            <span class="icon-pill-label" data-sound-label>사운드</span>
          </div>
        </div>
      </div>

      <div class="floating-media">
        <div class="floating-media-crop"></div>
        <div class="floating-media-overlay"></div>
        <div class="floating-caption">크롭 미디어 · Idle</div>
      </div>
    </div>
  </div>

  <!-- 팝업 카드 브라우저 -->
  <div class="master-frame">
    <div class="frame-label">팝업 (카드 브라우저 모드)</div>

    <div class="popup-shell">
      <div class="popup-header">
        <div class="popup-header-media"></div>
        <div class="popup-header-glass"></div>

        <div class="popup-header-content">
          <div class="window-controls">
            <div class="dot dot-red"></div>
            <div class="dot dot-yellow"></div>
          </div>
          <div class="popup-header-right">
            <!-- 설정/사운드와는 별도로, 삭제/URL 버튼 유지 -->
            <button class="pill-button">
              <span class="pill-icon">🗑</span>
              삭제 모드
            </button>
            <button class="pill-button secondary">
              URL
            </button>
          </div>
        </div>
      </div>

      <div class="popup-body">
        <div class="popup-body-inner">

          <div class="settings-strip">
            <div class="settings-chip">커스텀 미리보기</div>
            <div class="settings-chip">위젯 · 헤더 · 카드</div>
          </div>

          <div class="mini-custom-preview">
            <div class="mini-floating-preview"></div>
            <div class="mini-popup-header"></div>
            <div class="mini-popup-body"></div>
          </div>

          <div class="card-track-viewport">
            <div class="card-track">

              <div class="card-row">
                <div class="card is-side">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                </div>
                <div class="card is-center">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                  <div class="card-meta">
                    <div class="card-title">디자인 레퍼런스 · 아카이브</div>
                    <div class="card-desc">iOS/macOS 스타일 인터랙션 샘플</div>
                  </div>
                </div>
                <div class="card is-side">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                </div>
              </div>

              <div class="card-row">
                <div class="card is-side">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                </div>
                <div class="card is-center">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                  <div class="card-meta">
                    <div class="card-title">즐겨찾는 아카이브 링크</div>
                    <div class="card-desc">정리용 URL 카드 예시</div>
                  </div>
                </div>
                <div class="card is-side">
                  <div class="card-media">
                    <div class="card-overlay-fade"></div>
                  </div>
                </div>
              </div>

            </div>

            <div class="scroll-indicator">
              <div class="scroll-indicator-thumb"></div>
            </div>

          </div>
        </div>
      </div>
    </div>

  </div>

</div>

<script>
  // 사운드 토글 버튼 시각적 피드백만 구현 (실제 오디오 제어 X)
  (function () {
    var toggle = document.querySelector('.sound-toggle');
    if (!toggle) return;

    var iconEl = toggle.querySelector('[data-sound-icon]');
    var labelEl = toggle.querySelector('[data-sound-label]');

    toggle.addEventListener('click', function () {
      var current = toggle.getAttribute('data-sound') || 'off';
      var next = current === 'off' ? 'on' : 'off';

      toggle.setAttribute('data-sound', next);

      if (next === 'on') {
        toggle.classList.add('sound-on');
        if (iconEl) iconEl.textContent = '🔊';
        if (labelEl) labelEl.textContent = '사운드 ON';
      } else {
        toggle.classList.remove('sound-on');
        if (iconEl) iconEl.textContent = '🔈';
        if (labelEl) labelEl.textContent = '사운드';
      }
    });
  })();
</script>

</body>
</html>

참고 할거면 하시구.

 

자꾸 커다란 창안에 위젯을 가둬서

기능 구현도 하기도 전에 무료 플랜을 다써버림 ㅋㅋ;;;

 

[콘셉트]

위젯 형태에서 가만히 두면 덕질용 플래이어 형태로 동작하며

내부 컨탠츠 마우스로 누르면 새창이 팝업되면서

아카이빙 한 URL이 어플 모양의 래터박스로 쭈우우욱 나오는대

마우스로 그 어플모양 주소 클립을 누르면

자동 복사 되어서 바로 복사해서 넣을수있게 동작함 ㅇㅇ

잘 하면 이거 코드나 메모같은것도

담을수 있는 클리퍼로 만들수있엇는대 아쉽;;