0


前端vue3——实现二次元人物拼图校验

文章目录

yma16-logo

⭐前言

大家好,我是yma16,本文分享关于 前端vue3——实现二次元人物拼图校验。
vue3系列相关文章:
vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
前端vue2、vue3去掉url路由“ # ”号——nginx配置
csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板
认识vite_vue3 初始化项目到打包
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容
前端vue3——html2canvas给网站截图生成宣传海报
拖拽相关文章
前端——html拖拽原理

前端html拖拽原理
HTML 拖拽的基本原理是通过鼠标事件和 DOM 操作来实现的。

一般来说,拖拽操作包括三个阶段:

  1. 鼠标按下事件:当用户按下鼠标左键时,触发鼠标按下事件。在该事件处理函数中,首先需要记录下被拖拽元素的相关信息,比如该元素的位置、大小和初始鼠标点击位置等。
  2. 鼠标移动事件:当用户按下鼠标左键时并拖动鼠标时,触发鼠标移动事件。在该事件处理函数中,需要根据鼠标当前位置和拖拽元素的初始位置,计算出该元素要被移动的距离,并在 DOM 中更新该元素的位置。
  3. 鼠标松开事件:当用户松开鼠标左键时,触发鼠标松开事件。在该事件处理函数中,需要清除拖拽元素的相关信息,比如初始鼠标点击位置等。

在以上三个阶段中,需要使用的 DOM 操作包括:

  1. 获取 DOM 元素:可以使用 document.getElementById() 或 document.querySelector() 等方法来获取需要拖拽的元素。
  2. 更新元素位置:可以使用元素的 style 属性来修改元素的位置,比如设置元素的 left 和 top 属性。
  3. 创建新元素:可以使用 document.createElement() 方法来创建新的 DOM 元素。

通过以上鼠标事件和 DOM 操作的组合,可以实现基本的 HTML 拖拽功能。

⭐vue3拖拽实现拼图

使用vue3和原生的html drag 实现片的拖拽

💖 思路分解

  1. 拆分图片为4宫格样式
  2. 定义拖拽的样式div对应图片的4宫格
  3. 定义拖拽的div元素,背景图片使用图片拆分的素材
  4. 给元素定义序号
  5. 校验最终的元素序号,判断是否拼图成功

拆分图片
split-image

💖 布局结构

才有左右布局
左侧:拖拽来源区域
右侧:拖拽放入区域
template布局

<template><divclass="container-drag"><divstyle="width: 100%;text-align:center;margin: 10px;"><a-buttontype="primary"class="random-button"@click="randomDragOrder">随机顺序</a-button></div><divclass="container-drag-box"><divclass="container-drag-left"><!-- <> --><divv-for="item in state.dragConfig.sourceArray":key="item.id"class="drag-item-box":id="state.dragConfig.sourceDomPrefix + '-' + item.id"><divclass="drag-item"draggable="true":id="state.dragConfig.dragDomPrefix + '-' + item.id"><!-- 拖拽对象 data-order 校验排序用 --><img:src="item.src"width="280"height="280":data-order="item.id"/></div></div></div><divclass="container-drag-right"id="target-box-id"><!-- 目标对象 data-order 校验排序用--><divv-for="item in state.dragConfig.sourceArray":key="item"class="target-item-box dropzone":id="state.dragConfig.targetDomPrefix + '-' + item.id":data-order="item.id"></div></div></div><divstyle="width: 100%;text-align:center"><a-buttontype="primary"@click="confirmImg">
                确定
            </a-button></div></div></template>

css配置

<style>.container-drag{min-width: 800px;}.random-button{margin: 5px;cursor: pointer;}.container-drag-box{display: flex;justify-content: space-between;}.container-drag-left{width: 800px;}.container-drag-right{width: 600px;height: 600px;margin: 0;}.drag-item-box{display: inline-block;margin: 2px;padding: 0;width: 280px;height: 280px;border: 1px solid rgb(24, 144, 255);overflow: hidden;}.target-item-box{display: inline-block;width: 280px;height: 280px;border: 1px solid rgb(255, 255, 255);box-sizing: border-box;overflow: hidden;margin-right: 5px;margin-bottom: 0;margin-top: 0;}/* 拖拽对象 */.drag-item{margin: 0;text-align: center;cursor: pointer;}/* 拖拽中 */.dragging{opacity: .5;}/* 悬浮上方 */.dragover{background:rgba(0,255,0,.5);}</style>

