A few days ago, did a mobile terminal drag jigsaw game, the need is to show the preview picture in the wheel, and then drag from the preview picture to the corresponding position, all drag to the corresponding position is completed, is the following page, feel very interesting, remember the idea, welcome to point out a better way.

Train of thought

First of all, of course, it is to confirm the general direction first. 12 pieces of puzzle, first of all, it is definitely need to have 12 holes placed the picture, look at the preview again, well, also is 12, that’s right, directly to display images in the preview, so as to specify the location of the direct access to current drag image address fill to the specified location is ok, the next is easy, Let’s write the HTML CSS first.

<div class=" puzzles_show_box" id="puzzles_show_box"> <div class="item item-1" id="puzzles_b_1"></div> <div class="item item-1" id="puzzles_b_2"></div> <div class="item item-1" id="puzzles_b_3"></div> <div class="item item-2" id="puzzles_b_4"></div> <div class="item item-2" id="puzzles_b_5"></div> <div class="item item-2" id="puzzles_b_6"></div> <div class="item item-3" id="puzzles_b_7"></div> <div class="item item-3" id="puzzles_b_8"></div> <div class="item item-3" id="puzzles_b_9"></div> <div class="item item-4" id="puzzles_b_10"></div> <div class="item item-4" id="puzzles_b_11"></div> <div class="item item-4" id="puzzles_b_12"></div> </div>Copy the code

Because the height of the row is different, we use different class to set the height and different ID to distinguish each cell.

<div class=" scroll_outside_box"> <div class="scroll-wrap"> <div class="scroll-box" id="puzzles_scroll_box"> <div class="item" data-index="2"><img id="puzzles_s_2" src="image/puzzles-img-1/img-2.png"></div> <div class="item" id="scroll_item_width" data-index="1"><img id="puzzles_s_1"  src="image/puzzles-img-1/img-1.png"></div> <div class="item" data-index="10"><img id="puzzles_s_10" src="image/puzzles-img-1/img-10.png"></div> <div class="item" data-index="6"><img id="puzzles_s_6" src="image/puzzles-img-1/img-6.png"></div> <div class="item" data-index="5"><img id="puzzles_s_5" src="image/puzzles-img-1/img-5.png"></div> <div class="item" data-index="4"><img id="puzzles_s_4" src="image/puzzles-img-1/img-4.png"></div> <div class="item" data-index="9"><img id="puzzles_s_9" src="image/puzzles-img-1/img-9.png"></div> <div class="item" data-index="7"><img id="puzzles_s_7" src="image/puzzles-img-1/img-7.png"></div> <div class="item" data-index="8"><img id="puzzles_s_8" src="image/puzzles-img-1/img-8.png"></div> <div class="item" data-index="11"><img id="puzzles_s_11" src="image/puzzles-img-1/img-11.png"></div> <div class="item" data-index="3"><img id="puzzles_s_3" src="image/puzzles-img-1/img-3.png"></div> <div class="item" data-index="12"><img id="puzzles_s_12" src="image/puzzles-img-1/img-12.png"></div> </div> </div> <div class="scroll-arrow scroll-arrow-1" id="scroll_arrow_left"><img src="image/arrow-left.jpg"></div> <div class="scroll-arrow scroll-arrow-2" id="scroll_arrow_right"><img src="image/arrow-right.jpg"></div> </div>Copy the code

There is no js random, manual random (. I _ I. Harm, first write the idea, and then optimize it later.

Ok, here is a big step, CSS those don’t stick, you can think about it, don’t want to, you can. Next, it’s JS’s turn.

let _show_width = $('#puzzles_b_1').outerWidth(true); OuterWidth (true); let _scroll_width = $('#scroll_item_width').outerWidth(true); Let _outside_box_width = $('#scroll_outside_box').outerWidth(true); Let _scroll_box_width = $('#puzzles_scroll_box').outerWidth(true); // Let _show_box_top = $('#puzzles_show_box').offset(). Top $('#scroll_outside_box').offset(). Top $('# puzzles_scroll_box.item '). Each (function(I) {let index = $(this).data('index') let scroll_img = document.getelementbyid (' puzzles_s_${index} ') let show_img = document.getElementById(`puzzles_b_${index}`) let scroll_img_left = $(this)[0].offsetLeft scroll_img.addEventListener('touchstart', function (e){ let ev = e || window.event; let touch = ev.targetTouches[0]; oL = touch.clientX - scroll_img.offsetLeft; oT = touch.clientY - scroll_img.offsetTop; document.addEventListener("touchmove", defaultEvent, false); }) scroll_img.addEventListener('touchmove', function (e) { let ev = e || window.event; ev.preventDefault() let touch = ev.targetTouches[0]; let oLeft = touch.clientX - oL; let oTop = touch.clientY - oT; scroll_img.style.left = oLeft + 'px'; scroll_img.style.top = oTop + 'px'; }) scroll_img.addEventListener('touchend', function (e) { let ev = e || window.event; let _top = scroll_img.offsetTop let _left = scroll_img.offsetLeft let _show_left = show_img.offsetLeft let _show_top = show_img.offsetTop let _show_height = show_img.offsetHeight let _diff_height = _scroll_box_top - _show_top let src = '' let _scroll_box_left = $('#puzzles_scroll_box').position().left let _move_left = _left + scroll_img_left + _scroll_box_left let img_move_left = _show_left - _show_width * .5 let img_move_right = _show_left + _show_width + _show_width * .5 if(_move_left >= img_move_left && _move_left <= img_move_right && Math.abs(_top) <= _diff_height + _show_width * .5 && Math.abs(_top) >= _diff_height - _show_height - _show_width * .5) { src = scroll_img.getAttribute('src') $(`#puzzles_b_${index}`).append(`<img src="${src}">`) scroll_img.style.opacity = 0 if($('#puzzles_show_box img').length == 12) { $('#puzzles_success_box').removeClass('hide').addClass('show') $('#puzzles_note_show').show() $('#puzzles_scroll_hide').hide() setTimeout(function() { $('#puzzles_success_box, #puzzles_show_box').removeClass('show').addClass('hide') $('#puzzles_success_img').removeClass('hide').addClass('show') }, 1000) } } else { scroll_img.style.left = 0; scroll_img.style.top = 0; } }) }) function defaultEvent(e) { e.preventDefault(); }Copy the code

When touchStart is performed, the top and left values of the current position are calculated

When touchmove, subtract the initial value from the current top and left of the move, and get the difference of the move is the top and left of the relative move of the picture

So when you do touchEnd, the main thing is to calculate whether or not you’re in a given grid, and the _move_left field is just to calculate where you’re dragging the image, Left + initial position of the preview left+ scroll box The current left is the relative left of the display box, then calculate the left and right of the specified grid (up to myself, I used half of the width of the display grid to calculate), The left-most cell is 0.5, and the right-most cell is left+ width + 0.5, so as long as the left-most <= _move_left <= right-most, you are in the left and right of the cell. Abs (_top) <= abs(_top) <= abs(_top) <= abs(_top) In this case, just take the preview layer offsetTop – the offsetTop of the grid (also known as _diff_height) to get the distance between the preview image and the display grid, then calculate the top and bottom maximum value, the top should be _diff_height + the grid height 0.5, At the bottom is _diff_height – grid height – grid height 0.5, when the drag coordinate is in this range, it can be filled. Take the address of the image being dragged, fill it with the corresponding ID, and make the dragged image transparent so that it will not block the display grid. When the image length in the grid is ==12, it means that the filling is complete