From 40ebe00dc085c507635a690ce1df24a77ae661d0 Mon Sep 17 00:00:00 2001 From: Eric Bremner <ebremner@uwaterloo.ca> Date: Fri, 29 Jul 2022 13:45:20 -0400 Subject: [PATCH] ISTWCMS-5718: adding ff --- src/patterns/04-components/_index.scss | 1 + .../facts-and-figures/_facts-and-figures.scss | 959 ++++++++++++++++++ .../facts-and-figures/_infographics.twig | 55 + .../facts-and-figures/facts-and-figures.js | 268 +++++ .../facts-and-figures/facts-and-figures.md | 14 + .../facts-and-figures/facts-and-figures.twig | 50 + .../facts-and-figures/facts-and-figures.yml | 67 ++ .../facts-and-figures/jquery.circliful.min.js | 1 + 8 files changed, 1415 insertions(+) create mode 100644 src/patterns/04-components/facts-and-figures/_facts-and-figures.scss create mode 100644 src/patterns/04-components/facts-and-figures/_infographics.twig create mode 100644 src/patterns/04-components/facts-and-figures/facts-and-figures.js create mode 100644 src/patterns/04-components/facts-and-figures/facts-and-figures.md create mode 100644 src/patterns/04-components/facts-and-figures/facts-and-figures.twig create mode 100644 src/patterns/04-components/facts-and-figures/facts-and-figures.yml create mode 100644 src/patterns/04-components/facts-and-figures/jquery.circliful.min.js diff --git a/src/patterns/04-components/_index.scss b/src/patterns/04-components/_index.scss index cd3ddf6b..92a92e3d 100644 --- a/src/patterns/04-components/_index.scss +++ b/src/patterns/04-components/_index.scss @@ -15,6 +15,7 @@ @forward 'copy-text/copy-text'; @forward 'date/date'; @forward 'exp_col_block/exp_col_block'; +@forward 'facts-and-figures/facts-and-figures'; @forward 'filters/filters'; @forward 'icon/icon'; @forward 'icon/icon--button/icon--button'; diff --git a/src/patterns/04-components/facts-and-figures/_facts-and-figures.scss b/src/patterns/04-components/facts-and-figures/_facts-and-figures.scss new file mode 100644 index 00000000..73b6b46a --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/_facts-and-figures.scss @@ -0,0 +1,959 @@ +//appearance +$global-radius: 3px; +$global-rounded: 1000px; +$highlighted-fact-radius: $global-radius; +$highlighted-fact-round: $global-rounded; + +@use '../../01-core' as *; + +@each $faculty, $colour in $faculties_colours { + + .uw-ff { + .#{$faculty} { + @if $faculty == org-default { + .graph{ + background: var(--uw-gold); + } + + .number, + .timer { + color: var(--uw-black); + fill: var(--uw-black); + } + + .uw-ff--text { + &__big { + color: var(--uw-black); + } + + &__medium { + color: var(--uw-black); + } + + &__caption { + color: var(--uw-black); + } + + &__small { + background-color: var(--uw-gold); + color: var(--uw-black); + } + } + } + + @else if $faculty == org-stp or $faculty == org-stj or $faculty == org-ren or $faculty == org-cgc { + .graph { + background: var(--#{$colour}-primary); + } + + .number, + .timer { + color: var(--#{$colour}-primary); + fill: var(--#{$colour}-primary); + } + + .uw-ff--text { + &__big { + color: var(--#{$colour}-primary); + } + + &__medium { + color: var(--#{$colour}-primary); + } + + &__small { + background-color: var(--#{$colour}-primary); + color: var(--uw-white); + } + } + } + + @else if $faculty == neutral { + &__big { + color: var(--#{$colour}-3); + } + &__medium { + color: var(--#{$colour}-3); + + } + &__small{ + background-color: var(--#{$colour}-3); + color: var(--#{$colour}-3); + + } + } + + @else { + .graph{ + background: var(--#{$colour}-4); + } + + .number, + .timer { + color: var(--#{$colour}-4); + fill: var(--#{$colour}-4); + } + + .uw-ff--text { + &__big { + color: var(--#{$colour}-4); + } + &__medium { + color: var(--#{$colour}-4); + } + &__small{ + background-color: var(--#{$colour}-4); + color: var(--uw-white); + } + } + } + } + + &--with-bubbles{ + &__white{ + .#{$faculty} { + @if $faculty == org-default { + .uw-ff--text { + &__big { + color: var(--uw-black); + } + + &__medium { + color: var(--uw-black); + } + + &__caption { + color: var(--uw-black); + } + + &__small { + background-color: var(--uw-gold); + color: var(--uw-black); + } + } + } + + @else if $faculty == org-stp or $faculty == org-stj or $faculty == org-ren or $faculty == org-cgc { + .uw-ff--text { + &__big { + color: var(--#{$colour}-primary); + } + + &__medium { + color: var(--#{$colour}-primary); + } + + &__small { + background-color: var(--#{$colour}-primary); + color: var(--uw-white); + } + } + } + @else if $faculty == neutral { + &__big { + color: var(--#{$colour}-1); + } + + &__medium { + color: var(--#{$colour}-1); + + } + &__small{ + background-color: var(--#{$colour}-1); + color: var(--uw-black); + } + } + + @else { + .uw-ff--text { + &__big { + color: var(--#{$colour}-4); + } + + &__medium { + color: var(--#{$colour}-4); + } + + &__small { + background-color: var(--#{$colour}-4); + color: var(--uw-white); + } + } + } + } + } + &__black{ + .#{$faculty} { + @if $faculty == org-default { + .number, + .timer { + color: var(--uw-white); + fill: var(--uw-white); + } + .uw-ff--text { + &__big { + color: var(--uw-white); + } + + &__medium { + color: var(--uw-white); + } + + &__small { + background-color: var(--uw-gold); + color: var(--uw-black); + } + } + } + + @else if $faculty == org-stp or $faculty == org-stj or $faculty == org-ren or $faculty == org-cgc { + .uw-ff--text { + &__big { + color: var(--#{$colour}-light); + } + + &__medium { + color: var(--#{$colour}-light); + + } + + &__small { + background-color: var(--#{$colour}-light); + color: var(--uw-white); + } + } + } + @else if $faculty == neutral { + &__big { + color: var(--#{$colour}-1); + } + + &__medium { + color: var(--#{$colour}-1); + } + + &__small { + background-color: var(--#{$colour}-1); + color: var(--uw-black); + } + } + + @else { + .number, + .timer { + color: var(--#{$colour}-4); + } + .uw-ff--text { + &__big { + color: var(--#{$colour}-4); + } + + &__medium { + color: var(--#{$colour}-1); + } + + &__small{ + background-color: var(--#{$colour}-primary); + color: var(--uw-white); + } + } + } + } + } + &__grey{ + .#{$faculty} { + @if $faculty == org-default { + .uw-ff--text { + &__big { + color: var(--uw-black); + } + + &__medium { + color: var(--uw-black); + } + + &__small { + background-color: var(--uw-gold); + color: var(--uw-black); + } + } + } + @else { + .uw-ff--text { + &__big { + color: var(--#{$colour}-4); + } + &__medium { + color: var(--#{$colour}-4); + } + + &__small{ + background-color: var(--#{$colour}-4); + color: var(--uw-white); + } + } + } + } + } + + &__gold{ + .#{$faculty} { + @if $faculty == org-default { + .graph{ + background: var(--uw-black); + } + + .number, + .timer { + color: var(--uw-black); + fill: var(--uw-black); + } + + .uw-ff--text { + &__big { + color: var(--uw-black); + } + + &__medium { + color: var(--uw-black); + } + + &__small { + background-color: var(--uw-black); + color: var(--uw-gold); + } + } + } + + @else { + .graph{ + background: var(--uw-black); + } + + .number, + .timer { + color: var(--uw-black); + fill: var(--uw-black); + } + + .uw-ff--text { + &__big { + color: var(--uw-black); + } + + &__medium { + color: var(--uw-black); + } + + &__small { + background-color: var(--uw-black); + color: var(--uw-gold); + } + } + } + } + } + } + } +} + +.data-usecarousel, +.data-numberpercarousel { + height: 0; + visibility: hidden; +} + +.uw-ff .owl-carousel .owl-item img { + width: auto; +} + +/* Override default display: block +from owl script. Ensures bubbles +are the same height. */ +.uw-ff { + &--with-bubbles{ + .uw-ff--fact{ + border-radius: $highlighted-fact-radius + 10; + &:nth-of-type(odd) { + &::after { + border-left: var(--size-2) solid transparent; + border-right: var(--size-2) solid transparent; + content: ''; + height: 0; + left: 50%; + margin-left: -0.75rem; + position: absolute; + top: -1.25rem; + width: 0; + } + } + + &:nth-of-type(even) { + &::after { + border-left: var(--size-2) solid transparent; + border-right: var(--size-2) solid transparent; + bottom: -1.25rem; + content: ''; + height: 0; + left: 50%; + margin-left: -0.75rem; + position: absolute; + width: 0; + } + } + } + + &__black{ + .uw-ff--fact { + background-color: var(--uw-black); + + &:nth-of-type(odd) { + &::after { + border-bottom: var(--size-3) solid var(--uw-black); + } + } + + &:nth-of-type(even) { + &::after { + border-top: var(--size-3) solid var(--uw-black); + } + } + } + } + &__white{ + .uw-ff--fact{ + background-color: var(--uw-white); + + &:nth-of-type(odd) { + &::after { + border-bottom: var(--size-3) solid var(--uw-white); + + } + } + + &:nth-of-type(even) { + &::after { + border-top: var(--size-3) solid var(--uw-white); + } + } + } + } + &__grey{ + .uw-ff--fact{ + background-color: var(--uw-black-1); + + &:nth-of-type(odd) { + &::after { + border-bottom: var(--size-3) solid var(--uw-black-1); + } + } + &:nth-of-type(even) { + &::after { + border-top: var(--size-3) solid var(--uw-black-1); + } + } + } + } + + &__gold{ + .uw-ff--fact{ + background-color: var(--uw-gold); + + &:nth-of-type(odd) { + &::after { + border-bottom: var(--size-3) solid var(--uw-gold); + } + } + + &:nth-of-type(even) { + &::after { + border-top: var(--size-3) solid var(--uw-gold); + } + } + } + } + } + + &--wrapper { + clear: both; + display: block; + height: auto; + list-style-type: none; + margin: 0; + position: relative; + width: 100%; + + &__text-left { + .uw-ff--fact { + align-items: flex-start; + text-align: left; + } + + .infographic-circle, + .infographic-half-circle { + justify-self: flex-start; + } + .uw-ff--text { + text-align: left; + } + } + + &__text-right { + .infographic-number { + display:block; + } + + .infographic-vertical { + justify-self: flex-end; + width:auto; + } + + .uw-ff--fact{ + align-items: flex-end; + text-align: right; + } + + .infographic-circle, + .infographic-half-circle { + justify-self: flex-end; + } + + .uw-ff--text { + text-align: right; + + &__icon { + img { + clear: both; + float: right; + } + } + } + } + + &__text-center { + .uw-ff--fact { + text-align: center; + } + + .highlighted-fact-infographic{ + align-items: center; + } + + .infographic-vertical { + justify-self: center; + width: auto; + } + + .infographic-number{ + margin: 0 auto; + text-align: center; + width: auto; + } + + .infographic-circle, + .infographic-half-circle { + justify-self: center; + } + + .uw-ff--text { + text-align: center; + + &__icon { + img { + margin: 0 auto; + } + } + + &__small { + margin: var(--size-2) auto; + } + } + } + } + + &--fact { + align-content: center; + display: grid; + font-weight: 300; + padding: var(--size-4); + position: relative; + row-gap: var(--size-05); + width: 100%; + } + + &--text { + grid-column: 1 / 2; + grid-row: auto ; + width: 100%; + + &__icon { + display:block; + + img { + display: block; + height: 100%; + max-height: var(--size-12); + } + } + + &__big { + font-family: var(--font-condensed); + font-size: var(--font-size-11); + font-weight: var(--font-weight-400); + line-height: var(--font-lineheight-2); + } + + &__medium { + font-size: var(--font-size-2); + font-weight: var(--font-weight-300); + hyphens: none; + line-height: var(--font-lineheight-2); + padding: var(--size-1) 0; + } + + &__small { + display: inline-block !important; + font-family: var(--font-systemmedium); + font-size: var(--font-size-0); + hyphens: none; + line-height: var(--font-lineheight-2); + margin-bottom: var(--size-2); + margin-top: var(--size-2); + padding: var(--size-1) var(--size-205); + width: auto; + } + + &__caption { + font-size: var(--font-size-00); + font-style: italic; + hyphens: none; + line-height: var(--font-lineheight-2); + padding: var(--size-05) 0; + + p { + float: none; + font-size: var(--font-size-00); + line-height: var(--font-lineheight-2); + } + } + } + + &--no-carousel{ + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 10px; + + .uw-ff{ + &--fact{ + @include flex(1 1 auto); + @include flex-grow(1); + margin: var(--size-205) 0; + width: 100%; + + @media(min-width: $screen-xs) { + width: 50%; + } + + @media(min-width: $screen-md) { + width: 30%; + } + + @media(min-width: $screen-xl) { + width: 25%; + } + + .uw-contained-width--wide & { + @media(min-width: $screen-xs) { + width: 45%; + } + + @media(min-width: $screen-md) { + width: 45%; + } + + @media(min-width: $screen-xl) { + width: 45%; + } + } + + .uw-node__sidebar &, + .uw-contained-width--narrow & { + @media(min-width: $screen-xs) { + width: 100%; + } + + @media(min-width: $screen-md) { + width: 100%; + } + + @media(min-width: $screen-xl) { + width: 100%; + } + } + + .uw-full-width & { + + @media(min-width: $screen-xs) { + width: 45%; + } + + @media(min-width: $screen-md) { + width: 30%; + } + + @media(min-width: $screen-xl) { + width: 23%; + } + } + } + } + } + + &--carousel{ + .owl-stage{ + display: flex; + } + + .owl-item { + display: flex; + position: relative; + + &:nth-of-type(odd) { + .uw-ff--fact{ + &::after{ + bottom: inherit; + top: -1.25rem; + } + } + } + + &:nth-of-type(even) { + .uw-ff--fact{ + &::after{ + bottom: -1.25rem; + top: inherit; + transform: rotate(180deg) + } + } + } + + &:first-child { + margin-left: 0; + } + } + + .owl-stage-outer { + padding: var(--size-4) 0; + } + } +} + +.infographic-fields-inline .fieldset-wrapper { + display: grid; + grid-gap: var(--size-2); + grid-template-columns: 12em minmax(auto, 20em) minmax(auto, 40%); +} + +.infographic-fields-inline .fieldset-wrapper .fieldset-description { + grid-column: 1 / span 3; +} + +.circliful .outer { + -webkit-animation-play-state: running; + fill: transparent; + stroke: var(--gray-7); + stroke-dasharray: 534; + stroke-width: 19.8; + /* firefox bug fix - won't rotate at 90deg angles */ + -moz-transform: rotate(-89deg) translateX(-190px); + transition: stroke-dashoffset 1s; +} + +.highlighted-fact-infographic { + align-items: center; + display: block; + height: 100%; + + .number, + .timer { + font-family: var(--font-condensedbook); + font-size: 2.25rem; + } + + .graph { + display: block; + } + + .infographic-texthide { + display: none; + font-family: var(--font-condensedbook); + font-size: 3.2rem; + width: 100%; + + .no-js & { + display:block; + } + + .no-js.js & { + display: none; + } + } + + &.infographic-number { + .number{ + font-size: 3.2rem; + + .timer { + display: inline; + font-size: 3.2rem; + } + } + } + + &.infographic-vertical { + + .graph-wrapper { + background: var(--gray-4); + height: 200px; + position: relative; + width: var(--size-10); + } + + .graph { + bottom: var(--size-xs); + min-height: var(--size-205); + position: absolute; + width: var(--size-10); + } + + .timer { + margin-left: var(--size-1); + width: 3.75rem; + } + + .timer::after { + content: '%'; + display: inline-block; + } + } + + &.infographic-horizontal { + margin: 0; + max-width: 100%; + + .graph-wrapper { + background: var(--gray-4); + height: var(--size-10); + margin-bottom: var(--size-2); + margin-right: var(--size-2); + position: relative; + width: calc(100% - 5rem); + } + + .graph { + display: block; + height: var(--size-10); + width: 1px; + } + + .timer { + width: 3.75rem; + } + + .timer::after { + content: '%'; + display: inline-block; + } + } + + &.infographic-half-circle { + width: 15.625rem; + + svg { + margin: calc(-0.14 * 100%) 0 calc(-0.4 * 100%); + } + } + + &.infographic-circle { + width: 15.625rem; + } +} + +.no-js .uw-ff--carousel .owl-carousel { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 10px; + + .uw-ff { + &--fact { + @include flex(1 1 auto); + @include flex-grow(1); + margin: var(--size-205) 0; + width: 100%; + + @media(min-width: $screen-xs) { + width: 50%; + } + + @media(min-width: $screen-md) { + width: 30%; + } + + @media(min-width: $screen-xl) { + width: 25%; + } + + .uw-contained-width--wide & { + @media(min-width: $screen-xs) { + width: 45%; + } + + @media(min-width: $screen-md) { + width: 45%; + } + + @media(min-width: $screen-xl) { + width: 45%; + } + } + + .uw-node__sidebar &, + .uw-contained-width--narrow & { + @media(min-width: $screen-xs) { + width: 100%; + } + + @media(min-width: $screen-md) { + width: 100%; + } + + @media(min-width: $screen-xl) { + width: 100%; + } + } + + .uw-full-width & { + @media(min-width: $screen-xs) { + width: 45%; + } + + @media(min-width: $screen-md) { + width: 30%; + } + + @media(min-width: $screen-xl) { + width: 23%; + } + } + } + } +} + +.no-js.js { + .uw-ff--carousel .owl-carousel.owl-theme { + display: flex !important; + flex-flow: column; + } +} diff --git a/src/patterns/04-components/facts-and-figures/_infographics.twig b/src/patterns/04-components/facts-and-figures/_infographics.twig new file mode 100644 index 00000000..de2514d7 --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/_infographics.twig @@ -0,0 +1,55 @@ +{% if ffs.bg_colour == 'gold' %} + {% set graph_colour = "#000000" %} +{% else %} + {% if ffs.theme == 'org-art' %} + {% set graph_colour = "#d93f00" %} + {% elseif ffs.theme == 'org-eng' %} + {% set graph_colour = "#57058b" %} + {% elseif ffs.theme == 'org-ahs' %} + {% set graph_colour = "#005963" %} + {% elseif ffs.theme == 'org-mat' %} + {% set graph_colour = "#c60078" %} + {% elseif ffs.theme == 'org-sci' %} + {% set graph_colour = "#0033be" %} + {% elseif ffs.theme == 'org-env' %} + {% set graph_colour = "#607000" %} + {% elseif ffs.theme == 'org-stp' %} + {% set graph_colour = "#879637" %} + {% elseif ffs.theme == 'org-stj' %} + {% set graph_colour = "#01573e" %} + {% elseif ffs.theme == 'org-ren' %} + {% set graph_colour = "#00693c" %} + {% elseif ffs.theme == 'org-cgc' %} + {% set graph_colour = "#c4262e" %} + {% elseif ffs.theme == 'org-school' %} + {% set graph_colour = "#b71233" %} + {% elseif ffs.theme == 'org-default' %} + {% set graph_colour = "#FFD54F" %} + {% endif %} +{% endif %} + +<div + class="highlighted-fact-infographic infographic-{{ infographics.info_type | replace({'_': '-'}) }} " + data-infographic-type="{{ infographics.info_type }}" + data-percent="{{ infographics.info_text }}" + data-foregroundColor="{{ graph_colour }}" +> + {% if infographics.info_type == 'number' %} + <span class="number"> + <span class="timer">{{ infographics.info_text }}</span> + {% if infographics.info_suffix %} + {{ infographics.info_suffix }} + {% endif %} + </span> + {% else %} + <div class="infographic-texthide"> + {{ infographics.info_text }} + {% if infographics.info_suffix %} + {{ infographics.info_suffix }} + {% else %} + <span>%</span> + {% endif %} + </div> + {% endif %} + +</div> diff --git a/src/patterns/04-components/facts-and-figures/facts-and-figures.js b/src/patterns/04-components/facts-and-figures/facts-and-figures.js new file mode 100644 index 00000000..6d613535 --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/facts-and-figures.js @@ -0,0 +1,268 @@ +/** + * Javascript for facts and figures + */ + +(function ($, Drupal) { + Drupal.behaviors.factfigure = { + attach: function (context, settings) { + function runCarousel(id, numOfItems) + { + // Add the carousel to the FF using the id. + $(id + " .owl-carousel").owlCarousel( + { + margin: 10, + nav: true, + navContainerClass: "uw-owl-nav", + navText: [ + "‹ prev", + "next ›" + ], + responsiveClass: true, + responsive: { + 0: { + items: 1 + }, + 600: { + items: numOfItems <= 2 ? (numOfItems - 1 > 0) ? numOfItems - 1 : 1 : 2 + + }, + 1000: { + items: numOfItems + + } + } + } + ); + } + // Check if the element is is in view. + function isElementInViewport(elem) + { + var $elem = $(elem); + // Get the scroll position of the page. + var viewportTop = $("html").scrollTop(); + var viewportBottom = viewportTop + $(window).height(); + + // Get the position of the element on the page. + // Adds a little padding so it triggers when the + // element is closer to the middle of the page. + var elemTop = Math.round($elem.offset().top); + var elemBottom = elemTop + $elem.height(); + return ((elemTop < viewportBottom) && (elemBottom > viewportTop)); + } + // Run the animation if the element is in view. + function checkAnimation(infoHorizontal, infoVertical, infoNumber) + { + $(infoHorizontal).each( + function () { + if ($(this).hasClass("animated")) { + return; + } + if (isElementInViewport($(this))) { + runAnimation($(this)); + } + } + ); + $(infoVertical).each( + function () { + if ($(this).hasClass("animated")) { + return; + } + if (isElementInViewport($(this))) { + runAnimation($(this)); + } + } + ); + $(infoNumber).each( + function () { + if ($(this).hasClass("animated")) { + + return; + } + if (isElementInViewport($(this))) { + runAnimation($(this)); + } + } + ); + } + // Isolating this to try to run it when the slider changes. + function runAnimation(el) + { + var type = el.data("infographic-type"); + var percent = el.data("percent"); + + // Animate the graph. + if (type === "horizontal") { + el.find(".graph-wrapper .graph").animate({"width" : percent + "%"}, 2000); + } + else if (type === "vertical") { + el.find(".graph-wrapper .graph").animate({"height" : percent + "%"}, 2000); + } + animateNumber(el.find(".timer"), percent); + el.addClass("animated"); + } + // Animate the number. + function animateNumber(el, percent) + { + var hasComma; + var num; + // Find out if the number has a thousand marker (comma). + if (percent.toString().indexOf(",") >= 0) { + hasComma = true; + // If so, remove it for now so the animation will work. + percent = percent.replace(/,/g, ""); + } + else { + hasComma = false; + } + + $({counter: 0}).animate( + {counter: percent}, { + duration: 2000, + step: function () { + var num = Math.ceil(this.counter).toString(); + if (hasComma) { + // Add back the comma. + while (/(\d+)(\d{3})/.test(num)) { + num = num.replace(/(\d+)(\d{3})/, "$1" + "," + "$2"); + } + } + $(el).text(num); + }, + // Ensure the correct value is shown when animation is complete + // fixes issue with incomplete counters for large numbers + // see: https://stackoverflow.com/questions/50331552/jquery- + // counter-fails-to-show-the-correct-value-after-animation + complete : function () { + if (hasComma) { + // Add back the comma. + percent = num.replace(/(\d+)(\d{3})/, "$1" + "," + "$2"); + } + $(el).text(percent); + } + } + ); + } + // Build Info graphics. + function setupInfoGraphics(id) + { + + // For circle infographics, first + // check to make sure library is loaded. + if ($.fn.circliful) { + + // Set default options for circle infographics. + var $circlifulOptions = ""; + $circlifulOptions = { + animation: 1, + animationStep: 3, + foregroundBorderWidth: 15, + backgroundBorderWidth: 15, + backgroundColor: "#a2a2a2", + animateInView: "true", + fontColor: "#4e4e4e", + percentageTextSize: "35", + }; + + var circles = id + " .infographic-circle"; + + // Create circle infographic. + $(circles).each( + function () { + $(this).circliful($circlifulOptions); + } + ); + + var halfCircles = id + " .infographic-half-circle"; + + // Create half circle. + $(halfCircles).each( + function () { + $(this).circliful( + $.extend($circlifulOptions, {halfCircle: "true"}) + ); + } + ); + } + + // Setting selectors for the animation checks + // and bar builds. + var infoNumber = id + " .infographic-number"; + var infoVertical = id + " .infographic-vertical"; + var infoHorizontal = id + " .infographic-horizontal"; + + $(infoHorizontal).each( + function () { + $(this).append("<div class='graph-wrapper'><span class='graph'></span></div><span class='timer'>" + $(this).data("percent") + "</span>"); + } + ); + + $(infoVertical).each( + function () { + $(this).append("<div class='graph-wrapper'><span class='graph'></span></div><span class='timer'>" + $(this).data("percent") + "</span>"); + + } + ); + + // Check when the page loads. + checkAnimation(infoHorizontal, infoVertical, infoNumber); + + // Capture scroll events. + $(window).scroll( + function () { + checkAnimation(infoHorizontal, infoVertical, infoNumber); + } + ); + }; + // Function to run the FF code. + function runFF() + { + + // Step through each FF on the page. + $(".uw-ff").each( + function () { + // Get the id to reference the individual FF. + // Need this to ensure that if more than one FF on the page, + // that all FFs get the carousel added. + var id = "#uw-ff-" + $(this).data("id"); + + // Check to see if we have a carousel + // set from drupal in twig. + var hasCarousel = $(this).data("carousel") === "yes"; + + // If we have one. + if (hasCarousel) { + + // Get the number of items for the carousel, if any. + var numOfItems = $(id).data("num-per-carousel") !== "" ? $(this).data("num-per-carousel") : 3; + + // Run the carousel. + runCarousel(id, numOfItems); + } + // Check to see if info graphic is animated + // return else run setup. ensures we dont fire 2x. + if ($(".highlighted-fact-infographic ").hasClass("animated")) { + return; + } + else { + setupInfoGraphics(id); + } + } + ); + } + // When the data-ff element is on page we know the update button is on page. + if ($("[data-layout-builder-target-highlight-id] [data-ff='yes']").length) { + if ($("[data-ff='yes']")) { + runFF(); + } + } + $(document).ready( + function () { + // Run the FF code on each of the figures. + if ($(".uw-ff").length) { + runFF(); + } + } + ); + } + }; +})(jQuery, Drupal); diff --git a/src/patterns/04-components/facts-and-figures/facts-and-figures.md b/src/patterns/04-components/facts-and-figures/facts-and-figures.md new file mode 100644 index 00000000..72d00ac6 --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/facts-and-figures.md @@ -0,0 +1,14 @@ +--- +el: .uw-ff +title: Facts and Figures +--- + +__Variables:__ +* ffs: [array] Classes to modify the default component styling. + * id: [string] Unique id of the fact and figure. + * show: [boolean] Show the bubbles on the fact and figure. + * theme: [string] The theme/faculty to be applied to the fact and figure. + * text_align: [string] Which way the text is to be aligned. + * details: [array] Details about the text of the fact and figure. + * icon/text: [string] Either the string of text or the URL of the icon. + * type: [string] The type of text (big, medium, small or icon). diff --git a/src/patterns/04-components/facts-and-figures/facts-and-figures.twig b/src/patterns/04-components/facts-and-figures/facts-and-figures.twig new file mode 100644 index 00000000..bfbea4ed --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/facts-and-figures.twig @@ -0,0 +1,50 @@ +<div id="uw-ff-{{ ffs.id }}" class="uw-ff {% if ffs.show %}uw-ff--with-bubbles uw-ff--with-bubbles__{{ ffs.bg_colour}}{% else%}uw-ff__{{ ffs.bg_colour}}{% endif %}" data-carousel="{{ ffs.num_per_carousel ? 'yes' :'no' }}" data-num-per-carousel="{{ ffs.num_per_carousel }}" data-id="{{ ffs.id }}"> + <div class="uw-ff--wrapper uw-ff--wrapper__text-{{ ffs.text_align }} {{ ffs.num_per_carousel ? 'uw-ff--carousel' : 'uw-ff--no-carousel' }} {{ ffs.theme }}"> + {% if ffs.num_per_carousel >= 1%} + {% embed '@layouts/carousel/carousel.twig' %} + {% block content %} + {% for details in ffs.details %} + <div class="uw-ff--fact"> + + {% for detail in details %} + + {% if detail.type == 'infographic' %} + {% include '@components/facts-and-figures/_infographics.twig' with { + 'infographics': detail, + } %} + {% elseif detail.type == 'icon' %} + <div class="uw-ff--text uw-ff--text__{{ detail.type }}"> + <img src="{{ detail.icon }}" /> + </div> + {% else %} + <span class="uw-ff--text uw-ff--text__{{ detail.type }}">{{ detail.text }}</span> + {% endif %} + {% endfor %} + </div> + {% endfor %} + {% endblock %} + {% endembed %} + {% else %} + {% for details in ffs.details %} + <div class="uw-ff--fact"> + {% for detail in details %} + + {% if detail.type == 'infographic' %} + + {% include '@components/facts-and-figures/_infographics.twig' with { + 'infographics': detail, + } %} + {% elseif detail.type == 'icon' %} + <div class="uw-ff--text uw-ff--text__{{ detail.type }}"> + <img src="{{ detail.icon }}" /> + </div> + {% else %} + <span class="uw-ff--text uw-ff--text__{{ detail.type }}">{{ detail.text }}</span> + {% endif %} + {% endfor %} + </div> + {% endfor %} + + {% endif %} + </div> +</div> diff --git a/src/patterns/04-components/facts-and-figures/facts-and-figures.yml b/src/patterns/04-components/facts-and-figures/facts-and-figures.yml new file mode 100644 index 00000000..e371ef04 --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/facts-and-figures.yml @@ -0,0 +1,67 @@ +ffs: + id: 1 + show: true + bg_colour: 'grey' + theme: 'org-default' + text_align: 'center' + num_per_carousel: 3 + details: + - + - + type: 'infographics' + infographics: + type: 'number' + fact: '90' + suffix: 'years' + - + text: 'Big #1' + type: 'big' + - + text: 'Small #1' + type: 'small' + - + - type: 'infographics' + infographics: + type: 'half_circle' + fact: '90%' + - + text: 'Big #2' + type: 'big' + - + text: 'Small #1' + type: 'small' + - + - type: 'infographics' + infographics: + type: 'vertical' + fact: '90' + suffix: '%' + - + text: 'Big #2' + type: 'big' + - + text: 'Small #1' + type: 'small' + - + - type: 'infographics' + infographics: + type: 'horizontal' + fact: '90' + suffix: '%' + - + text: 'Big #2' + type: 'big' + - + text: 'Small #1' + type: 'small' + - + - type: 'infographics' + infographics: + type: 'circle' + fact: '90%' + - + text: 'Big #2' + type: 'big' + - + text: 'Small #1' + type: 'small' diff --git a/src/patterns/04-components/facts-and-figures/jquery.circliful.min.js b/src/patterns/04-components/facts-and-figures/jquery.circliful.min.js new file mode 100644 index 00000000..253235ef --- /dev/null +++ b/src/patterns/04-components/facts-and-figures/jquery.circliful.min.js @@ -0,0 +1 @@ +"use strict";!function(z){z.fn.circliful=function(e,T){var S=z.extend({foregroundColor:"#3498DB",backgroundColor:"#ccc",pointColor:"none",fillColor:"none",foregroundBorderWidth:15,backgroundBorderWidth:15,pointSize:28.5,fontColor:"#aaa",beforePercent:"",percent:75,animation:1,animationStep:5,icon:"none",iconSize:"30",iconColor:"#ccc",iconPosition:"top",iconDecoration:!0,target:0,showPercent:1,percentageTextSize:22,percentageX:100,percentageY:113,textAdditionalCss:"",targetPercent:0,targetTextSize:17,targetColor:"#2980B9",text:null,textStyle:null,textColor:"#666",textY:null,textX:null,percentages:[],multiPercentageLegend:0,textBelow:!1,noPercentageSign:!1,replacePercentageByText:null,halfCircle:!1,animateInView:!1,decimals:0,alwaysDecimals:!1,title:"Circle Chart",description:"",progressColor:null,strokeLinecap:"butt"},e);return this.each(function(){var r,n,x=z(this);r=S,n=x.data(),z.each(r,function(e,t){e.toLowerCase()in n&&(r[e]=n[e.toLowerCase()])});var d,p,l=S.percent,e=83,t=100,f=S.percentageY,g=S.percentageX,h="",u=S.backgroundBorderWidth,a=S.progressColor;if(S.halfCircle?"left"===S.iconPosition?(t=80,g=117,f=e=100):S.halfCircle&&(e=80,f=100):"bottom"===S.iconPosition?(e=124,f=95):"left"===S.iconPosition?(t=80,e=110,g=117):"middle"===S.iconPosition?(0===S.percentages.length&&(S.iconDecoration&&(d='<g stroke="'+("none"!==S.backgroundColor?S.backgroundColor:"#ccc")+'" ><line x1="133" y1="50" x2="140" y2="40" stroke-width="2" /></g>',d+='<g stroke="'+("none"!==S.backgroundColor?S.backgroundColor:"#ccc")+'" ><line x1="140" y1="40" x2="200" y2="40" stroke-width="2" /></g>'),g=170,f=35),e=110):"right"===S.iconPosition?(t=120,e=110,g=80):"top"===S.iconPosition&&"none"!==S.icon&&(f=120),0<S.targetPercent&&!0!==S.halfCircle&&(f=95,d='<g stroke="'+("none"!==S.backgroundColor?S.backgroundColor:"#ccc")+'" ><line x1="75" y1="101" x2="125" y2="101" stroke-width="1" /></g>',d+='<text text-anchor="middle" x="'+g+'" y="120" style="font-size: '+S.targetTextSize+'px;" fill="'+S.targetColor+'">'+S.targetPercent+(S.noPercentageSign&&null===S.replacePercentageByText?"":"%")+"</text>",d+='<circle cx="100" cy="100" r="69" fill="none" stroke="'+S.backgroundColor+'" stroke-width="3" stroke-dasharray="450" transform="rotate(-90,100,100)" />',d+='<circle cx="100" cy="100" r="69" fill="none" stroke="'+S.targetColor+'" stroke-width="3" stroke-dasharray="'+4.35*S.targetPercent+', 20000" transform="rotate(-90,100,100)" />'),null!==S.text&&(S.halfCircle?S.textBelow?d+='<text text-anchor="middle" x="'+(null!==S.textX?S.textX:"100")+'" y="'+(null!==S.textY?S.textY:"64%")+'" style="'+S.textStyle+'" fill="'+S.textColor+'">'+S.text+"</text>":d+='<text text-anchor="middle" x="'+(null!==S.textX?S.textX:"100")+'" y="'+(null!==S.textY?S.textY:"115")+'" style="'+S.textStyle+'" fill="'+S.textColor+'">'+S.text+"</text>":S.textBelow?d+='<text text-anchor="middle" x="'+(null!==S.textX?S.textX:"100")+'" y="'+(null!==S.textY?S.textY:"99%")+'" style="'+S.textStyle+'" fill="'+S.textColor+'">'+S.text+"</text>":d+='<text text-anchor="middle" x="'+(null!==S.textX?S.textX:"100")+'" y="'+(null!==S.textY?S.textY:"115")+'" style="'+S.textStyle+'" fill="'+S.textColor+'">'+S.text+"</text>"),p="none"!==S.icon?'<text text-anchor="middle" x="'+t+'" y="'+e+'" class="icon" style="font-size: '+S.iconSize+'px" fill="'+S.iconColor+'">&#x'+S.icon+"</text>":"",S.halfCircle){var o=0===S.showPercent?"display:none":"";x.addClass("svg-container").append(z('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">'+(void 0!==d?d:"")+'<clipPath id="cut-off-bottom"> <rect x="100" y="0" width="100" height="200" /> </clipPath><circle cx="100" cy="100" r="57" class="border" fill="'+S.fillColor+'" stroke="'+S.backgroundColor+'" stroke-width="'+u+'" stroke-dasharray="360" clip-path="url(#cut-off-bottom)" transform="rotate(-90,100,100)" /><circle class="circle" cx="100" cy="100" r="57" fill="none" stroke="'+S.foregroundColor+'" stroke-width="'+S.foregroundBorderWidth+'" stroke-dasharray="0,20000" transform="rotate(-180,100,100)" stroke-linecap="'+S.strokeLinecap+'" /><circle cx="100" cy="100" r="'+S.pointSize+'" fill="'+S.pointColor+'" clip-path="url(#cut-off-bottom)" transform="rotate(-90,100,100)" />'+p+'<text class="timer" text-anchor="middle" x="'+g+'" y="'+f+'" style="font-size: '+S.percentageTextSize+"px; "+h+";"+S.textAdditionalCss+'" fill="'+S.fontColor+'"><tspan class="number" style="'+o+'">'+(null===S.replacePercentageByText?0:S.replacePercentageByText)+'</tspan><tspan class="percent">'+(S.noPercentageSign||null!==S.replacePercentageByText?"":"%")+"</tspan></text>"))}else!function(){if(0<S.percentages.length){var e,t,r,n,o=S.percentages,l=47,a=360,c="";for(e=0;e<o.length;++e)r=o[e].percent,n=o[e].color,t=a/100*r,0<e&&(t=(a+=62.5)/100*r),c+='<circle cx="100" cy="100" r="'+(l+=10)+'" class="border" fill="'+S.fillColor+'" stroke="'+S.backgroundColor+'" stroke-width="'+u+'" stroke-dasharray="'+a+'" transform="rotate('+-90+',100,100)" /><circle class="circle" id="circle'+(e+1)+'" data-percent="'+r+'" cx="100" cy="100" r="'+l+'" class="border" fill="none" stroke="'+n+'" stroke-width="'+S.foregroundBorderWidth+'" stroke-dasharray="'+t+',20000" transform="rotate('+-90+',100,100)" stroke-linecap="'+S.strokeLinecap+'" />';var i=0===S.showPercent?"display:none":"";x.addClass("svg-container").append(z('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">'+(void 0!==d?d:"")+c+p+'<text class="timer" text-anchor="middle" x="'+g+'" y="'+f+'" style="font-size: '+S.percentageTextSize+"px; "+h+";"+S.textAdditionalCss+'" fill="'+S.fontColor+'"><tspan class="number" style="'+i+'">'+(null===S.replacePercentageByText?0:S.replacePercentageByText)+'</tspan><tspan class="percent">'+(S.noPercentageSign||null!==S.replacePercentageByText?"":"%")+"</tspan></text>")),0<S.percentages.length&&function(){var e,t=x.height(),r=x.width(),n=S.percentages,o="";for(e=0;e<n.length;++e){var l=n[e].title,a=n[e].color,c=n[e].percent;o+='<div><span class="color-box" style="background: '+a+'"></span>'+l+", "+c+"%</div>"}x.append(z("<div/>").append(o).attr("style","position:absolute;top:"+t/3+"px;left:"+(r+20)+"px").attr("class","legend-line"))}()}else{var s="";""!==S.beforePercent&&(s="f"===S.beforePercent.charAt(0)?'<tspan class="icon before-percent">&#x'+S.beforePercent+" </tspan>":'<tspan class="before-percent">'+S.beforePercent+" </tspan>");var i=0===S.showPercent?"display:none":"";x.addClass("svg-container").append(z('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">'+(void 0!==d?d:"")+'<circle cx="100" cy="100" r="57" class="border" fill="'+S.fillColor+'" stroke="'+S.backgroundColor+'" stroke-width="'+u+'" stroke-dasharray="360" transform="rotate(-90,100,100)" /><circle class="circle" cx="100" cy="100" r="57" fill="none" stroke="'+S.foregroundColor+'" stroke-width="'+S.foregroundBorderWidth+'" stroke-dasharray="0,20000" transform="rotate(-90,100,100)" stroke-linecap="'+S.strokeLinecap+'" /><circle cx="100" cy="100" r="'+S.pointSize+'" fill="'+S.pointColor+'" />'+p+'<text class="timer" text-anchor="middle" x="'+g+'" y="'+f+'" style="font-size: '+S.percentageTextSize+"px; "+h+";"+S.textAdditionalCss+'" fill="'+S.fontColor+'">'+s+'<tspan class="number" style="'+i+'">'+(null===S.replacePercentageByText?0:S.replacePercentageByText)+'</tspan><tspan class="percent">'+(S.noPercentageSign||null!==S.replacePercentageByText?"":"%")+"</tspan></text>"))}}();var c=x.find(".circle"),i=x.find(".timer"),s=30,y=0,C=S.animationStep,k=0,w=0,m=l,P=3.6*l;function b(){var e=c,t=P;if(0<S.percentages.length){var r,n=S.percentages,o=360;for(r=0;r<n.length;++r)t=o/100*(l=n[r].percent),e=x.find("#circle"+(r+1)),0<r&&(t=(o+=62.5)/100*l),v(e,t,o,l)}else v(e,t,360,S.percent)}function v(r,e,n,t){var o=window.setInterval(function(){e<=y?(window.clearInterval(o),k=1,"function"==typeof T&&T.call(this)):y+=C,S.halfCircle?t<=2*y/(n/100)&&1===k&&(y=n/100*t/2):t<=y/(n/100)&&1===k&&(y=n/100*t),w>S.target&&1===k&&(w=S.target),null===S.replacePercentageByText&&(m=S.halfCircle?parseFloat(100*y/n*2):parseFloat(100*y/n),!S.alwaysDecimals&&(0===t||1<t&&1!==k)?(m=Math.floor(m))>S.percent&&(m=S.percent.toFixed(S.decimals)):m=1!==k?Math.floor(m):S.percent.toFixed(S.decimals)),r.attr("stroke-dasharray",y+", 20000"),0===S.percentages.length?1===S.showPercent?i.find(".number").text(m):(i.find(".number").text(w),i.find(".percent").text("")):(i.find(".number").text(""),i.find(".percent").text("")),null!==a&&z.each(a,function(e,t){S.halfCircle&&(e/=2),e*(n/100)<=y&&r.css({stroke:t,transition:"stroke 0.1s linear"})})}.bind(r),s)}function B(){var e,t,r,n;c.hasClass("start")||(e=c.offset().top,t=e+c.outerHeight(),r=z(window).scrollTop(),n=r+z(window).height(),r<t&&e<n&&(c.addClass("start"),setTimeout(b,250)))}S.halfCircle&&(P=3.6*l/2),null!==S.replacePercentageByText&&(m=S.replacePercentageByText),1===S.animation||S.animateInView?S.animateInView?(B(),z(window).scroll(function(){B()})):b():0===S.percentages.length?(c.attr("stroke-dasharray",P+", 20000"),1===S.showPercent?i.find(".number").text(m):(i.find(".number").text(S.target),i.find(".percent").text(""))):null!==S.replacePercentageByText&&(i.find(".number").text(S.replacePercentageByText),i.find(".percent").text(""))})}}(jQuery); -- GitLab