순수한 CSS를 사용하여 직소 퍼즐을 구현할 수도 있다는 것이 밝혀졌습니다! 이 기사에서는 여러 CSS 기술을 극한까지 사용하고 순수 CSS를 사용하여 직소 퍼즐을 구현하는 기술을 소개합니다.
이 팁은 Temani Afif의 CodePen CSS 전용 퍼즐 게임에서 나온 것입니다. 전적으로 CSS로 구현된 퍼즐 게임입니다.
우리가 해야 할 일은 다음과 같이 흩어진 이미지 조각을 완전한 이미지로 복원하는 것입니다.
이것은 CSS로 완전히 구현된다는 점에 유의하세요. 핵심 난이도를 분석해 보겠습니다.
만드는 방법. 드래그 가능한 요소?
고정 위치에서 요소를 드래그하여 요소를 다른 위치에 유지하는 방법은 무엇입니까?
가장 어려운 점은 (2)를 기준으로 요소를 드래그했다가 놓으면 특정 위치에 놓을 때만 요소가 새 위치에 고정되고, 그렇지 않으면 원래 위치로 돌아갑니다. 원래 입장
아뇨, 위의 (2)와 (3)은 간단한 CSS로 해결할 수 있는 문제는 아닌 것 같습니다.
그럼 어떻게 하면 이들을 교묘하게 일치시키고 결합하고 최종적으로 CSS를 사용하여 이러한 효과를 얻을 수 있을까요? 프로세스를 단계별로 분석해 보겠습니다.
위의 첫 번째 사항을 토대로 요소를 드래그 가능하게 만드는 방법이 가장 해결하기 쉽습니다.
HTML5에서는 새로운 draggable
속성이 태그에 추가됩니다. 이 속성을 true
로 설정하면 요소의 드래그 가능 효과를 얻을 수 있습니다. draggable
属性,设置为 true
后,即可实现元素的拖拽效果。
简单而言:
<div>draggable false</div> <div draggable="true">draggable true</div>
我们实现这样两个 div,其中第二个设置了 draggable="true"
:
设置了 draggable="true"
的元素,长按住鼠标即可拖动元素:
这样,拖动的问题就解决了。CodePen Demo -- HTML draggable Demo
OK,接下来的难点就在于,如何将元素从位置A移动到位置B。
这里的核心在于,巧妙的应用 transition
元素。
我们来看这样一个例子,如果有一个元素,已经偏移了 translate(120px, 120px)
,我们 hover 这个元素的时候,让它回到原来的位置:
div { transform: translate(120px, 120px); } div:hover { transform: translate(0, 0); }
效果如下:
这里很有意思的是:
当我们 hover 元素,元素归位
由于元素归位,失去了 hover 的状态,又变回了原来状态,然后又重新触发了 hover 状态,如此反复,所以会看到剧烈的跳动
那,有没有办法让它复位了就不再跳回来呢?
可以的,我们可以通过设置一个非常大的 transition-duraiotn
和一个非常大的 transition-delay
,让整个过渡效果变得非常缓慢,慢到我们察觉不到:
div { transform: translate(120px, 120px); transition: 999999s 999999s; } div:hover { transform: translate(0, 0); transition: 0s; }
如此一来,元素复位了之后,就再也不会跳回来了(理论上):
如果,我们把上述的 transition: 999999s 999999s
,也就过渡持续时间与过渡延迟时间**设置短一点,譬如都设置为 2s 的话 transition: 2s 2s
<div class="g-wrap"> <div class="g-flag">FLAG</div> <div class="g-box" draggable="true"></div> </div>
draggable="true"
로 설정됩니다.
draggable="true"
가 설정된 요소, 길게 누르기 그냥 마우스를 누른 채 요소를 드래그하세요. 이렇게 하면 드래그 문제가 해결됩니다. CodePen 데모 -- HTML 드래그 가능 데모
여기서 핵심은 transition
요소를 영리하게 적용한 것입니다.
translate(120px, 120px)
로 오프셋된 요소가 있는 경우 이 요소에 마우스를 가져가면 원래 위치로 돌아갑니다. 🎜.g-flag:hover ~ .g-box { transform: translate(0, 0); transition: 0s; } .g-box { width: 120px; height: 120px; background: #000; transform: translate(120px, 120px); transition: 9999s 9999s; }
transition-duraiotn
및 매우 큰 transition-delay
를 설정하여 전체 전환 효과를 매우 느리게 만들 수 있습니다. 🎜 <div class="g-wrap"> <div class="g-flag">FLAG</div> <div class="g-box" draggable="true"></div> </div>
전환: 999999s 999999s
를 변경하면 전환 기간이 됩니다. 🎜전환 지연 시간**을 더 짧게 설정하세요. 예를 들어 둘 다 2s, transition: 2s 2s
로 설정하면 효과는 다음과 같습니다. 🎜🎜🎜🎜🎜이렇게 하면 무슨 일이 일어나고 있는지 대략적으로 이해할 수 있을 것입니다. 🎜🎜 :active pseudo-class🎜🎜를 통해 트리거를 구현합니다. 물론 위의 지식만으로는 충분하지 않습니다. 🎜🎜우선, 요소의 이동은 호버에 의한 것이 아니라, 특정 위치로 드래그한 후 마우스의 드래그 효과를 놓으면 요소가 이동됩니다. 또한 요소는 특정 위치에서 놓을 때만 이동할 수 있습니다. 🎜🎜이것은 어떻게 달성됩니까? 여기서도 🎜이벤트🎜 버블링을 통과해야 합니다. 🎜🎜간단히 코드를 수정하고 해당 요소에 상위 요소를 추가한 다음 마크 요소를 추가해 보겠습니다. 🎜<div class="g-wrap"> <div class="g-flag">FLAG</div> <div class="g-box" draggable="true"></div> </div>
.g-flag:hover ~ .g-box { transform: translate(0, 0); transition: 0s; } .g-box { width: 120px; height: 120px; background: #000; transform: translate(120px, 120px); transition: 9999s 9999s; }
其中,.g-flag
是我们实现的一个触发器,我们不再通过 hover 元素本身实现元素的移动,而是通过 hover 这个特殊的触发器来实现元素的移动,这个应该很好理解:
好!最为关键的步骤来了!
我们需要通过事件的冒泡,当开始拖拽 .g-box
元素本身的时候,才让我们的触发器显现,并且设置一个极为短暂的停留时间,这样让鼠标放下的一瞬间,触发元素的复位。
什么意思呢?看看效果图:
核心代码如下:
<div class="g-wrap"> <div class="g-flag">FLAG</div> <div class="g-box" draggable="true"></div> </div>
.g-wrap { position: relative; width: 120px; height: 120px; } .g-box { width: 120px; height: 120px; background: #000; transform: translate(120px, 120px); transition: 9999s 9999s; } .g-flag { position: absolute; width: 0; height: 0; top: -100px; left: -100px; transition: 0 0.5s; } .g-wrap:active .g-flag { border: 1px dashed #000; width: 100px; height: 100px; } .g-flag:hover ~ .g-box { transform: translate(0, 0); transition: 0s; }
这里运用到非常核心的一点是,在拖拽 .g-box
元素的过程中,触发了它的 :active
事件,同时,这个事件还会冒泡到它的父元素 .g-wrap
上。利用事件的冒泡,我们可以让元素在拖拽的过程中,让触发器显示,并且通过鼠标释放后立即触发了触发器的 hover 事件,让元素从位置 A,移动到了位置 B,实在是妙不可言!
最后,我们只需要让触发器的位置,与我们希望元素去到的位置,保持一致,即可实现拼图的原理:
完整的单个元素从 A 点通过拖拽到移动到 B 点的 DEMO,你可以戳这里:CodePen Demo -- HTML draggable Demo
掌握了上述的原理后,上述的拼图游戏的就迎刃而解了。感兴趣的可以去看看它的源码:CSS Only Puzzle game。剩下的大部分工作在于,将完整的图片切割成不同份数,随机放置不同到不同的位置。
这里,借助同样的原理,我再给出一个类似的 DEMO,一个简单的拼字游戏,给出完整的代码:
<p class="source">请把文字摆放到正确的位置:橘皮乌龙</p> <div class="g-container"> <div class="g-wrap"> <div class="g-flag"></div> <div class="g-box" draggable="true">橘</div> </div> <div class="g-wrap"> <div class="g-flag"></div> <div class="g-box" draggable="true">皮</div> </div> <div class="g-wrap"> <div class="g-flag"></div> <div class="g-box" draggable="true">乌</div> </div> <div class="g-wrap"> <div class="g-flag"></div> <div class="g-box" draggable="true">龙</div> </div> </div>
.g-container { display: flex; width: 400px; height: 100px; } .g-wrap { position: relative; margin: auto; width: 100px; height: 100px; border: 1px dashed #000; box-sizing: border-box; } .g-flag { position: absolute; top: 0; left: 0; width: 0; height: 0; background: rgba(0, 0, 0, .15); } .g-box { width: 100%; height: 100%; background-color: #000; cursor: grab; color: #fff; text-align: center; line-height: 100px; font-size: 48px; } .g-wrap:active .g-flag { width: 100%; height: 100%; } @for $i from 1 to 5 { .g-wrap:nth-child(#{$i}) .g-box { transform: rotate(#{random(180)}deg) translate(#{random(400) - 150}px, #{random(100) + 60}px); } } .g-box { transition: 99999s 999999s; } .g-flag:hover + .g-box { transform: translate(0, 0); transition: 0s; }
为了方便理解,每次拖拽元素的时候,需要放置的位置都会被高亮,当然,这一点提示效果完全是可以去掉的:
完整的 DEMO,你也可以戳这里 CodePen Demo -- Pure CSS Spelling game
在上述的代码中,我们利用了 SASS 快速实现了不同块的文字的位置的随机摆放,增加一定的随机性。同时,利用 SASS 减少了一些重复性代码的工作量。
原文地址:https://www.cnblogs.com/coco1s/p/16615333.html
作者:ChokCoco
更多编程相关知识,请访问:编程视频!!
위 내용은 순수 CSS를 사용하여 직소 퍼즐을 구현할 수도 있다는 것이 밝혀졌습니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!