Forum Discussion

BillyTheroux's avatar
BillyTheroux
Community Member
23 hours ago

CAROUSEL in Storyline!

Ok over the last few weeks I've been learning to use JavaScript in Storyline modules and this is another great example of taking some of the functionality out of Rise and using it in Storyline. I've discovered how to create a really slick carousel. 

https://360.articulate.com/review/content/b2224974-b080-41ad-aa47-f874da152b14/review 

You can customize the code for size speed and motion. Just need to copy your object IDs into the code and you're good to go. Code should be able to be copied and pasted right into your project. 

Let me know how you like it!!!!



// ------------------------------------
// STORYLINE CARD CAROUSEL
// ------------------------------------

const CARD_IDS = [
"CARD_1_OBJECT_ID",
"CARD_2_OBJECT_ID",
"CARD_3_OBJECT_ID",
"CARD_4_OBJECT_ID"
];

const PREVIOUS_BUTTON_ID = "PREVIOUS_BUTTON_OBJECT_ID";
const NEXT_BUTTON_ID = "NEXT_BUTTON_OBJECT_ID";

// ------------------------------------
// CUSTOMIZATION
// ------------------------------------

// Horizontal center of the carousel.
// Change these to match your slide.
const CENTER_X = slideWidth() / 2;
const CENTER_Y = slideHeight() / 2;

// Distance between card centers.
const CARD_SPACING = 330;

// Appearance of the centered card.
const ACTIVE_SCALE = 1;
const ACTIVE_OPACITY = 1;

// Appearance of cards beside the centered card.
const SIDE_SCALE = 0.78;
const SIDE_OPACITY = 0.45;

// Cards farther away can be hidden.
const HIDDEN_SCALE = 0.65;

// Animation responsiveness.
// Lower numbers are slower and smoother.
const SMOOTHING = 0.14;

// Whether Next from the last card returns to the first.
const LOOP_CAROUSEL = true;


// ------------------------------------
// SETUP
// ------------------------------------

const cards = CARD_IDS.map((id, index) => {
const item = object(id);

item.style.transformOrigin = "center center";

return {
item,
index,
currentX: item.x,
currentY: item.y,
currentScale: 1,
currentOpacity: 1
};
});

const previousButton = object(PREVIOUS_BUTTON_ID);
const nextButton = object(NEXT_BUTTON_ID);

let activeIndex = 0;


// ------------------------------------
// HELPERS
// ------------------------------------

function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}

function changeCard(direction) {
activeIndex += direction;

if (LOOP_CAROUSEL) {
if (activeIndex < 0) {
activeIndex = cards.length - 1;
}

if (activeIndex >= cards.length) {
activeIndex = 0;
}
} else {
activeIndex = clamp(
activeIndex,
0,
cards.length - 1
);
}

// Optional Storyline number variable.
// Create CurrentCarouselCard if you want to use this.
// setVar("CurrentCarouselCard", activeIndex + 1);
}


// ------------------------------------
// BUTTON EVENTS
// ------------------------------------

previousButton.click(() => {
changeCard(-1);
});

nextButton.click(() => {
changeCard(1);
});


// ------------------------------------
// CARD CLICK EVENTS
// ------------------------------------

// Clicking a side card brings it to the center.
// Clicking the active card can trigger your
// normal Storyline action or open a layer.

cards.forEach((card) => {
card.item.click(() => {
activeIndex = card.index;
});
});


// ------------------------------------
// ANIMATION LOOP
// ------------------------------------

update(() => {
cards.forEach((card) => {
const offset = card.index - activeIndex;
const absoluteOffset = Math.abs(offset);

let targetX;
let targetY = CENTER_Y - card.item.height / 2;
let targetScale;
let targetOpacity;

if (absoluteOffset === 0) {
// Active center card.
targetX =
CENTER_X - card.item.width / 2;

targetScale = ACTIVE_SCALE;
targetOpacity = ACTIVE_OPACITY;

card.item.style.pointerEvents = "auto";
} else if (absoluteOffset === 1) {
// Immediate side cards.
targetX =
CENTER_X -
card.item.width / 2 +
offset * CARD_SPACING;

targetScale = SIDE_SCALE;
targetOpacity = SIDE_OPACITY;

card.item.style.pointerEvents = "auto";
} else {
// Cards farther away.
targetX =
CENTER_X -
card.item.width / 2 +
offset * CARD_SPACING;

targetScale = HIDDEN_SCALE;
targetOpacity = 0;

card.item.style.pointerEvents = "none";
}

// Smoothly ease toward the target values.
card.currentX +=
(targetX - card.currentX) * SMOOTHING;

card.currentY +=
(targetY - card.currentY) * SMOOTHING;

card.currentScale +=
(targetScale - card.currentScale) * SMOOTHING;

card.currentOpacity +=
(targetOpacity - card.currentOpacity) * SMOOTHING;

card.item.x = card.currentX;
card.item.y = card.currentY;

card.item.style.transform =
`scale(${card.currentScale})`;

card.item.style.opacity =
card.currentOpacity;
});
});
No RepliesBe the first to reply