旋转拼图

Published on
/
/趣玩前端
<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>旋转拼图益智游戏</title>
    <style>
      * {
        box-sizing: border-box;
        -webkit-font-smoothing: antialiased;
        text-rendering: optimizeLegibility;
        scroll-behavior: smooth;
      }
      html,
      body {
        height: 100%;
        overflow: hidden;
      }
      body {
        margin: 0;
        padding: 0;
        background: #1e1e1e;
        font-family: monospace;
      }
      :root {
        --size: min(200px, min(30vh, 30vw));
        --subsz: calc(0.2 * var(--size));

        --clr1: #479ce7;
        --clr2: #ef476f;
        --clr3: #ffd166;
        --clr4: #06d6a0;
      }
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        position: relative;
        margin-top: 50vh;
      }
      .circle {
        position: absolute;
        width: var(--size);
        height: var(--size);
        background: #fff;
        border-radius: 100%;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        box-shadow: inset 0 0 0 calc(0.3 * var(--size)) #0002;
        margin: auto;
        transition: rotate 1s ease-in-out;
        &#A {
          background: var(--clr1);
          left: calc(var(--size) * 1.74);
        }
        &#B {
          background: var(--clr2);
          bottom: calc(var(--size) * -1);
        }
        &#C {
          background: var(--clr3);
          right: calc(var(--size) * 1.74);
        }
        &#D {
          background: var(--clr4);
          top: calc(var(--size) * -1);
        }
        > div {
          position: absolute;
          left: calc(50% - var(--subsz) / 2);
          top: 0;
          width: var(--subsz);
          height: calc(50%);
          transform-origin: 50% 100%;
          &::before {
            content: "";
            display: block;
            position: relative;
            top: -1px;
            width: var(--subsz);
            height: calc(var(--subsz));
            background: #1e1e1e;
            border-bottom-left-radius: var(--subsz);
            border-bottom-right-radius: var(--subsz);
          }
          &:nth-child(1) {
            rotate: 60deg;
          }
          &:nth-child(2) {
            rotate: 120deg;
          }
          &:nth-child(3) {
            rotate: 180deg;
          }
          &:nth-child(4) {
            rotate: 240deg;
          }
          &:nth-child(5) {
            rotate: 300deg;
          }

          &::after {
            position: absolute;
            display: block;
            transition: top 0.4s ease-in-out, background 1.2s ease-in;
            content: "";
            color: #fff;
            width: calc(0.8 * var(--subsz));
            height: calc(0.8 * var(--subsz));
            left: calc(0.1 * var(--subsz));

            border-radius: 100%;
            top: calc(-0.9 * var(--subsz));
          }
          &[data-cur="a"]::after {
            top: calc(0.06 * var(--subsz));
            background: var(--clr1);
            transition: top 0.4s ease-in-out, background 0s linear;
          }
          &[data-cur="b"]::after {
            top: calc(0.06 * var(--subsz));
            background: var(--clr2);
            transition: top 0.4s ease-in-out, background 0s linear;
          }
          &[data-cur="c"]::after {
            top: calc(0.06 * var(--subsz));
            background: var(--clr3);
            transition: top 0.4s ease-in-out, background 0s linear;
          }
          &[data-cur="d"]::after {
            top: calc(0.06 * var(--subsz));
            background: var(--clr4);
            transition: top 0.4s ease-in-out, background 0s linear;
          }
        }
      }
      .arrow {
        position: absolute;
        &.a {
          top: calc(-0.2 * var(--size));
          rotate: 90deg;
          translate: calc(1.4 * var(--size));
          .left,
          .right {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill='%23479ce7' version='1.1' id='Layer_1' viewBox='0 0 302.817 302.817' xml:space='preserve'%3E%3Cpath id='XMLID_5_' d='M298.423,128.606L235.94,66.124c-0.004-0.003-0.007-0.006-0.011-0.009c-0.355-0.354-0.725-0.689-1.111-1.005 c-0.214-0.175-0.439-0.327-0.66-0.488c-0.169-0.123-0.332-0.256-0.507-0.372c-0.29-0.194-0.591-0.365-0.891-0.536 c-0.12-0.068-0.235-0.146-0.356-0.21c-0.286-0.153-0.58-0.284-0.874-0.418c-0.151-0.069-0.298-0.146-0.452-0.21 c-0.253-0.105-0.513-0.19-0.77-0.281c-0.207-0.073-0.41-0.153-0.621-0.217c-0.206-0.063-0.416-0.108-0.625-0.161 c-0.268-0.069-0.534-0.143-0.807-0.197c-0.16-0.032-0.321-0.049-0.481-0.075c-0.322-0.053-0.644-0.108-0.971-0.14 c-0.13-0.013-0.261-0.012-0.391-0.022c-0.352-0.025-0.704-0.051-1.061-0.051c-0.193,0-0.386,0.019-0.579,0.026 c-0.29,0.011-0.577,0.013-0.869,0.042c-0.495,0.047-0.989,0.121-1.479,0.217c-0.005,0.001-0.01,0.001-0.016,0.002 c-0.067,0.014-0.131,0.036-0.199,0.05c-0.415,0.088-0.828,0.188-1.236,0.312c-0.158,0.048-0.31,0.11-0.466,0.163 c-0.308,0.105-0.616,0.208-0.919,0.333c-0.208,0.086-0.405,0.188-0.607,0.282c-0.239,0.112-0.48,0.218-0.714,0.343 c-0.243,0.129-0.474,0.276-0.708,0.418c-0.183,0.111-0.368,0.214-0.547,0.333c-0.281,0.188-0.548,0.393-0.814,0.599 c-0.122,0.094-0.248,0.179-0.368,0.277c-0.341,0.28-0.665,0.577-0.977,0.884c-0.04,0.039-0.084,0.071-0.123,0.111l-0.02,0.02 c-0.016,0.015-0.03,0.03-0.045,0.045l-62.421,62.42c-5.858,5.857-5.858,15.355,0,21.213c2.929,2.929,6.768,4.394,10.606,4.393 c3.838-0.001,7.678-1.465,10.606-4.393l38.836-38.835c-4.299,47.301-39.205,88.259-88.071,97.979 c-6.707,1.334-13.454,2.03-20.161,2.11c-14.532,0.174-28.878-2.539-42.235-7.898c-1.028-0.412-2.049-0.84-3.064-1.284 c-12.185-5.322-23.474-12.883-33.235-22.493c-5.903-5.814-15.401-5.738-21.212,0.165c-5.813,5.903-5.739,15.4,0.165,21.212 c8.282,8.154,17.427,15.148,27.2,20.912c21.5,12.678,46.03,19.397,71.056,19.396c0,0,0,0,0,0h0.001 c9.087-0.001,18.245-0.887,27.34-2.696c61.89-12.311,106.147-63.914,112.006-123.7l35.131,35.13c5.857,5.858,15.355,5.858,21.213,0 C304.281,143.962,304.281,134.464,298.423,128.606z'/%3E%3C/svg%3E");
          }
        }
        &.b {
          top: calc(0.8 * var(--size));
          rotate: 180deg;
          .left,
          .right {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill='%23ef476f' version='1.1' id='Layer_1' viewBox='0 0 302.817 302.817' xml:space='preserve'%3E%3Cpath id='XMLID_5_' d='M298.423,128.606L235.94,66.124c-0.004-0.003-0.007-0.006-0.011-0.009c-0.355-0.354-0.725-0.689-1.111-1.005 c-0.214-0.175-0.439-0.327-0.66-0.488c-0.169-0.123-0.332-0.256-0.507-0.372c-0.29-0.194-0.591-0.365-0.891-0.536 c-0.12-0.068-0.235-0.146-0.356-0.21c-0.286-0.153-0.58-0.284-0.874-0.418c-0.151-0.069-0.298-0.146-0.452-0.21 c-0.253-0.105-0.513-0.19-0.77-0.281c-0.207-0.073-0.41-0.153-0.621-0.217c-0.206-0.063-0.416-0.108-0.625-0.161 c-0.268-0.069-0.534-0.143-0.807-0.197c-0.16-0.032-0.321-0.049-0.481-0.075c-0.322-0.053-0.644-0.108-0.971-0.14 c-0.13-0.013-0.261-0.012-0.391-0.022c-0.352-0.025-0.704-0.051-1.061-0.051c-0.193,0-0.386,0.019-0.579,0.026 c-0.29,0.011-0.577,0.013-0.869,0.042c-0.495,0.047-0.989,0.121-1.479,0.217c-0.005,0.001-0.01,0.001-0.016,0.002 c-0.067,0.014-0.131,0.036-0.199,0.05c-0.415,0.088-0.828,0.188-1.236,0.312c-0.158,0.048-0.31,0.11-0.466,0.163 c-0.308,0.105-0.616,0.208-0.919,0.333c-0.208,0.086-0.405,0.188-0.607,0.282c-0.239,0.112-0.48,0.218-0.714,0.343 c-0.243,0.129-0.474,0.276-0.708,0.418c-0.183,0.111-0.368,0.214-0.547,0.333c-0.281,0.188-0.548,0.393-0.814,0.599 c-0.122,0.094-0.248,0.179-0.368,0.277c-0.341,0.28-0.665,0.577-0.977,0.884c-0.04,0.039-0.084,0.071-0.123,0.111l-0.02,0.02 c-0.016,0.015-0.03,0.03-0.045,0.045l-62.421,62.42c-5.858,5.857-5.858,15.355,0,21.213c2.929,2.929,6.768,4.394,10.606,4.393 c3.838-0.001,7.678-1.465,10.606-4.393l38.836-38.835c-4.299,47.301-39.205,88.259-88.071,97.979 c-6.707,1.334-13.454,2.03-20.161,2.11c-14.532,0.174-28.878-2.539-42.235-7.898c-1.028-0.412-2.049-0.84-3.064-1.284 c-12.185-5.322-23.474-12.883-33.235-22.493c-5.903-5.814-15.401-5.738-21.212,0.165c-5.813,5.903-5.739,15.4,0.165,21.212 c8.282,8.154,17.427,15.148,27.2,20.912c21.5,12.678,46.03,19.397,71.056,19.396c0,0,0,0,0,0h0.001 c9.087-0.001,18.245-0.887,27.34-2.696c61.89-12.311,106.147-63.914,112.006-123.7l35.131,35.13c5.857,5.858,15.355,5.858,21.213,0 C304.281,143.962,304.281,134.464,298.423,128.606z'/%3E%3C/svg%3E");
          }
        }
        &.c {
          top: calc(-0.2 * var(--size));
          rotate: 270deg;
          translate: calc(-1.4 * var(--size));
          .left,
          .right {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill='%23ffd166' version='1.1' id='Layer_1' viewBox='0 0 302.817 302.817' xml:space='preserve'%3E%3Cpath id='XMLID_5_' d='M298.423,128.606L235.94,66.124c-0.004-0.003-0.007-0.006-0.011-0.009c-0.355-0.354-0.725-0.689-1.111-1.005 c-0.214-0.175-0.439-0.327-0.66-0.488c-0.169-0.123-0.332-0.256-0.507-0.372c-0.29-0.194-0.591-0.365-0.891-0.536 c-0.12-0.068-0.235-0.146-0.356-0.21c-0.286-0.153-0.58-0.284-0.874-0.418c-0.151-0.069-0.298-0.146-0.452-0.21 c-0.253-0.105-0.513-0.19-0.77-0.281c-0.207-0.073-0.41-0.153-0.621-0.217c-0.206-0.063-0.416-0.108-0.625-0.161 c-0.268-0.069-0.534-0.143-0.807-0.197c-0.16-0.032-0.321-0.049-0.481-0.075c-0.322-0.053-0.644-0.108-0.971-0.14 c-0.13-0.013-0.261-0.012-0.391-0.022c-0.352-0.025-0.704-0.051-1.061-0.051c-0.193,0-0.386,0.019-0.579,0.026 c-0.29,0.011-0.577,0.013-0.869,0.042c-0.495,0.047-0.989,0.121-1.479,0.217c-0.005,0.001-0.01,0.001-0.016,0.002 c-0.067,0.014-0.131,0.036-0.199,0.05c-0.415,0.088-0.828,0.188-1.236,0.312c-0.158,0.048-0.31,0.11-0.466,0.163 c-0.308,0.105-0.616,0.208-0.919,0.333c-0.208,0.086-0.405,0.188-0.607,0.282c-0.239,0.112-0.48,0.218-0.714,0.343 c-0.243,0.129-0.474,0.276-0.708,0.418c-0.183,0.111-0.368,0.214-0.547,0.333c-0.281,0.188-0.548,0.393-0.814,0.599 c-0.122,0.094-0.248,0.179-0.368,0.277c-0.341,0.28-0.665,0.577-0.977,0.884c-0.04,0.039-0.084,0.071-0.123,0.111l-0.02,0.02 c-0.016,0.015-0.03,0.03-0.045,0.045l-62.421,62.42c-5.858,5.857-5.858,15.355,0,21.213c2.929,2.929,6.768,4.394,10.606,4.393 c3.838-0.001,7.678-1.465,10.606-4.393l38.836-38.835c-4.299,47.301-39.205,88.259-88.071,97.979 c-6.707,1.334-13.454,2.03-20.161,2.11c-14.532,0.174-28.878-2.539-42.235-7.898c-1.028-0.412-2.049-0.84-3.064-1.284 c-12.185-5.322-23.474-12.883-33.235-22.493c-5.903-5.814-15.401-5.738-21.212,0.165c-5.813,5.903-5.739,15.4,0.165,21.212 c8.282,8.154,17.427,15.148,27.2,20.912c21.5,12.678,46.03,19.397,71.056,19.396c0,0,0,0,0,0h0.001 c9.087-0.001,18.245-0.887,27.34-2.696c61.89-12.311,106.147-63.914,112.006-123.7l35.131,35.13c5.857,5.858,15.355,5.858,21.213,0 C304.281,143.962,304.281,134.464,298.423,128.606z'/%3E%3C/svg%3E");
          }
        }
        &.d {
          top: calc(-1.2 * var(--size));
          .left,
          .right {
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill='%2306d6a0' version='1.1' id='Layer_1' viewBox='0 0 302.817 302.817' xml:space='preserve'%3E%3Cpath id='XMLID_5_' d='M298.423,128.606L235.94,66.124c-0.004-0.003-0.007-0.006-0.011-0.009c-0.355-0.354-0.725-0.689-1.111-1.005 c-0.214-0.175-0.439-0.327-0.66-0.488c-0.169-0.123-0.332-0.256-0.507-0.372c-0.29-0.194-0.591-0.365-0.891-0.536 c-0.12-0.068-0.235-0.146-0.356-0.21c-0.286-0.153-0.58-0.284-0.874-0.418c-0.151-0.069-0.298-0.146-0.452-0.21 c-0.253-0.105-0.513-0.19-0.77-0.281c-0.207-0.073-0.41-0.153-0.621-0.217c-0.206-0.063-0.416-0.108-0.625-0.161 c-0.268-0.069-0.534-0.143-0.807-0.197c-0.16-0.032-0.321-0.049-0.481-0.075c-0.322-0.053-0.644-0.108-0.971-0.14 c-0.13-0.013-0.261-0.012-0.391-0.022c-0.352-0.025-0.704-0.051-1.061-0.051c-0.193,0-0.386,0.019-0.579,0.026 c-0.29,0.011-0.577,0.013-0.869,0.042c-0.495,0.047-0.989,0.121-1.479,0.217c-0.005,0.001-0.01,0.001-0.016,0.002 c-0.067,0.014-0.131,0.036-0.199,0.05c-0.415,0.088-0.828,0.188-1.236,0.312c-0.158,0.048-0.31,0.11-0.466,0.163 c-0.308,0.105-0.616,0.208-0.919,0.333c-0.208,0.086-0.405,0.188-0.607,0.282c-0.239,0.112-0.48,0.218-0.714,0.343 c-0.243,0.129-0.474,0.276-0.708,0.418c-0.183,0.111-0.368,0.214-0.547,0.333c-0.281,0.188-0.548,0.393-0.814,0.599 c-0.122,0.094-0.248,0.179-0.368,0.277c-0.341,0.28-0.665,0.577-0.977,0.884c-0.04,0.039-0.084,0.071-0.123,0.111l-0.02,0.02 c-0.016,0.015-0.03,0.03-0.045,0.045l-62.421,62.42c-5.858,5.857-5.858,15.355,0,21.213c2.929,2.929,6.768,4.394,10.606,4.393 c3.838-0.001,7.678-1.465,10.606-4.393l38.836-38.835c-4.299,47.301-39.205,88.259-88.071,97.979 c-6.707,1.334-13.454,2.03-20.161,2.11c-14.532,0.174-28.878-2.539-42.235-7.898c-1.028-0.412-2.049-0.84-3.064-1.284 c-12.185-5.322-23.474-12.883-33.235-22.493c-5.903-5.814-15.401-5.738-21.212,0.165c-5.813,5.903-5.739,15.4,0.165,21.212 c8.282,8.154,17.427,15.148,27.2,20.912c21.5,12.678,46.03,19.397,71.056,19.396c0,0,0,0,0,0h0.001 c9.087-0.001,18.245-0.887,27.34-2.696c61.89-12.311,106.147-63.914,112.006-123.7l35.131,35.13c5.857,5.858,15.355,5.858,21.213,0 C304.281,143.962,304.281,134.464,298.423,128.606z'/%3E%3C/svg%3E");
          }
        }
        .left,
        .right {
          position: relative;
          background-size: contain;
          background-repeat: no-repeat;
          width: calc(0.42 * var(--size));
          height: calc(0.22 * var(--size));
          rotate: -180deg;
          cursor: pointer;
          &:hover {
            filter: brightness(100);
          }
        }
        .left {
          left: calc(-0.42 * var(--size));
        }
        .right {
          top: calc(-0.22 * var(--size));
          left: calc(0.42 * var(--size));
          transform: rotateY(180deg);
        }
      }

      .ui {
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        width: 100%;
        height: 100%;
        z-index: 100;
        pointer-events: none;

        .title,
        .author {
          position: absolute;
          color: #555;
          user-select: none;
        }
        .title {
          left: 16px;
          top: 0.4em;
          font-size: 1.4em;
        }
        .author {
          left: 16px;
          top: 2.4em;
          font-size: 1em;
        }

        .direction {
          position: absolute;
          width: calc(0.5 * var(--size));
          path {
            fill: #0002;
          }
          left: 0;
          right: 0;
          top: 0;
          bottom: 0;
          margin: auto;
          &.top {
            top: calc(-0.98 * var(--size));
            left: calc(0.03 * var(--size));
            rotate: 30deg;
          }
          &.right {
            top: calc(0.03 * var(--size));
            left: calc(1.7 * var(--size));
            rotate: 150deg;
          }
          &.bottom {
            top: calc(0.98 * var(--size));
            left: calc(-0.03 * var(--size));
            rotate: 210deg;
          }
          &.left {
            top: calc(-0.03 * var(--size));
            left: calc(-1.7 * var(--size));
            rotate: 330deg;
          }
          &.topup {
            width: calc(0.18 * var(--size));
            top: calc(-0.64 * var(--size));
            left: calc(-0 * var(--size));
            rotate: 270deg;
            background: var(--clr4);
            border-radius: 100%;
            z-index: -1;
          }
          &.bottomup {
            width: calc(0.18 * var(--size));
            top: calc(0.64 * var(--size));
            left: calc(-0 * var(--size));
            rotate: 270deg;
            background: var(--clr2);
            border-radius: 100%;
            z-index: -1;
          }
        }

        .shuffle {
          position: absolute;
          right: 1em;
          top: 1em;
          padding: 4px 24px;
          font-size: 1.2em;
          color: #1e1e1e;
          background: var(--clr3);
          border-radius: 2px;
          pointer-events: all;
          cursor: pointer;
          border: 3px solid #0006;
          &:hover {
            background: #fffc;
          }
        }
        .solved {
          position: absolute;
          right: 2em;
          bottom: 1.4em;
          font-size: 1.4em;
          color: var(--clr2);
          &.true {
            color: var(--clr4);
          }
        }
      }
    </style>
  </head>
  <body>
    <div class="ui">
      <div class="shuffle">打乱</div>

      <div class="solved true">已解决</div>

      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction bottomup"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction topup"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction top"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction right"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction bottom"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        class="direction left"
      >
        <path
          d="m14.707 12.707-4 4a1 1 0 0 1-1.414-1.414L12.586 12 9.293 8.707a1 1 0 1 1 1.414-1.414l4 4a1 1 0 0 1 0 1.414z"
        />
      </svg>
    </div>

    <div class="container">
      <div class="circle" id="A" data-pos="0">
        <div data-cur="a" data-static="2"></div>
        <div data-cur="a" data-static="3"></div>
        <div data-cur="a" data-static="4"></div>
        <div data-cur="" data-static="5"></div>
        <div data-cur="a" data-static="0"></div>
        <div data-cur="a" data-static="1"></div>
      </div>
      <div class="circle" id="B" data-pos="0">
        <div data-cur="b" data-static="0"></div>
        <div data-cur="b" data-static="1"></div>
        <div data-cur="b" data-static="2"></div>
        <div data-cur="b" data-static="3"></div>
        <div data-cur="" data-static="4"></div>
        <div data-cur="b" data-static="5"></div>
      </div>
      <div class="circle" id="C" data-pos="0">
        <div data-cur="" data-static="5"></div>
        <div data-cur="c" data-static="0"></div>
        <div data-cur="c" data-static="1"></div>
        <div data-cur="c" data-static="2"></div>
        <div data-cur="c" data-static="3"></div>
        <div data-cur="c" data-static="4"></div>
      </div>
      <div class="circle" id="D" data-pos="0">
        <div data-cur="d" data-static="3"></div>
        <div data-cur="" data-static="4"></div>
        <div data-cur="d" data-static="5"></div>
        <div data-cur="d" data-static="0"></div>
        <div data-cur="d" data-static="1"></div>
        <div data-cur="d" data-static="2"></div>
      </div>

      <div class="arrow a">
        <div class="left"></div>
        <div class="right"></div>
      </div>
      <div class="arrow b">
        <div class="left"></div>
        <div class="right"></div>
      </div>
      <div class="arrow c">
        <div class="left"></div>
        <div class="right"></div>
      </div>
      <div class="arrow d">
        <div class="left"></div>
        <div class="right"></div>
      </div>
    </div>

    <script>
      const circles = document.querySelectorAll(".circle");
      const arrows = document.querySelectorAll(".arrow");
      let clickAllowed = true;

      function handleClick(index, direction, force = false) {
        if (!clickAllowed && !force) return;
        if (!force) {
          clickAllowed = false;
          setTimeout(() => (clickAllowed = true), 1000);
        }
        if (direction === "left") {
          circles[index].dataset.pos++;
          circles[index].querySelectorAll("div").forEach((node) => {
            node.dataset.static = (Number(node.dataset.static) - 1 + 6) % 6;
          });
        } else {
          circles[index].dataset.pos--;
          circles[index].querySelectorAll("div").forEach((node) => {
            node.dataset.static = (Number(node.dataset.static) + 1) % 6;
          });
        }
        circles[index].style.rotate = `${-60 * circles[index].dataset.pos}deg`;
        clockwiseUpCheck();
      }

      arrows.forEach((arrow, i) => {
        const leftArrow = arrow.querySelector(".left");
        const rightArrow = arrow.querySelector(".right");
        leftArrow.addEventListener("click", () => handleClick(i, "left"));
        rightArrow.addEventListener("click", () => handleClick(i, "right"));
      });

      function checkTransfer(fro, tow) {
        let [froLet, froStatic] = [fro[0], fro[1]];
        let [towLet, towStatic] = [tow[0], tow[1]];
        let froEle = document.querySelector(
          `.circle#${froLet} [data-static="${froStatic}"]`
        );
        let towEle = document.querySelector(
          `.circle#${towLet} [data-static="${towStatic}"]`
        );
        if (froEle.dataset.cur != "" && towEle.dataset.cur == "") {
          towEle.dataset.cur = froEle.dataset.cur;
          froEle.dataset.cur = "";
        }
      }

      function clockwiseUpCheck() {
        setTimeout(() => {
          checkTransfer("A5", "B0");
          checkTransfer("B4", "C0");
          checkTransfer("C5", "D0");
          checkTransfer("D4", "A0");
          checkTransfer("B5", "D5");
          checkSolution();
        }, 1000);
      }

      function shuffle(times = 10, delay = 10) {
        let count = 0;
        const interval = setInterval(() => {
          const randomIndex = Math.floor(Math.random() * arrows.length);
          const randomDir = Math.random() > 0.5 ? "left" : "right";
          handleClick(randomIndex, randomDir, true);
          count++;
          if (count >= times) {
            clearInterval(interval);
          }
        }, delay);
      }

      const shuffleBtn = document.querySelector(".shuffle");
      shuffleBtn.addEventListener("click", () => shuffle(800));

      const checkVis = document.querySelector(".solved");
      function checkSolution() {
        let check = true;
        circles.forEach((circle) => {
          let contents = circle.querySelectorAll("div[data-cur]");
          contents.forEach((content) => {
            if (
              content.dataset.cur !== "" &&
              circle.id.toLowerCase() !== content.dataset.cur
            ) {
              check = false;
            }
          });
        });
        checkVis.innerHTML = check ? "已解决" : "未解决";
        if (check) {
          checkVis.classList.add("true");
        } else {
          checkVis.classList.remove("true");
        }
      }
    </script>
  </body>
</html>