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
48 changes: 36 additions & 12 deletions assets/js/theme/common/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,44 @@ import 'slick-carousel';

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;

const multipleSlides = $carousel[0].childElementCount > 1;
$carousel.slick({ dots: multipleSlides });
golcinho marked this conversation as resolved.
Show resolved Hide resolved

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

$slidesNodes.each((index, element) => {
golcinho marked this conversation as resolved.
Show resolved Hide resolved
const $element = $(element);
const isContentBlock = !!$element.find('.heroCarousel-content').length;

if (isContentBlock) return true;

const $image = $element.find('.heroCarousel-image-wrapper img');
$('<img/>') // Make in memory copy of image to avoid css issues
.attr('src', $($image).attr('src'))
.load(function getImageSizes() {
const imageRealWidth = this.width; // Note: $(this).width() will not
const imageRealHeight = this.height; // work for in memory images.

const imageAspectRatio = imageRealHeight / imageRealWidth;

const isImageSquare = imageAspectRatio > 0.8 && imageAspectRatio <= 1.2;
const isImageVertical = imageAspectRatio > 1.2;

const slideClass = isImageSquare && 'is-square-image-type'
|| isImageVertical && 'is-vertical-image-type'
|| '';

$element.addClass(slideClass);
});
golcinho marked this conversation as resolved.
Show resolved Hide resolved
});

// 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
});
}
}
106 changes: 81 additions & 25 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,24 @@
min-width: 100%;
margin-bottom: (spacing("double") + spacing("single"));
margin-top: -(spacing("single")); // 3
overflow: hidden;

@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 +49,8 @@
.slick-next,
.slick-prev {
top: 50%;
transform: translateY(-50%);
margin: 0;
}

.slick-next {
Expand Down Expand Up @@ -79,35 +87,79 @@
position: relative;
a {
text-decoration: none;
}
}
golcinho marked this conversation as resolved.
Show resolved Hide resolved

.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 {

golcinho marked this conversation as resolved.
Show resolved Hide resolved
.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 {

golcinho marked this conversation as resolved.
Show resolved Hide resolved
height: remCalc(250px);
display: flex;
justify-content: center;
align-items: flex-start;

height: 56.25vw;
golcinho marked this conversation as resolved.
Show resolved Hide resolved

@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 +169,21 @@
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%;
golcinho marked this conversation as resolved.
Show resolved Hide resolved
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