vue任务列表拖放拖动效果

代码语言:html

所属分类:拖放

代码描述:vue任务列表拖放拖动效果

代码标签: 拖放 拖动 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<style>
html,
body {
  background: #0079bf;
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Droid Sans, Helvetica Neue, sans-serif;
  color: #172b4d;
}

#app {
  background: #0079bf;
  height: 100%;
  overflow-x: auto;
}

main {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: flex-start;
  padding: 20px 0 30px 0;
  box-sizing: border-box;
}
main:before {
  content: '';
  float: right;
  min-width: 20px;
  width: 10px;
  height: 100%;
}
main:after {
  content: '';
  float: right;
  min-width: 20px;
  width: 10px;
  height: 100%;
}

.pane {
  display: inline-block;
  height: 100%;
  min-width: 272px;
  max-width: 272px;
  margin: 0 5px;
  border-radius: 3px;
  padding: 10px;
  box-sizing: border-box;
  background: #ebecf0;
}

.pane-header {
  font-weight: 600;
}

.pane-card {
  background: #ffffff;
  padding: 10px;
  margin: 10px 0;
  border-radius: 3px;
  box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
  cursor: grab;
}
.pane-card:hover {
  background: #f4f5f7;
}
.pane-card.dragging {
  color: transparent;
  background: none;
  border: 2px dashed rgba(0, 0, 0, 0.2);
  box-shadow: none;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  cursor: grabbing;
}

.author {
  position: absolute;
  bottom: 5px;
  left: 50%;
  transform: translateX(-50%);
  color: #FFF;
}
.author a {
  color: inherit;
}

#ghost-card {
  position: absolute;
  user-select: none;
  pointer-events: none;
  top: 100vh;
  left: 100vw;
  opacity: 0;
  transform-origin: center;
  transform: scale(1) rotate(0);
  box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
  transition: transform 0.04s ease-in-out;
}
#ghost-card.animate {
  transition: box-shadow 0.1s ease-in-out;
  transition: transform 0.05s ease-in-out;
}
#ghost-card.active {
  opacity: 1;
  box-shadow: 0 12px 24px -6px rgba(9, 30, 66, 0.25), 0 0 0 1px rgba(9, 30, 66, 0.08);
}
#ghost-card.leaving {
  transition: all .1s ease;
  box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
}

.settings {
  position: absolute;
  top: 0;
  right: 0;
  width: 200px;
  padding: 5px 10px;
  box-sizing: border-box;
  background: #ebecf0;
  color: #172b4d;
  border-radius: 0 0 0 7px;
  max-height: 40px;
  transition: all .2s ease-in-out;
  box-shadow: -1px 1px 10px rgba(9, 30, 66, 0.1);
  overflow: hidden;
  cursor: pointer;
}
.settings.expanded {
  max-height: 100vh;
  overflow: auto;
  cursor: default;
}
.settings.expanded h2 {
  font-size: 1.2em;
}
.settings h2 {
  font-size: 1em;
  font-weight: 700;
  text-align: left;
  margin: 7px 0;
  transition: all .1s ease-in-out;
  display: flex;
  justify-content: space-between;
}
.settings h2 button {
  border: none;
  background: none;
  cursor: pointer;
}
.settings h3 {
  font-size: 1em;
  font-weight: 600;
  text-align: left;
  margin: 15px 0 7.5px 0;
}
.settings label {
  display: block;
  margin: 5px 0;
}
.settings label input {
  border: none;
  border-radius: 3px;
  padding: 3px 3px;
}
.settings label input[type=number] {
  display: block;
  margin: 5px 0 10px 0;
}
.settings label input[disabled=disabled] {
  cursor: not-allowed;
  opacity: .6;
}
.settings label select {
  display: block;
  margin: 5px 0 10px 0;
}

.data-inspector {
  position: absolute;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.5);
  color: #FFF;
  padding: 10px;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.data-inspector p {
  margin: 0;
}
</style>

</head>
<body translate="no">
<div id="app" @mousemove="onDrag($event)" @mouseup="onDragStop()">
<main>
<div v-for="(pane, paneIdx) in filledPanes" :key="paneIdx" :ref="`pane-${paneIdx}`" class="pane">
<div class="pane-header">{{ pane.name }}</div>
<div v-for="(card, cardIdx) in pane.cards" :key="cardIdx" :class="{ 'pane-card': true, 'dragging': draggedCardIdx === card.index }" :ref="`card-${card.index}`" @mousedown="onDragStart($event, card.index)">
{{ card.name }}
</div>
</div>

</main>
<div id="ghost-card" ref="ghostCard" :style="`
               width: ${ghostCardStyle.width}px;
               left: ${ghostCardStyle.pos.x}px; top: ${ghostCardStyle.pos.y - 10}px;
               transform: ${ghostCardStyle.transform};
               transform-origin: ${ghostCardStyle.transformOrigin};
               `" :class="{ 'pane-card': true, 'active': draggedCardIdx !== -1, leaving: ghostCardStyle.leaving, animate: settings.animate }">
{{ draggedCard.name }}
</div>
<div class="settings" :class="{expanded: settingsExpanded}" @click="expandSettings">
<h2>Settings <button v-show="settingsExpanded" @click.stop="wrapSettings">Close</button></h2>
<h3>Animation</h3>
<label>
Smooth
<input v-model="settings.smooth" type="checkbox">
</label>
<label>
Animate on end
<input v-model="settings.animateEnd" type="checkbox">
</label>
<h3>Transform</h3>
<label>
Origin
<select v-model="settings.transformOriginMode">
<option value="mouse">Mouse position</option>
<option value="center">Center</option>
</select>
</label>
<label>
Scale
<input v-model="settings.scale" type="number">
</label>
<h3>Rotation</h3>
<label>
Offset Min
<input v-model="settings.rotationOffset.min" type="number" :disabled="!settings.smooth">
</label>
<label>
Offset Max
<input v-model="settings.rotationOffset.max" type="number" :disabled="!settings.smooth">
</label>
<label>
Mitigation
<input v-model="settings.rotationMitigation" type="number" :disabled="!settings.smooth">
</label>
<h3>Debug</h3>
<label>
<input v-model="settings.debug.dataInspector" type="checkbox">
Data inspector
</label>
</div>
<div class="data-inspector" v-if="settings.debug.dataInspector">
<p>Mouse X: {{ mousePos.x }}</p>
<p>Mouse Y: {{ mousePos.y }}</p>
<p>Dragged card index: {{ draggedCardIdx }}</p>
<p>Pane overlapped index: {{ paneOverlappedIdx }}</p>
<p>Ghost card X: {{ ghostCardStyle.pos.x }}</p>
<p>Ghost card Y: {{ ghostCardStyle.pos.y }}</p>
<p>Mouse distance from middle: {{ ghostCardStyle.percentDistanceMiddle * 100 }}%</p>
<p>Ghost card rotation: {{ Math.round(ghostCardStyle.rotation * 100) / 100 }}</p>
<p>Motion velocity: {{ ghostCardStyle.velocity }}</p>
</div>
</div>

<script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/vue@2.6.1.js"></script>
<script >
const SETTINGS = {
  smooth: true,
  animateEnd: true,
  transfo.........完整代码请登录后点击上方下载按钮下载查看

网友评论0