布局效果
box-left

💖 拖拽函数

拖拽对象配置方法

drag,dragstart,dragend

放入区域配置方法

drop,dragover,dragleave,dragenter
// 拖拽对象constdrag=(event)=>{
    console.log("dragging", event);}constdragStart=(event)=>{// 保存被拖动元素的引用
    state.dragConfig.dragTarget = event.target;// 设置为半透明
    event.target.classList.add("dragging");}constdragEnd=(event)=>{// 拖动结束,重置透明度
    event.target.classList.remove("dragging");}// 目标对象constdragOver=(event)=>{// 阻止默认行为以允许放置
    event.preventDefault();}constdragLeave=(event)=>{// 在可拖动元素离开潜在放置目标元素时重置该目标的背景if(event.target.classList.contains("dropzone")){
        event.target.classList.remove("dragover");}}constdragEnter=(event)=>{// 在可拖动元素进入潜在的放置目标时高亮显示该目标if(event.target.classList.contains("dropzone")){
        event.target.classList.add("dragover");}}constdrop=(event)=>{// 阻止默认行为(会作为某些元素的链接打开)
    event.preventDefault();// 将被拖动元素移动到选定的目标元素中if(event.target.classList.contains("dropzone")){
        event.target.classList.remove("dragover");// 删除自身
        state.dragConfig.dragTarget.parentNode.removeChild(state.dragConfig.dragTarget);// 添加元素
        event.target.appendChild(state.dragConfig.dragTarget);}}constinitDragAction=(sourceElement)=>{if(!sourceElement){return}/* 在放置拖拽对象上触发的事件 */
    sourceElement.addEventListener("drag", drag);

    sourceElement.addEventListener("dragstart", dragStart);

    sourceElement.addEventListener("dragend", dragEnd);}constinitTargetAction=(targetElement)=>{if(!targetElement){return}/* 在放置目标对象上触发的事件 */

    targetElement.addEventListener("dragover",
        dragOver,false,);

    targetElement.addEventListener("dragenter", dragEnter);

    targetElement.addEventListener("dragleave", dragLeave);

    targetElement.addEventListener("drop", drop);}

💖 校验函数

遍历dom节点获取自定义的

data-order

属性进行校验

// 校验constconfirmImg=()=>{const rightDom = document.getElementById('target-box-id')
    console.log('rightDom', rightDom)const rightDomChildNodes = rightDom.childNodes
    console.log('rightDomChildNodes', rightDomChildNodes)if(rightDomChildNodes.length){// childNodes会出现空文本节点for(let i =0, length = rightDomChildNodes.length; i < length;++i){
            console.log('childNodes', rightDomChildNodes[i])if(rightDomChildNodes[i].nodeType !==1){// 跳过文本节点continue}elseif(rightDomChildNodes[i].hasChildNodes){
                console.log('childNodes attr', rightDomChildNodes[i])const currentDataOrder = rightDomChildNodes[i].getAttribute('data-order')const imgDataOrder = rightDomChildNodes[i].getElementsByTagName('img')[0].getAttribute('data-order')
                console.log('currentDataOrder', currentDataOrder)
                console.log('imgDataOrder', imgDataOrder)if(currentDataOrder !== imgDataOrder){return message.warn('拼图位置错误:\t第'+ currentDataOrder+'张图片')}}else{return message.warn('没有完成拼图,请拖拽图片')}}}else{return message.warn('没有完成拼图,请拖拽图片')}return'恭喜你完成拼图'}

💖 inscode整体代码

完整的vue代码

