////////*************** */
// 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