简单的html拼图特效

740 阅读2分钟

3ccb6f1e-7ee3-4cd0-8729-6b8da3aa118d.gif

html-拼图特效

作者:fengfanv

Tips:

  • 欢迎 客官 您的 光临,文章如果对您有帮助,欢迎 点赞评论,让更多的人看到,万分感谢。

Demo 注意事项

  • Demo 是用Vue编写的,使用时需要先引用Vue。
<script src="https://unpkg.com/vue@next"></script>
  • Demo 样式是基于 移动端750设计图尺寸 编写的,使用时需要设置
<html style="font-size: calc(100vw / 750 * 100);"></html>
  • 引用 Demo 时,需要重新设置一下,图片的大小,否则拼图上的图片会被扭曲显示。

Demo 源码:

  • demo.html
<div id="app">
    <!--拼图区域-->
    <div class="card_frame">
    </div>
    <!--存放拼图碎片的区域-->
    <div class="card_fragment">
        <ul>
            <li
                v-for="(item, index) in list"
                :key="index"
                :style="{
                    width: item.width + 'px',
                    height: item.height + 'px',
                    left: (current_fragment_id == item.id? current_left : item.current_left) + 'px',
                    top: (current_fragment_id == item.id ? current_top : item.current_top) + 'px',
                    'box-shadow': current_fragment_id == item.id && current_fragment_position_status ? '0 0 1rem green' : '0 0 0',
                    border: current_fragment_id == item.id && current_fragment_position_status ? '0.04rem solid green' : '0.04rem solid black',
                    transition: current_fragment_id == item.id ? '0s' : '0.2s',
                    'z-index': current_fragment_id == item.id ? '999' : '0',
                    background: item.background,
                    'background-position': '-' + item.one_left + 'px -' + item.one_top + 'px'
                }"
                @touchstart.stop.prevent="touchstart($event, item, index)"
                @touchmove.stop.prevent="touchmove($event, item, index)"
                @touchend.stop.prevent="touchend($event, item, index)"
            >
                <p>{{ index + 1 }}</p>
            </li>
        </ul>
    </div>
</div>
  • demo.js
Vue.createApp({
    data() {
        return {
            list: [], //拼图碎片list
            current_fragment_id: null, //当前移动中的碎片id
            current_fragment_position_status: false, //当前移动中的碎片,位置是否是到达,要放的位置,是的话,变成绿色,不是不变
            startPageX: 0,
            startPageY: 0,
            current_left: 0,
            current_top: 0,
            allfinish: false, //全部拼完
        }
    },
    mounted() {
        setTimeout(() => {
            this.init()
        }, 1000)
    },
    methods: {
        //拼图初始化方法
        init() {
            let _this = this;
            //1、把碎片内数组内的设计图尺寸转换成 当前设备下的 真实尺寸

            //拼图的区域:one_parent
            _this.one_parent_left = (window.innerWidth / 750) * 100 * 1.44;//拼图区域,距离页面最左边的位置
            _this.one_parent_top = (window.innerWidth / 750) * 100 * 1.78;//拼图区域,距离页面最顶部的位置

            //存放碎片的区域:two_parent
            let two_parent_left = (window.innerWidth / 750) * 100 * 0.26;//存放碎片区域,距离页面最左边的位置
            let two_parent_top = (window.innerWidth / 750) * 100 * (1.78 + 0.04 + 6.62 + 0.04 + 1.2 + 0.04);//存放碎片区域,距离页面最顶部的位置
            let two_parent_width = (window.innerWidth / 750) * 100 * 7;//存放碎片区域,宽度

            //2、初始化,碎片list 与 拼图的图片
            let list = fragment1;
            let len = list.length;

            let imgurl = './艾索德.png';

            //3、处理碎片list
            for (let i = 0; i < len; i++) {
                //当前碎片的大小,转换成,当前设备上,真实大小
                list[i].width = (window.innerWidth / 750) * 100 * list[i].width;
                list[i].height = (window.innerWidth / 750) * 100 * list[i].height;
                list[i].one_left = (window.innerWidth / 750) * 100 * list[i].one_left;
                list[i].one_top = (window.innerWidth / 750) * 100 * list[i].one_top;

                //初始化当前碎片的位置
                list[i].two_left = two_parent_left + (two_parent_width / 5) * i;
                list[i].two_top = two_parent_top;
                list[i].current_left = list[i].two_left;
                list[i].current_top = list[i].two_top;

                list[i].background = "url(" + imgurl + ") no-repeat white";

                if (i == 0 || i == len - 1) {
                    //先放两个碎片,到拼图区域
                    list[i].current_left = _this.one_parent_left + list[i].one_left;
                    list[i].current_top = _this.one_parent_top + list[i].one_top;
                    list[i].finish = true;
                } else {
                    let num = 0;
                    if (i == 1) {
                        num = 0;
                    } else if (i == 2) {
                        num = 1;
                    } else if (i == 3) {
                        num = 2;
                    }
                    //这个碎片list一共有5个碎片,上面已经放了2,还剩下三个,这里是设置这三个,在存放碎片区域的位置
                    list[i].two_left = two_parent_left + list[0].width * num;
                    list[i].current_left = list[i].two_left;
                }
            }
            this.list = list;
        },
        //碎片,触摸开始
        touchstart(e, item) {
            if (item.finish == false) {
                this.startPageX = e.changedTouches[0].pageX;
                this.startPageY = e.changedTouches[0].pageY;

                this.current_left = item.current_left;
                this.current_top = item.current_top;

                this.current_fragment_id = item.id;
            }
        },
        //碎片,触摸移动
        touchmove(e, item, index) {
            let _this = this;
            if (item.finish == false) {
                let list = _this.list;

                let pageX = e.changedTouches[0].pageX;
                let pageY = e.changedTouches[0].pageY;

                if (_this.current_fragment_id != null) {
                    //移动的距离
                    let moveX = pageX - _this.startPageX;
                    let moveY = pageY - _this.startPageY;

                    _this.current_left = _this.list[index].current_left + moveX;
                    _this.current_top = _this.list[index].current_top + moveY;

                    this.current_fragment_position_status = false;

                    //检测当前移动中的碎片,位置,是否是,碎片要放的位置
                    let check_left = _this.one_parent_left + list[index].one_left - 20;
                    let check_right = _this.one_parent_left + list[index].one_left + list[index].width;
                    let check_top = _this.one_parent_top + list[index].one_top - 20;
                    let check_bottom = _this.one_parent_top + list[index].one_top + list[index].height;

                    if (_this.current_left >= check_left && _this.current_left < check_right) {
                        if (_this.current_top >= check_top && _this.current_top < check_bottom) {
                            _this.current_fragment_position_status = true;
                        }
                    }
                }
            }
        },
        //触摸结束
        touchend(e, item, index) {
            let _this = this;
            if (item.finish == false) {
                //检测当前移动中的碎片,位置,是否是,要放的位置
                if (_this.current_fragment_position_status == true) {
                    _this.list[index].current_left = _this.one_parent_left + _this.list[index].one_left;
                    _this.list[index].current_top = _this.one_parent_top + _this.list[index].one_top;
                    _this.list[index].finish = true;

                    //检测碎片是否都拼完成了
                    let len = _this.list.length;
                    let num = 0;
                    for (let i = 0; i < len; i++) {
                        if (_this.list[i].finish) {
                            num++;
                        }
                    }
                    if (num == len) {
                        console.log("全部拼完!");
                        _this.allfinish = true;
                    }
                }
                _this.current_fragment_position_status = false;
                _this.current_fragment_id = null;
            }
        },

    }
}).mount("#app");

