vue拼圖動畫Demo

意必固我_LRL發表於2020-10-12

 

 

這是一個基於vue的Demo,可以實現拼圖動畫,但是具體的沒有寫拼圖成功的邏輯,滑鼠懸停移動。週期重新整理

我把它放到的我的部落格園介面上了。重新整理介面可以看到。

演示地址

https://liruilongs.github.io/jigsawPuzzle.github.io/

 

 

 

 

 

 

 部分程式碼

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>vue.js fifteen puzzle</title>
      <link rel="stylesheet" href="./style.css">
</head>

<body>
   <div id="jigsawID" ></div>
  
  <script src='vue.min.js'></script>
    <script  src="./script.js"></script>

</body>

</html>
style.css,
script.js,
*, *:before, *:after {
  box-sizing: inherit;
}



.wrapper {
  position: relative;
  width: 95vmin;
  height: 95vmin;
  max-width: 500px;
  max-height: 500px;
  border-radius: 8px;
  list-style: none;
  overflow: hidden;
  padding: 8px;
}

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  border: 1px solid #000;
  font-size: 18px;
  font-family: inherit;
  cursor: pointer;
  transition: opacity 0.2s ease, visibility 0s linear;
}

.overlay-hidden {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 4px;
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.item {
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  cursor: pointer;

}

.button {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  padding: 0;
 
  border-radius: 5px;
  border: 1px solid Transparent; box-shadow: 0 0 5px #303133;
  font-size: 18px;
  font-family: inherit;
  background: #fff;
  cursor: pointer;
}

.button:focus {
  outline: none;
  color: #fff;
  background: #00f;
}

.button:focus:active {
  background: #fff;
  color: inherit;
}

.button:disabled {
  color: inherit;
  cursor: default;
}

.hidden {
  visibility: hidden;
}

.list-move {
  transition: -webkit-transform 0.4s ease;
  transition: transform 0.4s ease;
  transition: transform 0.4s ease, -webkit-transform 0.4s ease;
}
const FIFTEEN = Array.from({ length: 15 }, (e, i) => i + 1);
FIFTEEN.push(false);

const arraysEqual = (arr1, arr2) => {
  if (arr1.length !== arr2.length) return false;

  for (let i = arr1.length; i--;) {
    if (arr1[i] !== arr2[i]) return false;
  }

  return true;
};

const isPlayable = (emptyIndex, tileIndex, width) =>
emptyIndex % width !== 0 && emptyIndex - 1 === tileIndex ||
emptyIndex % width !== width - 1 && emptyIndex + 1 === tileIndex ||
emptyIndex - width === tileIndex ||
emptyIndex + width === tileIndex;


const app = document.createElement('div');

document.getElementById("jigsawID").appendChild(app);
new Vue({
  el: app,
  data: function () {
    return {
      mounted: false,
      state: [...FIFTEEN] };

  },
  computed: {
    completed: function () {
      return this.mounted && arraysEqual(FIFTEEN, this.state);
    } },

  mounted: function () {
    this.mounted = true;
    this.shuffleState();
  },
  methods: {
    updateState(i) {
      const updated = [...this.state];
      updated[this.state.indexOf(false)] = this.state[i];
      updated[i] = false;
      this.state = updated;
    },
    shuffleState() {
      this.state.sort(() => Math.random() - 0.5);
    } },

  render(h) {
    const empty = this.state.indexOf(false);

    return h(
    'div',
    { class: 'wrapper' },
    [
    h(
    'transition-group', {
      class: 'grid',
      props: { tag: 'ul', name: 'list' } },

    this.state.map((num, i) => h(
    'li', {
      class: { 'item': true, 'hidden': !num },
      key: num },
    [h(
    'img',
    {
      attrs: { disabled: this.completed || !isPlayable(empty, i, 4) ,src:"./hzw-0"+num+".gif"},
      class: 'button',
      on: !this.completed && isPlayable(empty, i, 4) ? { mouseover: e => {
          this.updateState(i);
          e.currentTarget.blur();
        } } : {} },

    )]))),



    h(
    'button',
    {
      attrs: { disabled: !this.completed },
      class: { overlay: true, 'overlay-hidden': !this.completed },
      on: this.completed ? { mouseover: () => this.shuffleState() } : {} },

    'Congratulations! Play again?')]);



  } });

 

 

相關文章