Jump to content
Search Community

SamuelMb

Premium
  • Posts

    2
  • Joined

  • Last visited

About SamuelMb

  • Birthday 07/12/1994

Contact Methods

  1. Explanation I was under the wrong impression that If I passed a selector into the hitTest then it would do the hit test against every element that fit the selector. In which case I dont neccesarily have the element when I execute the hitTest() I just have a selector which might fit many diffirent elements and I want to return the element of that selector that was actually hit. Anyway, I realize now that this is not actually how the hitTest() works and Ive finished my solution. Thanks for your help. Your suggestions where very helpfull for much of my experimentation. Issue Resolved I experimented with a lot of diffirent ways of doing it using the liveSnap property. But nothing quite did all the things I wanted with the flexibility I was looking for. Instead I ended up bringing in the flip plugin and just using that to create my own snapping to complement the draggable plugin. Which turned out to be the perfect solution. I have a ton of flexibility now. Record For the record, in case anyone else is trying to do something similar ill post another codepen with the approach I came up with for my solution. https://codepen.io/carelesscourage/pen/VwXbLRx The Code My real source code is doing all this in Nuxt 3 which has do do some extra juggling because of SSR. Heres how I did it in Nuxt 3 if anyone is spesifically dealing with that approach. Also, for the record, the below code will only work in Nuxt 3 if you transpile GSAP. Otherwise you have to import the gsap dependecies using require() inside the process.client check. Heres the Nuxt 3 docs to explain how to transpile dependencies: docs <script setup> import { gsap } from "gsap" import { Flip } from "gsap/Flip"; import { Draggable } from "gsap/Draggable"; const fragElement = ref(null) let zones = [] let fragRect = null let draggable = null onMounted(() => { if(process.client) { gsap.registerPlugin(Flip, Draggable); zones = document.querySelectorAll('[data-dropzone]') fragRect = fragElement.value.getBoundingClientRect() draggable = new Draggable(fragElement.value, { onDrag: onDrag, onRelease: onRelease, }) } }) function zoneHit(el, {hit, mis = () => {}, dud = () => {}}) { let noHit = true function onHit(zone) { noHit = false hit(zone, el) } zones.forEach((zone) => { el.hitTest(zone) ? onHit(zone) : mis(zone, el) }) noHit && dud(el) } function landHit(zone, el) { zone.classList.remove("drag-hit"); zone.classList.add("land-hit"); Flip.fit(el.target, zone, { duration: 0.1, }); } function landMis(zone, el) { zone.classList.remove("drag-hit"); zone.classList.remove("land-hit"); } function onDrag(e) { fragElement.value.classList.add("drag") zoneHit(this, { hit: (zone) => zone.classList.add("drag-hit"), mis: (zone) => zone.classList.remove("drag-hit") }) } function onRelease(e) { fragElement.value.classList.remove("drag") zoneHit(this, { hit: landHit, mis: landMis, dud: () => gsap.to(this.target, {duration: 0.5, x:0, y:0}) }) } </script> <template> <div ref="fragElement" class="frag u-panel" > <slot></slot> </div> </template> <style lang="scss" scoped> .frag { background-color: var(--background); padding: var(--space-familiar); border: solid 3px red; transition: all none !important; transition: max-width 0.4s !important; max-width: 700px; } </style>
  2. Intro: Theres probably not a simple anwser to this but I wanted to see if someone more gsap experienced than me knew of some cool trick that could help me before I go on to do some overly complicated way of solving my issue. Whatver the case, thanks to anyone who is willing to give my issue a shot one way or another. Context: So, I want to create a component builder that lets users drag and drop blocks in place. As part of this I am using GSAP Draggable to drag and drop an element. The riddle im stuck on at the moment is I want the element to snap into place when its dragged over an area that can receive it. The simple solution is to just use the hitTest() function to detect if eligeble element is hit and then get either the points off that element to use in the livesnap, or get the transforms to match that element or something like that. Problem is that in a more complex example, for my use case, I dont actually want to manually create a uniqe function for every possible snappable area since there might be a lot. The ultimate solution would be if I could somehow dynamically fetch whatever snappable element we have hit. But as far as I can tell, from the docs, the hitTest() doesnt actually return the hit element, it just returns a boolean which kinda forces me to do something uniqley for each individual element that can get hit. Question: Is there a straight forward way to dynamically get whatever element I hit with the hitTest()? Codepen: Ive provided a codepen that acts like a massive simplification of what I am trying to do just to narrow it down to exactly what I am asking and making easy to experiement with solutions. Hope that makes it simpler to understand.
×
×
  • Create New...