//图的碎片数组
var fragment1 = [
    {
        id: 0,
        width: 2.29,//碎片大小
        height: 3.31,
        one_left: 0, //完成时的位置
        one_top: 0, //完成时的位置
        current_left: 0, //当前位置
        current_top: 0, //当前位置
        two_left: 0, //未完成时的位置
        two_top: 0, //未完成时的位置
        finish: false,//碎片是否已经拼到相应位置
    },
    {
        id: 1,
        width: 2.29,
        height: 3.31,
        one_left: 0,
        one_top: 3.31,
        current_left: 0,
        current_top: 0,
        two_left: 0,
        two_top: 0,
        finish: false,
    },
    {
        id: 2,
        width: 2.29,
        height: 2.2,
        one_left: 2.29,
        one_top: 0,
        current_left: 0,
        current_top: 0,
        two_left: 0,
        two_top: 0,
        finish: false,
    },
    {
        id: 3,
        width: 2.29,
        height: 2.2,
        one_left: 2.29,
        one_top: 2.2,
        current_left: 0,
        current_top: 0,
        two_left: 0,
        two_top: 0,
        finish: false,
    },
    {
        id: 4,
        width: 2.29,
        height: 2.2,
        one_left: 2.29,
        one_top: 4.4,
        current_left: 0,
        current_top: 0,
        two_left: 0,
        two_top: 0,
        finish: false,
    },
];
  • demo.css
* {
    margin: 0;
    padding: 0;
}

/*拼图的区域*/
.card_frame {
    width: 4.58rem;
    height: 6.62rem;
    margin: 0 auto;
    margin-top: 1.78rem;
    background: white;
    border: 0.04rem solid black;
}

/*存放拼图碎片的区域*/
.card_fragment {
    width: 7rem;
    height: 3rem;
    margin: 0 auto;
    margin-top: 1.2rem;
    background: #fed929;
    border: 0.04rem solid black;
}

/*碎片样式*/
.card_fragment li {
    display: flex;
    align-items: center;
    position: absolute;
    border: 0.04rem solid black;
    background: white;
    color: black;
    text-align: center;
    font-weight: bold;
    background-size: 4.58rem 6.62rem !important;
    background: white;
}