Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
andff committed Dec 6, 2024
1 parent 681e20e commit 33d4bfd
Show file tree
Hide file tree
Showing 3 changed files with 643 additions and 0 deletions.
99 changes: 99 additions & 0 deletions nested-color-coded-interactive-timeline/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Nested &amp; Color Coded Interactive Timeline</title>
<link rel="stylesheet" href="./style.css">

</head>
<body>
<!-- partial:index.partial.html -->
<div class="body-wrap">
<!-- # component starts -->
<div class="pres-timeline" id="this-timeline">
<!-- ### -->
<!-- <div class="periods-section"> -->
<div class="periods-container">
<section class="period-single" period="period1">
<h4 class="year">181x-181x</h4>
<h2 class="title">1 Lorem ipsum dolor sit amet, consectetur adipisicing.</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium doloremque, laboriosam officia facere eligendi quam reiciendis, rem explicabo dolores tenetur libero minus, facilis quibusdam. Consectetur amet beatae fuga, architecto magnam.</p>
</section>
<section class="period-single" period="period2">
<h4 class="year">182x-182x</h4>
<h2 class="title">2 Lorem ipsum dolor sit amet, consectetur adipisicing.</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium doloremque, laboriosam officia facere eligendi quam reiciendis, rem explicabo dolores tenetur libero minus, facilis quibusdam. Consectetur amet beatae fuga, architecto magnam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium doloremque, laboriosam officia facere eligendi quam reiciendis, rem explicabo dolores tenetur libero minus, facilis quibusdam. Consectetur amet beatae fuga, architecto magnam.</p>
</section>
<section class="period-single" period="period3">
<h4 class="year">183x-183x</h4>
<h2 class="title">3 Lorem ipsum dolor sit amet, consectetur adipisicing.</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium doloremque, laboriosam officia facere eligendi quam reiciendis, rem explicabo dolores tenetur libero minus, facilis quibusdam. Consectetur amet beatae fuga, architecto magnam.</p>
</section>
<div class="btn-back"></div>
<div class="btn-next"></div>
</div>
<!-- </div> -->
<!-- ### -->
<!-- <div class="timeline-section"> -->
<div class="timeline-container">
<!-- # timeline graphic place holder - fill with js -->
<div class="timeline"></div>

<div class="btn-back"><svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h30v30H0z"/><path fill="#D8D8D8" fill-rule="evenodd" d="M11.828 15l7.89-7.89-2.83-2.828L6.283 14.89l.11.11-.11.11L16.89 25.72l2.828-2.83"/></svg></div>
<div class="btn-next"><svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h30v30H0z"/><path fill="#D8D8D8" fill-rule="evenodd" d="M18.172 14.718l-7.89-7.89L13.112 4l10.606 10.607-.11.11.11.11-10.608 10.61-2.828-2.83 7.89-7.89"/></svg></div>
</div>
<!-- </div> -->
<!-- ### -->
<!-- <div class="cards-section"> -->
<div class="cards-container">
<section class="card-single active" period="period1">
<h4 class="year">1816</h4>
<h2 class="title">Lorem ipsum dolor sit amet.</h2>
<div class="content">
<img src="https://ununsplash.imgix.net/photo-1421284621639-884f4129b61d?fit=crop&fm=jpg&h=700&q=75&w=1050" alt="" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore vitae sint dolore, officia esse! A recusandae nemo illum rem eos iusto repellendus, voluptatibus tempora nulla voluptatem officia inventore ea modi.</p>
</div>
</section>
<section class="card-single" period="period1">
<h4 class="year">1816</h4>
<h2 class="title">Lorem ipsum dolor sit amet.</h2>
<div class="content">
<img src="https://ununsplash.imgix.net/photo-1421284621639-884f4129b61d?fit=crop&fm=jpg&h=700&q=75&w=1050" alt="" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore vitae sint dolore, officia esse! A recusandae nemo illum rem eos iusto repellendus, voluptatibus tempora nulla voluptatem officia inventore ea modi.</p>
</div>
</section>
<section class="card-single" period="period2">
<h4 class="year">1816</h4>
<h2 class="title">Lorem ipsum dolor sit amet.</h2>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A tempora blanditiis ut voluptas nisi labore quos iste totam obcaecati modi rerum iusto, voluptate odio commodi ratione amet illum dicta accusamus, ipsum ea vero neque enim, recusandae dignissimos? Quae ea aspernatur dolor atque, ipsum repellendus. Repudiandae culpa magnam, doloribus exercitationem illo impedit quasi officia, veniam vero molestiae sunt dolorem, excepturi ullam dicta sed amet provident ut soluta pariatur magni! Fugiat eveniet suscipit praesentium culpa aperiam ab nulla, exercitationem atque quod, labore, qui quaerat nihil nam laborum aliquam! Nesciunt dignissimos eaque impedit ex, architecto minima ad, temporibus rem possimus consequatur doloremque, fuga?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore vitae sint dolore, officia esse! A recusandae nemo illum rem eos iusto repellendus, voluptatibus tempora nulla voluptatem officia inventore ea modi.</p>
</div>
</section>
<section class="card-single" period="period1">
<h4 class="year">1816</h4>
<h2 class="title">Lorem ipsum dolor sit amet.</h2>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore vitae sint dolore, officia esse! A recusandae nemo illum rem eos iusto repellendus, voluptatibus tempora nulla voluptatem officia inventore ea modi.</p>
</div>
</section>
<section class="card-single" period="period3">
<h4 class="year">1816</h4>
<h2 class="title">Lorem ipsum dolor sit amet.</h2>
<div class="content">
<img src="https://ununsplash.imgix.net/photo-1421284621639-884f4129b61d?fit=crop&fm=jpg&h=700&q=75&w=1050" alt="" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore vitae sint dolore, officia esse! A recusandae nemo illum rem eos iusto repellendus, voluptatibus tempora nulla voluptatem officia inventore ea modi.</p>
</div>
</section>
</div>
<!-- </div> -->
<!-- ### -->
</div>
<!-- # component ends -->
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script><script src="./script.js"></script>

