Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Cornnerstone): BCTHEME-52 - Allowing carousel image to stretch distorts image #1711

Merged
merged 8 commits into from
Jul 14, 2020
65 changes: 53 additions & 12 deletions assets/js/theme/common/carousel.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,62 @@
import 'slick-carousel';

const showCarouselIfSlidesAnalizedSetup = ($carousel) => {
const analizedSlides = [];
return ($slides) => ($slide) => {
analizedSlides.push($slide);
return $slides.length === analizedSlides.length
&& $carousel.addClass('is-visible');
};
};

export default function () {
const $carousel = $('[data-slick]');
if ($carousel.length) {
const multipleSlides = $carousel[0].childElementCount > 1;
$carousel.slick({ dots: multipleSlides });
}

if ($carousel.length === 0) return;

$carousel.slick({ dots: $carousel[0].childElementCount > 1 });

const $slidesNodes = $('.heroCarousel-slide');

const showCarouselIfSlidesAnalized = showCarouselIfSlidesAnalizedSetup($carousel)($slidesNodes);

$slidesNodes.each((index, element) => {
const $element = $(element);
const isContentBlock = !!$element.find('.heroCarousel-content').length;

if (isContentBlock) {
showCarouselIfSlidesAnalized($element);
return true;
}

const $image = $element.find('.heroCarousel-image-wrapper img');
$('<img/>')
.attr('src', $($image).attr('src'))
.load(function getImageSizes() {
const imageRealWidth = this.width;
const imageRealHeight = this.height;

const imageAspectRatio = imageRealHeight / imageRealWidth;

$element.addClass(() => {
switch (true) {
case imageAspectRatio > 0.8 && imageAspectRatio <= 1.2:
return 'is-square-image-type';
case imageAspectRatio > 1.2:
return 'is-vertical-image-type';
default:
return '';
}
});

showCarouselIfSlidesAnalized($element);
});
});

// Alternative image styling for IE, which doesn't support objectfit
if (typeof document.documentElement.style.objectFit === 'undefined') {
$('.heroCarousel-slide').each((index, element) => {
const $container = $(element);
const imgUrl = $container.find('img').data('lazy');

if (imgUrl) {
$container.css('backgroundImage', `url(${imgUrl})`).addClass('compat-object-fit');
}
if (document.documentElement.style.objectFit === undefined) {
$slidesNodes.each((index, element) => {
$(element).addClass('compat-object-fit');
golcinho marked this conversation as resolved.
Show resolved Hide resolved
});
}
}
103 changes: 79 additions & 24 deletions assets/scss/components/stencil/heroCarousel/_heroCarousel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
// object-fit and instead copy the image src to a the background-image of the
// wrapper div and add the compat-object-fit class.
//
// 2. Visually overrides the top margin for '.body' defined in _body.scss.
// The '.body' top margin creates space between the header and page content.
// However, on the homepage, we want the carousel to be flush with the header.
//
// 3. Allows image to scale on large screens while preventing the top and bottom
// from becoming cut off.
// -----------------------------------------------------------------------------
Expand All @@ -22,14 +18,28 @@
min-width: 100%;
margin-bottom: (spacing("double") + spacing("single"));
margin-top: -(spacing("single")); // 3
overflow: hidden;
visibility: hidden;

&.is-visible {
visibility: visible;
}

@include breakpoint("medium") {
margin-top: -(spacing("single") + spacing("base")); // 3
}

&.slick-initialized { // 2
max-height: remCalc(1000);
&.slick-initialized {
opacity: 1;
max-height: 100vh;

@include breakpoint("small") {
max-height: remCalc(400px);
}

@include breakpoint("medium") {
max-height: remCalc(600px);
}
}

&:not(.slick-initialized) :not(.heroCarousel-slide--first).heroCarousel-slide {
Expand All @@ -43,6 +53,8 @@
.slick-next,
.slick-prev {
top: 50%;
transform: translateY(-50%);
margin: 0;
}

.slick-next {
Expand Down Expand Up @@ -82,32 +94,73 @@
}

.heroCarousel-image {
@include breakpoint("medium") {
object-fit: cover; // 1
max-height: remCalc(600px);
width: 100%;
object-fit: contain;
width: 100%;
height: 100%;
object-position: 50% 0%;

@include breakpoint("small") {
object-position: 50% 50%;
}
}

&.stretch {
.heroCarousel-image {
object-fit: cover;
object-position: 50% 50%;
}

&.compat-object-fit { // 1
.heroCarousel-image {
width: 100%;
height: 100%;
}
}
}

&.compat-object-fit { // 1
overflow: hidden;

.heroCarousel-image {
width: auto;
}
}

.heroCarousel-image-wrapper {
height: remCalc(250px);
display: flex;
justify-content: center;
align-items: flex-start;
height: 56.25vw;

@include breakpoint("small") {
max-height: remCalc(400px);
}

@include breakpoint("medium") {
max-height: remCalc(600px);
}
}

&.compat-object-fit { // 1
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;

&.stretch {
@include breakpoint("large") { // 4
background-size: 100% 100%;
}
&.is-square-image-type {

.heroCarousel-image-wrapper {
height: 100vw;

@include breakpoint("small") {
height: 56.25vw;
}
}
}

.heroCarousel-image {
opacity: 0;
&.is-vertical-image-type {

.heroCarousel-image-wrapper {
height: 110vw;

@include breakpoint("small") {
height: 56.25vw;
}
}
}
}
Expand All @@ -117,17 +170,19 @@
padding: spacing("half") spacing("single") (spacing("double"));
text-align: center;

@include breakpoint("medium") {
@include breakpoint("small") {
@include carouselOpaqueBackgrounds;
width: remCalc(700px);
padding: spacing("single") * 1.5;
width: 70%;
background-color: rgba($carousel-bgColor, 0.9);
left: 0;
padding: spacing("single");
margin: 0 auto;
padding: spacing("single") * 1.5;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: remCalc(700px);

&.heroCarousel-content--empty {
background-color: transparent;
Expand Down
4 changes: 2 additions & 2 deletions templates/components/carousel.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"slidesToScroll": 1,
"autoplay": true,
"autoplaySpeed": {{carousel.swap_frequency}},
"lazyLoad": "anticipated"
"lazyLoad": "anticipated",
}'>
{{#each carousel.slides}}
<a href="{{url}}">
<div class="heroCarousel-slide {{#if ../theme_settings.homepage_stretch_carousel_images}}stretch{{/if}} {{#if @first}}heroCarousel-slide--first{{/if}}">
<div class="heroCarousel-image-wrapper" {{#and image_height image_width}}style="height: {{multiply (divide image_height image_width) 100}}vw"{{/and}}>
<div class="heroCarousel-image-wrapper">
{{#if @first}}
{{> components/common/responsive-img
image=stencil_image
Expand Down