<template><div class="container-drag"><div style="width: 100%;text-align:center;margin: 10px;"><a-button type="primary"class="random-button" @click="randomDragOrder">随机顺序</a-button></div><div class="container-drag-box"><div class="container-drag-left"><!--<>--><div v-for="item in state.dragConfig.sourceArray":key="item.id"class="drag-item-box":id="state.dragConfig.sourceDomPrefix + '-' + item.id"><div class="drag-item" draggable="true":id="state.dragConfig.dragDomPrefix + '-' + item.id"><!-- 拖拽对象 data-order 校验排序用 --><img :src="item.src" width="280" height="280":data-order="item.id"/></div></div></div><div class="container-drag-right" id="target-box-id"><!-- 目标对象 data-order 校验排序用--><div v-for="item in state.dragConfig.sourceArray":key="item"class="target-item-box dropzone":id="state.dragConfig.targetDomPrefix + '-' + item.id":data-order="item.id"></div></div></div><div style="width: 100%;text-align:center"><a-button type="primary" @click="confirmImg">
                确定
            </a-button></div></div></template><script setup>import{ reactive, onMounted }from'vue'import{ message }from'ant-design-vue'const state =reactive({dragConfig:{sourceDomPrefix:'source-item',targetDomPrefix:'target-item',dragDomPrefix:'drag-item',dragTarget:null,sourceImg:'/img/imageSource.png',sourceArray:[{id:1,src:'/img/image1.png'},{id:2,src:'/img/image2.png'},{id:3,src:'/img/image3.png'},{id:4,src:'/img/image4.png'},]}})// 数组随机顺序constrandomDragOrder=()=>{const sourceArray =[...state.dragConfig.sourceArray]
    sourceArray.sort(()=> Math.random()-0.5);
    state.dragConfig.sourceArray = sourceArray
}// 拖拽对象constdrag=(event)=>{
    console.log("dragging", event);}constdragStart=(event)=>{// 保存被拖动元素的引用
    state.dragConfig.dragTarget = event.target;// 设置为半透明
    event.target.classList.add("dragging");}constdragEnd=(event)=>{// 拖动结束,重置透明度
    event.target.classList.remove("dragging");}// 目标对象constdragOver=(event)=>{// 阻止默认行为以允许放置
    event.preventDefault();}constdragLeave=(event)=>{// 在可拖动元素离开潜在放置目标元素时重置该目标的背景if(event.target.classList.contains("dropzone")){
        event.target.classList.remove("dragover");}}constdragEnter=(event)=>{// 在可拖动元素进入潜在的放置目标时高亮显示该目标if(event.target.classList.contains("dropzone")){
        event.target.classList.add("dragover");}}constdrop=(event)=>{// 阻止默认行为(会作为某些元素的链接打开)
    event.preventDefault();// 将被拖动元素移动到选定的目标元素中if(event.target.classList.contains("dropzone")){
        event.target.classList.remove("dragover");// 删除自身
        state.dragConfig.dragTarget.parentNode.removeChild(state.dragConfig.dragTarget);// 添加元素
        event.target.appendChild(state.dragConfig.dragTarget);}}constinitDragAction=(sourceElement)=>{if(!sourceElement){return}/* 在放置拖拽对象上触发的事件 */
    sourceElement.addEventListener("drag", drag);

    sourceElement.addEventListener("dragstart", dragStart);

    sourceElement.addEventListener("dragend", dragEnd);}constinitTargetAction=(targetElement)=>{if(!targetElement){return}/* 在放置目标对象上触发的事件 */

    targetElement.addEventListener("dragover",
        dragOver,false,);

    targetElement.addEventListener("dragenter", dragEnter);

    targetElement.addEventListener("dragleave", dragLeave);

    targetElement.addEventListener("drop", drop);}// 校验constconfirmImg=()=>{const rightDom = document.getElementById('target-box-id')
    console.log('rightDom', rightDom)const rightDomChildNodes = rightDom.childNodes
    console.log('rightDomChildNodes', rightDomChildNodes)if(rightDomChildNodes.length){// childNodes会出现空文本节点for(let i =0, length = rightDomChildNodes.length; i < length;++i){
            console.log('childNodes', rightDomChildNodes[i])if(rightDomChildNodes[i].nodeType !==1){// 跳过文本节点continue}elseif(rightDomChildNodes[i].hasChildNodes){
                console.log('childNodes attr', rightDomChildNodes[i])const currentDataOrder = rightDomChildNodes[i].getAttribute('data-order')const imgDataOrder = rightDomChildNodes[i].getElementsByTagName('img')[0].getAttribute('data-order')
                console.log('currentDataOrder', currentDataOrder)
                console.log('imgDataOrder', imgDataOrder)if(currentDataOrder !== imgDataOrder){return message.warn('拼图位置错误:\t第'+ currentDataOrder+'张图片')}}else{return message.warn('没有完成拼图,请拖拽图片')}}}else{return message.warn('没有完成拼图,请拖拽图片')}return'恭喜你完成拼图'}// 生命周期onMounted(()=>{// 拖拽对象const dragArr = state.dragConfig.sourceArray.map(item=>{return state.dragConfig.dragDomPrefix +'-'+ item.id
    })
    dragArr.forEach(id=>{initDragAction(document.getElementById(id))})// 目标对象const sourceArr = state.dragConfig.sourceArray.map(item=>{return state.dragConfig.sourceDomPrefix +'-'+ item.id
    })
    sourceArr.forEach(id=>{initTargetAction(document.getElementById(id))})const targetArr = state.dragConfig.sourceArray.map(item=>{return state.dragConfig.targetDomPrefix +'-'+ item.id
    })
    targetArr.forEach(id=>{initTargetAction(document.getElementById(id))})})</script><style>.container-drag {

    min-width: 800px;}.random-button {margin: 5px;cursor: pointer;}.container-drag-box {display: flex;
    justify-content: space-between;}.container-drag-left {width: 800px;}.container-drag-right {width: 600px;height: 600px;margin:0;}.drag-item-box {display: inline-block;margin: 2px;padding:0;width: 280px;height: 280px;border: 1px solid rgb(255,255,255);overflow: hidden;}.target-item-box {display: inline-block;width: 280px;height: 280px;border: 1px solid rgb(255,255,255);
    box-sizing: border-box;overflow: hidden;
    margin-right: 5px;
    margin-bottom:0;
    margin-top:0;}/* 拖拽对象 */.drag-item {margin:0;
    text-align: center;cursor: pointer;}/* 拖拽中 */.dragging {opacity:.5;}/* 悬浮上方 */.dragover {background:rgba(0,255,0,.5);}</style>

