i have this animation where the plasmid (circle thing) moves towards a row of objects (blue lipids) and i want the lipids to form a circle around the plasmid while it is passing through the row.
I dont know how to animate the movement of the lipids and what tools to use (GSAP was useful so far).
If possible it should look a bit like this
I came this far codepen
const plasmid_container = document.querySelector(".plasmid_container");
let DOM_plasmid_container = plasmid_container.getBoundingClientRect();
const drop_container = document.querySelector(".drop_container");
let DOM_drop_container = drop_container.getBoundingClientRect();
const scrollsource = document.querySelector(".scrollsource")
let DOM_scrollsource = scrollsource.getBoundingClientRect()
console.log(DOM_scrollsource)
const startpoint = {x: DOM_plasmid_container.x + (DOM_plasmid_container.width/2), y: DOM_plasmid_container.y + (DOM_plasmid_container.height/2)}
console.log(startpoint)
const drop_center = {x: DOM_drop_container.x + (DOM_drop_container.width/2), y: DOM_drop_container.y + (DOM_drop_container.height/2)}
// gets each element with the id and returns the positions of it in an array of ClientRect objects
function get_class_positions(class_name) {
const positions = [];
const elements = document.querySelectorAll(class_name);
for (let i = 0; i < elements.length; i++) {
let element_x = elements[i].getBoundingClientRect().x - startpoint.x;
let element_y = elements[i].getBoundingClientRect().y -startpoint.y;
positions.push({x: element_x, y: element_y});
}
return positions;
}
const anchor = get_class_positions(".anchor")
console.log("DOM anchor")
console.log(anchor)
//create access point and import relevant packages
gsap.registerPlugin(MotionPathPlugin, ScrollTrigger);
/* // variables to set start and end for scrolltimeline
let plasmid_start_trigger = DOM_plasmid_container.y - DOM_scrollsource.y
let plasmid_end_trigger = DOM_drop_container.y - DOM_scrollsource.y + DOM_drop_container.height/2
*/
//create a timeline object
let tl_plasmid = gsap.timeline({
//connect the timeline to scrolltrigger instead of duration in s
scrollTrigger: {
trigger: ".scrollsource", // selector or element
start: "top top", // [trigger]=animated element, [scroller]=viewport
end: "90% 60%",
scrub: 2, // Add scrub to control the animation progress on scroll
markers: true, // Add markers
},
})
// -------------- plasmid path ---------------
// it assumes startpoint is {0/0} so its necessary to substract the strating coordinates from all other coordinates --> this can be changed saw something somewhere in the GSAP docs
const plasmidPath1 = [
{x: 0, y:0},
{x: 0, y: anchor[0].y},
// 1
{x: anchor[0].x, y: anchor[0].y}
]
// scale 3
const plasmidPath2 = [
{x: anchor[1].x, y: anchor[0].y},
{x: anchor[1].x, y: anchor[2].y},
{x: anchor[2].x, y: anchor[2].y},
]
// scale 1
const plasmidPath3 = [
{x: anchor[3].x, y: anchor[2].y},
{x: anchor[3].x, y: anchor[4].y},
{x: anchor[4].x, y: anchor[4].y},
{x: drop_center.x - startpoint.x, y: drop_center.y - startpoint.y},
]
// move in drop
const plasmidPath5 = [
{x: anchor[5].x, y: anchor[5].y},
]
// drop opacity 1
const plasmidPath6 = [
{x: anchor[6].x, y: anchor[6].y}
]
//drop opacity 0
//before bilipid
const plasmidPath7 = [
{x: anchor[7].x, y: anchor[7].y}
]
//after bilipid
// -------------- drop path ---------------
// starts when plasmid hits center, moves synchronized, opacity 0
const dropPath1 = [
{x: 0, y: anchor[5].y - anchor[4].y},
]
// drop opacity 1
const dropPath2 = [
{x: 0, y: anchor[6].y - anchor[4].y}
]
// drop opacity 0
// -------------- PLASMID ANIMATION ---------------
// Animate the plasmid along the plasmidMoving path
tl_plasmid.to(".plasmid_container", {
motionPath: {
path: plasmidPath1,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 3,
ease: "linear",
})
.to(".plasmid_container", {
motionPath: {
path: plasmidPath2,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 1,
ease: "linear",
})
.to(".plasmid_container", {
motionPath: {
path: plasmidPath3,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 1,
ease: "linear",
})
.add("inDrop")
.to(".plasmid_container", {
motionPath: {
path: plasmidPath5,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 1,
ease: "linear",
})
.add("dropVisible")
.to(".plasmid_container", {
motionPath: {
path: plasmidPath6,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 1,
ease: "linear",
})
.to(".plasmid_container", {
motionPath: {
path: plasmidPath7,
curviness: 1,
alignOrigin: [0.5, 1]
},
scale: 1,
ease: "linear",
})
// -------------- DROP ANIMATION ---------------
// inserted drop tween
tl_plasmid.to(".drop_container", {
motionPath: {
path: dropPath1,
curviness: 1,
alignOrigin: [0.5, 1]
},
ease: "linear",
opacity: 1,
rotate: -720
}, "inDrop") //starts when inDrop label is reached by plasmid
.to(".drop_container", {
motionPath: {
path: dropPath2,
curviness: 1,
alignOrigin: [0.5, 1]
},
ease: "linear",
opacity: 0,
rotation: 365,
}, "dropVisible") //starts when drop has opacity 1, then turn opacity to 0
// create number of images in a certain container with a class and a name
function fill_image_container(container_name, image_source, img_name, div_class, number){
const container = document.getElementById(container_name);
if (!container) {
console.error(`Container with id '${container_name}' not found.`);
return;
}
for (let i = 0; i < number; i++) {
const img = document.createElement('img');
img.src = image_source; // Your image URL as string
img.id = `${img_name}_${i}`; // Alt text for the image
const div = document.createElement('div'); // Step 1: Create a new div
div.className = `${div_class}`
div.appendChild(img); // Step 2: Append the img to the div
container.appendChild(div); // Step 3: Append the div to the container
}
}
fill_image_container("lipid-container", "https://static.igem.wiki/teams/5057/bilipid-b.svg", "bilipid", "bilipid", 100)
window.addEventListener("scroll", () => {
/* let plasmid = document.getElementById("plasmid");
let DOM_plasmid = plasmid.getBoundingClientRect();
// console.log("Plasmid x:", rect_plasmid.x, "Plasmid y:", rect_plasmid.y);
let plasmid_center = {x: DOM_plasmid.x + DOM_plasmid.width/2, y: DOM_plasmid.y + DOM_plasmid.height/2}
console.log("Plasmid center: ", plasmid_center) */
/* let bilipid_50 = document.getElementById("bilipid_50")
let DOM_bilipid_50 = bilipid_50.getBoundingClientRect()
console.log("Bilipid_50 y: " , DOM_bilipid_50.y) */
// function to track the center of a element selected by ID
})
I also tried to create a Class for the lipids to link them toghether and then let them keep a certain distance to the plasmid but this approach seems way to complicated…
user26412111 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.