////////*************** */ // Framework Data ////////*************** */ const frameworkCardFields = [ { "fieldID": "intentions1", "section": "intentions", "text": "Think of an expression (a word or phrase) you're unsure about.", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f78b9a407a20a1cfcb_person-set-intentions.svg", "personLeftAltText": "Woman wearing a dark blue suit holds up a sign that says set intentions", "nextFields": { "btnTrue": "contextAB", "btnFalse": null } }, { "fieldID": "contextAB", "section": "context", "helpText": "If you're not sure about the history or associations of an expression, consider doing a quick Google search to see what others have said.

Even if you don't find an expression harmful, it's possible that it has a harmful backstory or that other people with different experiences find it harmful.", "helpBtnText": "Feeling stuck?", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f79fb0587446f1ff00_person-consider-context.svg", "personRight": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f78db9c712aa1e711f_person-context-help.svg", "personLeftAltText": "Woman in an orange wheelchair holds up a sign that says consider context", "personRightAltText": "Man in an orange button up shrugs his shoulders", "fields": [ { "fieldID": "contextA", "text": "Does this expression center dominant groups as the default or perpetuate harmful stereotypes?", "helpText": "This means that the word or phrase treats a group of people with more social or historical power as the default. For example,“chairman” of the board (versus “chair” or “chairperson”) reflects a stereotype that the role is only meant for men, and not for people of other genders.", "nextFields": { "btnTrue": "inclusion1", "btnFalse": "contextCD" } }, { "fieldID": "contextB", "text": "Does this expression have a harmful history or association?", "nextFields": { "btnTrue": "inclusion1", "btnFalse": "contextCD" } } ] }, { "fieldID": "contextCD", "section": "context", "helpText": "There may be direct ways to understand whether people feel seen and respected by a language choice, especially when it comes to demographic and identity terms. For more on these types of expressions, check out our common questions.", "helpBtnText": "Feeling stuck?", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f743984ffe0bd94874_person-context2.svg", "personRight": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f7b38c26725ae3e884_person-context2-help.svg", "personLeftAltText": "Man in an orange tank top holds a sign that says consider context", "personRightAltText": "Woman in an orange shirt wearing a purse walks and pants out of exhaustion", "fields": [ { "fieldID": "contextC", "text": "Does the expression acknowledge and indicate respect for a diverse range of experiences?", "helpText": "This means that the word or phrase doesn't convey equal respect to people of different backgrounds (cultures, languages, lived experiences, etc.). For example, when “pow wow” is used to refer to a meeting instead of an Indigenous cultural event, it doesn't recognize the significance this event has to Native Americans and may not make those individuals feel respected.", "nextFields": { "btnTrue": "endingContinue", "btnFalse": "inclusion1" } }, { "fieldID": "contextD", "text": "Does this term convey the intended meaning precisely and effectively?", "nextFields": { "btnTrue": "endingContinue", "btnFalse": "inclusion1" } } ] }, { "fieldID": "inclusion1", "section": "inclusion", "helpText": "Practicing inclusive language is an ongoing journey. Everyone makes mistakes - even the most informed and well-intentioned people. If you slip up and use non-inclusive language, it's important to acknowledge the harmful impact of your words and be open to learning more. Check out this resource for navigating difficult conversations about inclusive language.", "helpBtnText": "What if I've used a less inclusive expression?", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f741bcb9a217b10aae_person-inclusion.svg", "personRight": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f759ce998055f7f860_person-feelingStuck3.svg", "personLeftAltText": "Woman in a yellow shirt with a hand on her hip holds a sign that says center inclusion", "personRightAltText": "Man in a yellow suit and tie slips and is in the act of falling", "text": "Is there another expression that's more precise and effective?", "nextFields": { "btnTrue": "endingChange2", "btnFalse": "endingChange1" } }, { "fieldID": "endingContinue", "section": "change", "text": "Continue using the expression.", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f70591854c087d41fa_person-endingContinue.svg" }, { "fieldID": "endingChange1", "section": "change", "text": "Use the expression with caution or decide not to use it. Consider explaining your choice to your audience.", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f7a754c23d698d43b4_person-endingChange1.svg" }, { "fieldID": "endingChange2", "section": "change", "text": "Check out this tool for other harmful expressions and their inclusive alternatives.", "personLeft": "https://cdn.prod.website-files.com/62a15d12aa7b1a70e4f99a9e/6940e7f77dd7a2012ba90cd8_person-endingChange2.svg" } ]; //======================== // Helpers //======================== const getFieldData = (fieldID) => { // if no field ID is given, // default to first/intro field in frameworkCardFields array if (!fieldID) return frameworkCardFields[0]; const fieldData = frameworkCardFields.find( field => field.fieldID === fieldID ); if (!fieldData) { console.error("❌ getFieldData failed for:", fieldID); } return fieldData; }; // Check if all values in array are true let checker = arr => arr.every(Boolean); // check if array includes specific value // TODO: refactor to accept value as param let checker2 = (myArr) => { if (myArr.includes(true)) { return false; } return true; } //======================== // Modal //======================== // Get the modal var modal = document.getElementById("myModal"); // Get the element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on (x), close the modal span.onclick = function() { modal.style.display = "none"; } // When the user clicks anywhere outside of the modal, close it window.onclick = function(event) { if (event.target == modal) { modal.style.display = "none"; } } //======================== // Buttons //======================== const createButton = (text, nextField, isTrue) => { const cardButton = document.createElement("button"); cardButton.classList = "card-btn-submit"; // TODO: refactor - pass in yes/no value // or check this programmatically from 'btnTrue'/'btnFalse' keys cardButton.value = isTrue; cardButton.append(text); // on button click, create/show next card cardButton.addEventListener('click', (e) => { handleButtonClick(e, nextField); }); return cardButton; }; const createRestartButton = () => { const restartButton = document.createElement("button"); restartButton.classList = "card-btn-restart"; restartButton.append("Check another expression"); // on button click, restart framework at the beginning restartButton.addEventListener('click', () => { location.replace(location.href); }); return restartButton; }; const createHelpButton = (helpText, helpBtnText) => { const helpButton = document.createElement("button"); const helpIcon = document.createElement("i"); helpButton.classList = "card-btn-help"; helpIcon.classList = "fa-solid fa-arrow-pointer fa-beat"; helpButton.append(helpIcon, helpBtnText); // animate every 5 secs gsap.from(helpButton, { duration: 1, rotation: 15, ease: "elastic", repeat: 5, repeatDelay: 5, force3D: true }); return helpButton; }; const handleButtonClick = (e, nextField) => { const button = e.target; const buttonValue = button.value; const buttonWrapperEl = button.parentElement; const buttons = buttonWrapperEl.getElementsByTagName("button"); const cardEl = buttonWrapperEl.parentElement; const sectionEl = cardEl.parentElement; const currentFieldID = sectionEl.id; // when button is submitted, for (let i = 0; i < buttons.length; i++) { // deselect previously selected button (if it exists) if (buttons[i].classList.contains("selected")) { buttons[i].classList.remove("selected") } } // flag card as "submitted" cardEl.classList = ` card submitted ${buttonValue}`; button.classList += " selected"; // if submitted, then check button values as boolean array const buttonStatuses = checkSectionButtons(sectionEl); const isSubmitted = checker(buttonStatuses); if (isSubmitted) { // pass in card id and answer boolean value const computedNextField = getNextField(sectionEl, nextField); if (!computedNextField) { console.error("❌ nextCardField is invalid", { sectionId: sectionEl.id, nextFieldFromButton: nextField }); return; } const existingCardGroup = document.querySelector(`section.${computedNextField}`); try { drawSVGPath(computedNextField, currentFieldID); } catch (err) { console.warn("drawSVGPath failed but continuing:", err); } if (!existingCardGroup) { createCardGroup(computedNextField); } else { existingCardGroup.scrollIntoView(); } } }; // TODO: move and/or refactor out of buttons const getNextField = (sectionEl, nextField) => { let areAnswersTrue = checkButtonAnswers(sectionEl); let sectionID = sectionEl.id; let nextSection = null; if (sectionID === "contextAB") { areAnswersTrue = checkButtonAnswers2(sectionEl); nextSection = areAnswersTrue ? "contextCD" : "inclusion1"; } else if (sectionID === "contextCD") { areAnswersTrue = checkButtonAnswers(sectionEl); nextSection = areAnswersTrue ? "endingContinue" : "inclusion1"; } else { nextSection = nextField; } return nextSection; }; // For contextAB section // TODO: refactor const checkButtonAnswers2 = (sectionEl) => { const cards = sectionEl.getElementsByClassName("card"); const buttonAnswers = []; for (let i = 0; i < cards.length; i++) { // check if all cards in section have been submitted const isAnswerTrue = cards[i].classList.contains("true"); buttonAnswers.push(isAnswerTrue); } return checker2(buttonAnswers); }; // For contextCD section // TODO: refactor const checkButtonAnswers = (sectionEl) => { const cards = sectionEl.getElementsByClassName("card"); const buttonAnswers = []; for (let i = 0; i < cards.length; i++) { // check if all cards in section have been submitted const isAnswerTrue = cards[i].classList.contains("true"); buttonAnswers.push(isAnswerTrue); } return checker(buttonAnswers); }; const checkSectionButtons = (sectionEl) => { const cards = sectionEl.getElementsByClassName("card"); const buttonsSubmitted = []; for (let i = 0; i < cards.length; i++) { // check if all cards in section have been submitted const isSubmitted = cards[i].classList.contains("submitted"); buttonsSubmitted.push(isSubmitted); } return buttonsSubmitted; }; const getButtons = (nextFields) => { let cardButtons = null; if (nextFields) { const { btnTrue, btnFalse } = nextFields; const enableYesNoBtns = !!(btnTrue && btnFalse); const trueText = enableYesNoBtns ? "Yes" : "Let's go"; // create button wrapper cardButtons = document.createElement("div"); cardButtons.className = "btn-wrapper"; // append button(s) to container const buttonYes = createButton(trueText, btnTrue, true); cardButtons.append(buttonYes); if (enableYesNoBtns) { const buttonNo = createButton("No", btnFalse, false); cardButtons.append(buttonNo); } } return cardButtons; }; //=============================== // Framework Help Text El //=============================== const createHelpTextEl = (helpText, personRight, personRightAltText) => { const helpTextContainer = document.createElement("div"); const helpTextWrapper = document.createElement("div"); const helpTextP = document.createElement("p"); helpTextContainer.classList.add("help-container"); helpTextWrapper.classList.add("help-text-wrapper"); helpTextP.innerHTML = helpText; helpTextWrapper.append(helpTextP); helpTextContainer.append(helpTextWrapper); // add people assets if( personRight ) { const personRightEl = document.createElement("img"); personRightEl.classList += "person-img"; personRightEl.src = personRight; personRightEl.alt = personRightAltText; helpTextContainer.append(personRightEl); } return helpTextContainer; }; //======================== // Cards //======================== // if section element already exists with class === fieldID, // don't create another card group const createCardGroup = (fieldID) => { const currentField = getFieldData(fieldID); if (!currentField) { console.error("❌ No field data found for:", fieldID); return; } const { fields, section, helpText, helpBtnText, personLeft, personRight, personLeftAltText, personRightAltText } = currentField; const sectionEl = document.createElement("section"); const cardWrapperEl = document.createElement("div"); cardWrapperEl.classList = "card-wrapper"; sectionEl.classList += `${section} ${fieldID}`; sectionEl.id = fieldID; cardWrapperEl.id = fieldID; // add people assets if( personLeft ) { const personLeftEl = document.createElement("img"); personLeftEl.classList += "person-img"; personLeftEl.src = personLeft; personLeftEl.alt = personLeftAltText; sectionEl.append(personLeftEl); } // if multiple fields exist... if ( !!fields ) { // iterate through each field for (let i = 0; i < fields.length; i++) { // create multiple card elements const newCard = createCard(fields[i]); // then, append card to cardWrapperEl cardWrapperEl.append(newCard); } } else { // otherwise, just create 1 card const newCardEl = createCard(currentField); // then, append card to cardWrapperEl cardWrapperEl.append(newCardEl); // if end card, // add "Check another expression" (restart) button if ((fieldID).includes("ending")) { const restartButton = createRestartButton(); // then, append button to cardWrapperEl cardWrapperEl.append(restartButton); document.body.style.overflow = "auto"; } } if( !!helpText ) { // add help text const helpTextEl = createHelpTextEl(helpText, personRight, personRightAltText); const helpBtn = createHelpButton(helpText, helpBtnText); // on button click, show help text helpBtn.addEventListener('click', () => { const helpTextWrapper = helpTextEl.querySelector('div.help-text-wrapper'); console.log("helpText ", helpTextWrapper); if (!helpTextWrapper.classList.contains("active")) { gsap.fromTo(helpTextWrapper, 0.5, { opacity: 0, y: 0 }, { opacity: 1, y: 1 }); helpTextWrapper.classList.add("active"); } else { gsap.fromTo(helpTextWrapper, 0.5, { opacity: 1, y: 0 }, { opacity: 0, y: -100 }); helpTextWrapper.classList.remove("active"); } }); cardWrapperEl.append(helpBtn); sectionEl.append(cardWrapperEl, helpTextEl); } else { sectionEl.append(cardWrapperEl); } // add card group to main content in DOM document.querySelector("#guide-main").append(sectionEl); // setCardPosition(); if (fieldID !== "intentions1") { sectionEl.scrollIntoView(); } else { window.scrollTo(0, 0); } // let dot = document.getElementById(`dot-${fieldID}`); // let dotPosition = dot.getBoundingClientRect(); // const { y } = dotPosition; // console.log("dot ", dot, dotPosition, y); }; // TODO: put svg in position: relative container instead of this?? const setCardPosition = () => { // TODO: on page load, wait until svg has loaded before firing let svgChild = document.getElementById('dot-contextAB'); console.log("setCard!!! ", svgChild); let foreign = document.createElementNS('http://www.w3.org/2000/svg',"foreignObject"); foreign.setAttribute('width', 500); foreign.setAttribute('height',500); let iDiv = document.createElement('div'); let t = document.createTextNode("This is a paragraph."); iDiv.appendChild(t); foreign.appendChild(iDiv); svgChild.appendChild(foreign); }; const createTextEl = (text, className) => { const newTextEl = document.createElement("p"); if ((text).includes("tooltip")) { newTextEl.innerHTML = text; } else { // add text (from fieldData to cardText element) newTextEl.textContent = text; } if (className) { newTextEl.classList = className; } return newTextEl; }; const createCard = (currentField) => { const { text, nextFields, fieldID, helpText, link } = currentField; // card text element const textEl = createTextEl(text, "card-text"); const cardEl = document.createElement("div"); cardEl.classList = "card"; cardEl.append(textEl); if (link) { const { linkText, linkURL } = link; const linkEl = document.createElement("a"); linkEl.textContent = linkText; linkEl.href = linkURL; linkEl.setAttribute("target", "_blank"); // append linkEl to card cardEl.append(linkEl); } if (nextFields) { const cardButtons = getButtons(nextFields); // append buttons to card cardEl.append(cardButtons); } if (helpText) { const helpTextContent = createTextEl(helpText, "tooltip-content"); if ((text).includes("tooltip")) { textEl.append(helpTextContent); } } // animate in gsap.from(cardEl, { duration: 2, scale: 0.5, ease: "elastic", force3D: true }); return cardEl; }; //======================== // SVG road //======================== // track position of blue dot - add active class const drawSVGPath = (nextField, prevField) => { console.log(nextField, prevField); let line = null; let branch = null; let pathOutline = null; let dot = document.getElementById(`dot-${nextField}`); let sideNavDot = document.getElementById(`sidenav-${nextField}`); let sideNavOutline; let sectionPpl = null; if (!dot || !sideNavDot) { console.warn("Missing SVG element(s)", { nextField, dot, sideNavDot }); return; } const contextCDbranchOutline = document.getElementById("branch-contextCD-wide"); const contextCDbranch = document.getElementById("branch-contextCD"); const inclusion1branchOutline = document.getElementById("branch-inclusion1-wide"); const inclusion1branch = document.getElementById("branch-inclusion1"); const inclusion1straightOutline = document.getElementById("straight-inclusion1-wide"); const inclusion1straight = document.getElementById("straight-inclusion1"); const endingContinueStraightOutline = document.getElementById("straight-endingContinue-wide"); const endingContinueStraight = document.getElementById("straight-endingContinue"); const change1branchOutline = document.getElementById("branch-endingChange1-wide"); const change1branch = document.getElementById("branch-endingChange1"); const change2straightOutline = document.getElementById("straight-endingChange2-wide"); const change2straight = document.getElementById("straight-endingChange2"); dot.classList = "st5"; sideNavDot.style.stroke = "#000000"; switch(nextField) { case "contextAB": line = document.getElementById(`straight-${nextField}`); line.style.display = "block"; pathOutline = document.getElementById(`straight-${nextField}-wide`); pathOutline.style.display = "block"; gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cy: 976.9}, ease: "none"}); // side nav sideNavDot.style.fill = "#D16028"; sideNavOutline = document.getElementById(`sidenav-straight-${nextField}`); sideNavOutline.style.stroke = "#000000"; // activate section ppl sectionPpl = document.getElementById("contextAB-ppl"); if (sectionPpl) sectionPpl.classList.toggle("inactive-step"); break; case "contextCD": contextCDbranch.style.stroke = "#3364CC"; contextCDbranchOutline.style.stroke = "#F5F5F5"; gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cx: 1819.1, cy: 2115.9}, ease: "none"}); // clear straight path if previously taken inclusion1straight.style.display = "none"; inclusion1straightOutline.style.display = "none"; // clear change2 path if previously taken change2straight.style.display = "none"; change2straightOutline.style.display = "none"; // clear change1 path if previously taken change1branch.style.stroke = "#DEDEDE"; change1branchOutline.style.stroke = "#F5F5F5"; // side nav sideNavDot.style.fill = "#D16028"; sideNavOutline = document.getElementById(`sidenav-branch-${nextField}`); sideNavOutline.style.stroke = "#000000"; // activate section ppl sectionPpl = document.getElementById("contextCD-ppl"); if (sectionPpl) sectionPpl.classList.toggle("inactive-step"); break; case "inclusion1": // clear endingContinue path if previously taken endingContinueStraight.style.stroke = "#DEDEDE"; endingContinueStraightOutline.style.stroke = "#F5F5F5"; // clear change2 path if previously taken change2straight.style.display = "none"; change2straightOutline.style.display = "none"; // clear change1 path if previously taken change1branch.style.stroke = "#DEDEDE"; change1branchOutline.style.stroke = "#F5F5F5"; // straight down if (prevField === "contextAB") { inclusion1straight.style.display = "block"; inclusion1straightOutline.style.display = "block"; // clear branch path if previously taken contextCDbranch.style.stroke = "#DEDEDE"; contextCDbranchOutline.style.stroke = "#F5F5F5"; inclusion1branch.style.stroke = "#DEDEDE"; inclusion1branchOutline.style.stroke = "#F5F5F5"; // side nav sideNavOutline = document.getElementById(`sidenav-straight-${nextField}`); } else { // highlight path from considerContextAB to considerContextCD // (in case it was cleared by resubmitting considerContextAB answer) contextCDbranch.style.stroke = "#3364CC"; contextCDbranchOutline.style.stroke = "#F5F5F5"; inclusion1branch.style.stroke = "#3364CC"; inclusion1branchOutline.style.stroke = "#F5F5F5"; // clear straight path if previously taken inclusion1straight.style.display = "none"; inclusion1straightOutline.style.display = "none"; // side nav sideNavOutline = document.getElementById(`sidenav-branch-${nextField}`); } gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cx: 960, cy: 2957.2}, ease: "none"}); // side nav sideNavDot.style.fill = "#FDB714"; sideNavOutline.style.stroke = "#000000"; // activate section ppl sectionPpl = document.getElementById("inclusion1-ppl"); if (sectionPpl) sectionPpl.classList.toggle("inactive-step"); break; case "endingContinue": // highlight path to 'endingContinue' endingContinueStraight.style.stroke = "#3364CC"; endingContinueStraightOutline.style.stroke = "#F5F5F5"; gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cx: 1819.1, cy: 4063.6}, ease: "none"}); // clear straight path if previously taken inclusion1straight.style.display = "none"; inclusion1straightOutline.style.display = "none"; // clear branch path if previously taken inclusion1branch.style.stroke = "#DEDEDE"; inclusion1branchOutline.style.stroke = "#F5F5F5"; // clear change2 path if previously taken change2straight.style.display = "none"; change2straightOutline.style.display = "none"; // clear change1 path if previously taken change1branch.style.stroke = "#DEDEDE"; change1branchOutline.style.stroke = "#F5F5F5"; // side nav sideNavDot.style.fill = "#512B83"; sideNavOutline = document.getElementById(`sidenav-straight-${nextField}`); sideNavOutline.style.stroke = "#000000"; // activate section ppl sectionPpl = document.getElementById("endingContinue-person"); if (sectionPpl) sectionPpl.classList.toggle("inactive-step"); break; case "endingChange1": change1branch.style.stroke = "#3364CC"; change1branchOutline.style.stroke = "#F5F5F5"; // clear endingContinue path if previously taken endingContinueStraight.style.stroke = "#DEDEDE"; endingContinueStraightOutline.style.stroke = "#F5F5F5"; // clear change2 path if previously taken change2straight.style.display = "none"; change2straightOutline.style.display = "none"; // TODO: animate along curve gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cx: 128.1, cy: 4063.6}, ease: "none"}); // side nav sideNavDot.style.fill = "#512B83"; sideNavOutline = document.getElementById(`sidenav-branch-${nextField}`); sideNavOutline.style.stroke = "#000000"; // collapse side nav toggleSideNav(); // activate section ppl sectionPpl = document.getElementById("endingChange1-person"); sectionPpl.classList.toggle("inactive-step"); break; case "endingChange2": change2straight.style.display = "block"; change2straightOutline.style.display = "block"; // clear change1 path if previously taken change1branch.style.stroke = "#DEDEDE"; change1branchOutline.style.stroke = "#F5F5F5"; // clear endingContinue path if previously taken endingContinueStraight.style.stroke = "#DEDEDE"; endingContinueStraightOutline.style.stroke = "#F5F5F5"; gsap.to("#dot-current, #dot-current-ring", {duration: 1, attr: {cx: 960, cy: 4063.6}, ease: "none"}); // side nav sideNavDot.style.fill = "#512B83"; sideNavOutline = document.getElementById(`sidenav-straight-${nextField}`); sideNavOutline.style.stroke = "#000000"; // activate section ppl sectionPpl = document.getElementById("endingChange2-person"); sectionPpl.classList.toggle("inactive-step"); break; default: console.log("nextField drawSVGPath ", nextField); } }; const drawFullSVGPath = () => { let svgObject = document.getElementById('svg-road-intro'); let svgPath = svgObject.getElementById('path-full'); let length = svgPath.getTotalLength(); console.log(length); svgPath.style.strokeDasharray = length + ' ' + length; svgPath.style.strokeDashoffset = length; // let tl = gsap.timeline({ repeat: 2, repeatDelay: 1 }); // tl.from(svgPath, 1, {drawSVG: 0}); // // tl.to(svgPath, {drawSVG: "100%", duration: 1, strokeWidth:110}); }; // Only show side nav when framework journey has scrolled into view const el = document.querySelector(".side-nav-wrapper"); let elTop = el.getBoundingClientRect().top - document.body.getBoundingClientRect().top; window.addEventListener('scroll', () => { if (document.documentElement.scrollTop > elTop){ el.style.position = 'fixed'; } else { el.style.position = 'absolute'; } }); // document.addEventListener("mousemove", function(e) { // const myDiv = document.getElementById("myDiv"); // console.log("gello ", myDiv); // myDiv.style.left = e.clientX + "px"; // myDiv.style.top = e.clientY + "px"; // }); const point = { x: 10, y: 10 }; const angle = Math.PI / 2; const rotatedPoint = { x: point.x * Math.cos(angle) - point.y * Math.sin(angle), y: point.x * Math.sin(angle) + point.y * Math.cos(angle) }; ////////////////////////////////////// // Make the side nav element draggagle: dragElement(document.getElementById("side-nav-draggable")); function dragElement(elmnt) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; const dragHeaderEl = document.getElementById(elmnt.id + "-header"); /* the header is where you move the DIV from:*/ dragHeaderEl.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: pos3 = e.clientX; pos4 = e.clientY; console.log("pos3 pos4 ", pos3, pos4); document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; console.log("pos1 pos2 pos3 pos4 ", pos1, pos2, pos3, pos4, e); console.log("elmnt.offsetTop ", elmnt.offsetTop, "elem.offsetLeft ", elmnt.offsetLeft); // set the element's new position: // elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; // elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; elmnt.style.top = pos3 + "px"; elmnt.style.left = pos4 + "px"; } function closeDragElement() { /* stop moving when mouse button is released:*/ document.onmouseup = null; document.onmousemove = null; } } // Side nav toggle open/close const handleSideNavToggle = () => { const toggleButton = document.getElementById("side-nav-toggle"); toggleButton.addEventListener('click', toggleSideNav); }; const toggleSideNav = () => { const buttonIcon = document.getElementById("side-nav-icon"); const navSvgWrapper = document.getElementsByClassName("side-nav-svg-wrapper")[0]; // toggle nav open/close navSvgWrapper.classList.toggle("collapse-nav"); // toggle icon + / - buttonIcon.classList.toggle("fa-minus"); buttonIcon.classList.toggle("fa-plus"); }; //======================== // On load //======================== // TODO: refactor to initialize field data before body loads window.addEventListener("load", () => { createCardGroup("intentions1"); handleSideNavToggle(); }); // window.addEventListener("load", drawSVGPath); // TODO select intro svgs // add scroll event listener // on scroll, move elements at different speeds