代码放在inscode vue3项目在线运行

⭐运行效果

💖 随机顺序

random

💖 拖拽中

draging

💖 校验失败

verrify-error

💖 校验通过

verrify-success
拖拽过程截图

drag-process

⭐总结

拼图校验总结:

1.校验的顺序可以用元素的attribute传递位置顺序进行标记
2.拖拽对象的函数使用 拖拽对象配置方法

drag,dragstart,dragend

放入区域配置方法

drop,dragover,dragleave,dragenter

拖拽总结:

在HTML中,拖放(drag and
drop)是一种用户界面交互的特定形式,其中用户可以拖动元素或数据并将其放置在另一个位置。以下是HTML拖放的一些总结:

  1. 拖放可用于各种用途,例如重新排序列表,将文本或文件拖动到另一个应用程序中,或从文件资源管理器将文件拖动到Web页面中。
  2. 在HTML中,拖放API由一些事件组成,包括dragstart、dragenter、dragover、dragleave、drop和dragend。
  3. 通过使用HTML data属性,可以将数据附加到拖动事件,并在放置事件中访问它们。
  4. 通过使用CSS,可以为用户拖动时显示的元素创建自定义外观。
  5. 在JavaScript中,可以使用dragEvent对象来访问有关拖动和放置事件的详细信息,例如拖动元素的位置和放置元素的位置。
  6. 可以使用HTML5的拖放API创建复杂的拖放交互,例如可拖动的图形和对象,将元素沿路径拖动等。

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
cute-img

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!

标签: 前端 javascript vue3

本文转载自: https://blog.csdn.net/qq_38870145/article/details/134895099
版权归原作者 yma16 所有, 如有侵权,请联系我们删除。

“前端vue3——实现二次元人物拼图校验”的评论:

还没有评论