</body>
</html>
262 changes: 262 additions & 0 deletions nested-color-coded-interactive-timeline/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
"use strict";
class PRESTimeline {
constructor(target, color) {
// this.__process_stylesheet(document.styleSheets[0]);
this.base = target;
this.color = color;
// console.log(this.color)
this.periodContainer = $(this.base).find('.periods-container');
this.cardContainer = $(this.base).find('.cards-container');
this.timelineNodeContainer = $(this.base).find('.timeline-container .timeline');
// this.activePeriod = $(this.base).find('.periods-container section.active')
this._parseData();
this._initialColor();
this._generateTimeline();
this._setStateClasses();
this._assignBtn();
this._adjustPeriodContainer();
this._adjustCardContainer();
// console.log(this.cardData)
}
_parseData() {
let base = this.base;
let periods = $(base).find('.periods-container section');
for (let section of periods) {
section.period = $(section).attr('period');
section.index = $(section).index();
}
// console.log(periods)
this.periodData = periods;
let data = $(base).find('.cards-container section');
// console.log(data)
for (let section of data) {
section.period = $(section).attr('period');
section.index = $(section).index();
}
// console.log(data)
this.cardData = data;
// #assign initial entry point (active items)
this.activePeriod = this.periodData[0];
this.activePeriodIndex = 0;
this.activeCard = this.cardData[0];
this.activeCardIndex = 0;
}
_setStateClasses() {
// # periods
$(this.base).find('.periods-container section.active').removeClass('active');
$(this.base).find('.periods-container section.prev').removeClass('prev');
$(this.base).find('.periods-container section.next').removeClass('next');
// console.log("setclass: " + this.activePeriod.index)
$(this.activePeriod).addClass('active');
// console.log(this.activePeriod.index)
// this.activePeriodIndex = this.activePeriod.index
if ($(this.activePeriod).prev().length != 0) {
$(this.activePeriod).prev().addClass('prev');
$(this.base).find('.periods-container .btn-back').removeClass('hide');
}
else {
$(this.base).find('.periods-container .btn-back').addClass('hide');
}
if ($(this.activePeriod).next().length != 0) {
$(this.activePeriod).next().addClass('next');
$(this.base).find('.periods-container .btn-next').removeClass('hide');
}
else {
$(this.base).find('.periods-container .btn-next').addClass('hide');
}
// ## cards
$(this.base).find('.cards-container section.active').removeClass('active');
$(this.base).find('.cards-container section.prev').removeClass('prev');
$(this.base).find('.cards-container section.next').removeClass('next');
$(this.activeCard).addClass('active');
// this.activeCardIndex - this.activeCard.index
if ($(this.activeCard).prev().length != 0) {
$(this.activeCard).prev().addClass('prev');
}
if ($(this.activeCard).next().length != 0) {
$(this.activeCard).next().addClass('next');
}
// ## timeline
$(this.base).find('.timeline li.active').removeClass('active');
// let findNode = $(this.base).find('.timeline ol li')[this.activeCard.index]
$(this.timelineData[this.activeCard.index]).addClass('active');
let timelineB = $(this.base).find('.timeline-container .btn-back');
let timelineN = $(this.base).find('.timeline-container .btn-next');
// console.log($(timelineN))
if (this.activeCardIndex === 0) {
timelineB.addClass('hide');
}
else {
timelineB.removeClass('hide');
}
if (this.activeCardIndex >= this.cardData.length - 1) {
timelineN.addClass('hide');
}
else {
timelineN.removeClass('hide');
}
}
// ## timeline generater
_generateTimeline() {
// ## create node list
let htmlWrap = '<ol></ol>';
$(this.timelineNodeContainer).append(htmlWrap);
let wrap = $(this.timelineNodeContainer).find('ol');
let numNode = this.cardData.length;
for (let i = 0; i < numNode; i++) {
let c = this.cardData[i].color;
let el = wrap.append('<li class="' + this.cardData[i].period + '" style="border-color: ' + c + '"></li>');
}
// ## width of timeline
let nodeW = 200;
wrap.css('width', nodeW * numNode - 16);
let nodeList = $(this.base).find('.timeline ol li');
this.timelineData = nodeList;
}
// ## assign button actions
_assignBtn() {
let periodPrev = $(this.base).find('.periods-container .btn-back');
let periodNext = $(this.base).find('.periods-container .btn-next');
periodPrev.click(() => {
if (this.activePeriodIndex > 0) {
// console.log('prev')
this.activePeriodIndex -= 1;
this.activePeriod = this.periodData[this.activePeriodIndex];
this._chainActions('period');
this._setStateClasses();
}
this._adjustPeriodContainer();
});
periodNext.click(() => {
if (this.activePeriodIndex < this.periodData.length - 1) {
// console.log('next' + this.activePeriodIndex)
this.activePeriodIndex += 1;
this.activePeriod = this.periodData[this.activePeriodIndex];
this._chainActions('period');
this._setStateClasses();
}
this._adjustPeriodContainer();
});
let timelinePrev = $(this.base).find('.timeline-container .btn-back');
let timelineNext = $(this.base).find('.timeline-container .btn-next');
timelinePrev.click(() => {
if (this.activeCardIndex > 0) {
this.activeCardIndex -= 1;
this.activeCard = this.cardData[this.activeCardIndex];
this._chainActions('timeline');
this._setStateClasses();
}
this._adjustCardContainer();
this._adjustPeriodContainer();
});
timelineNext.click(() => {
if (this.activeCardIndex < this.cardData.length - 1) {
this.activeCardIndex += 1;
this.activeCard = this.cardData[this.activeCardIndex];
this._chainActions('timeline');
this._setStateClasses();
}
this._adjustCardContainer();
this._adjustPeriodContainer();
});
// ## assign each timeline li
for (let i = 0; i < this.timelineData.length; i++) {
$(this.timelineData[i]).click(() => {
this.activeCardIndex = this.cardData[i].index;
this.activeCard = this.cardData[this.activeCardIndex];
this._chainActions('timeline');
this._setStateClasses();
this._adjustCardContainer();
this._shiftTimeline();
});
}
}
// ## color ##
_initialColor() {
for (let i = 0; i < this.periodData.length; i++) {
let p = this.periodData[i].period;
this.periodData[i].color = this.color[p];
let temp = this.periodData[i];
$(temp).css('border-color', temp.color);
$(temp).find('.year').css('color', temp.color);
// ## color for timeline items, this part utilize the period name as class which will be add to the li later
// ### cross browser bug fix
let sbstyle = document.createElement("style");
document.head.appendChild(sbstyle);
// let sheet = document.styleSheets[0]
sbstyle.sheet.insertRule('li.' + p + '.active { background-color: ' + this.color[p] + ' !important } ', 0);
sbstyle.sheet.insertRule('li.' + p + '::before { background-color: ' + this.color[p] + ' } ', 0);
sbstyle.sheet.insertRule('li.' + p + '::after { background-color: ' + this.color[p] + ' } ', 0);
}
for (let i = 0; i < this.cardData.length; i++) {
let p = this.cardData[i].period;
this.cardData[i].color = this.color[p];
let temp = this.cardData[i];
$(temp).css('border-color', temp.color);
$(temp).find('.year').css('color', temp.color);
}
}
_adjustPeriodContainer() {
let activeH = $(this.activePeriod).outerHeight();
$(this.periodContainer).height(activeH);
console.log('top adjusted');
}
_adjustCardContainer() {
let activeH = $(this.activeCard).outerHeight() + 24;
$(this.cardContainer).height(activeH);
console.log('bot adjusted');
}
_shiftTimeline() {
// #### We need to fix this part if using this component in different sizes ####
let timelineW = $(this.base).find('.timeline-container').outerWidth();
let timelinePadding = 210;
let timelineCenter = 300;
let liWidth = 16;
let activeNodeX = $(this.timelineData[this.activeCardIndex]).position().left;
let finalPos = -activeNodeX + timelinePadding;
$(this.timelineNodeContainer).css('left', finalPos);
console.log(activeNodeX);
}
_chainActions(state) {
switch (state) {
case 'period':
console.log('period');
if (this.activePeriod.period != this.activeCard.period) {
// ## find the closest li with the active period
let ta = [];
for (let i = 0; i < this.cardData.length; i++) {
let temp = this.cardData[i];
if (this.activePeriod.period === temp.period)
ta.push(temp);
}
this.activeCard = ta[0];
this.activeCardIndex = ta[0].index;
}
break;
case 'timeline':
console.log('timeline');
if (this.activeCard.period != this.activePeriod.period) {
let ta;
for (let i = 0; i < this.periodData.length; i++) {
let temp = this.periodData[i];
if (this.activeCard.period === temp.period)
ta = temp;
}
this.activePeriod = ta;
this.activePeriodIndex = ta.index;
}
break;
}
this._shiftTimeline();
this._adjustCardContainer();
}
}
// ## document load ##
$(document).ready(function () {
let colorcode = {
'period1': '#fec541',
'period2': '#36d484',
'period3': '#32ccf4'
};
let timeline = new PRESTimeline($('#this-timeline'), colorcode);
});
Loading

0 comments on commit 33d4bfd

Please sign in to comment.