Skip to content

Commit

Permalink
Merge pull request #104 from belsman/feat/add-animation-to-layer
Browse files Browse the repository at this point in the history
feat: add entry and exit animation on the layer module
  • Loading branch information
vanthome committed Oct 24, 2023
2 parents d580e63 + f693117 commit f095d40
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 12 deletions.
13 changes: 13 additions & 0 deletions packages/vcl/layer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ A simple layer with a panel as its content.

[basic example](/demo/example.html)

Utilise the `fade-out-animation` with the `layer-cover` and `layer` to create a smooth entry and exit animation (_Available on Chrome 117_)

[Dynamic modal with entry and exit transition](/demo/example-with-transitions.html)

Utilise the `zoom-animation` to create *zoom in* and *zoom out* effect when the modals opens and exit (_Available on chrome 117_)

[Dynamic modal with Zoom in and zoom out animation](/demo/example-with-zoom-animation.html)

## Classes

- `layer-cover`
Expand All @@ -39,8 +47,13 @@ A simple layer with a panel as its content.
- `layer-fill`: Makes the layer cover the whole viewport.
- `layer-stick-to-bottom`: Makes the layer stick to the bottom.
- `layer-gutter-padding`: Add a padding of half the gutter width.
- `fade-out-animation`: Creates a smooth fade in and out transition when the layer enter and exit the window.
- `zoom-animation`: Show a zoom in and zoom out animation effect when the layer enter and exit the window.

## Variables

- `$layer-cover-bg-color`
- `$layer-border-color`
- `$layer-cover-transition-duration`
- `$layer-transition-duration`
- `$layer-box-animation-durations`
28 changes: 17 additions & 11 deletions packages/vcl/layer/demo.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
@use "../button.scss" as *;
@use "../flex-grid.scss";
@use "../icogram.scss" as *;
@use "../icon.scss" as *;
@use "../loose-button-group.scss";
@use "../panel.scss" as *;
@use "../size-modulation.scss";
@use "../typography.scss" as *;
@use "../utils.scss" as *;
@use "../theme.scss" as *;
@use "./index.scss";
@use '../button.scss' as *;
@use '../flex-grid.scss';
@use '../icogram.scss' as *;
@use '../icon.scss' as *;
@use '../loose-button-group.scss';
@use '../panel.scss' as *;
@use '../size-modulation.scss';
@use '../typography.scss' as *;
@use '../utils.scss' as *;
@use '../theme.scss' as *;
@use './index.scss';

.example-layer-width-animation {
width: 100%;
height: 400px;
background-color: #f9f9ff;
}
103 changes: 103 additions & 0 deletions packages/vcl/layer/demo/example-with-transitions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<div class="example-layer-width-animation">
<button id="showDialog" type="button" class="button emphasized">
<div class="icogram"><span class="text">Show Dialog</span></div>
</button>
</div>

<script>
const CLOSE_MODAL_DURATION = 500;

const docRoot = document.demoShadowRoot || document;

const showDialog = docRoot.querySelector('#showDialog');

let myTimeout;

const layerHTML = `
<div class="layer" role="dialog">
<div class="layer-box">
<div class="panel panel-dialog danger m-0" role="dialog">
<div class="panel-body">
<div class="panel-content">
<div class="icogram">
<div
class="icon far fa-question-circle scale300p"
aria-hidden="true"
aria-label="account"
role="img"
></div>
<div class="text">Do you really want to delete XY?</div>
</div>
</div>
</div>
<div class="panel-footer no-bg row justify-between center">
<div class="loose-button-group">
<button
type="button"
class="button transparent outline cancel"
id="cancel"
>
<div class="icogram">
<span class="text">Cancel</span>
</div>
</button>
<button type="button" class="button danger delete" id="delete">
<div class="icogram">
<span class="text">Delete</span>
</div>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="layer-cover"></div>
`;

showDialog.addEventListener('click', () => {
if (myTimeout) {
clearTimeout(myTimeout);
}

showDialog.parentElement.insertAdjacentHTML('beforeend', layerHTML);

const layerCover = docRoot.querySelector('.layer-cover');
const layer = docRoot.querySelector('.layer');

const cancelBtn = docRoot.querySelector('#cancel');
const deleteBtn = docRoot.querySelector('#delete');

// Listeners
deleteBtn.addEventListener('click', () => {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(function () {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
});

cancelBtn.addEventListener('click', () => {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(() => {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
});

docRoot.onclick = (event) => {
if (event.target === layerCover || event.target === layer) {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(() => {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
}
};
});
</script>
103 changes: 103 additions & 0 deletions packages/vcl/layer/demo/example-with-zoom-animation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<div class="example-layer-width-animation">
<button id="showDialog" type="button" class="button emphasized">
<div class="icogram"><span class="text">Show Dialog</span></div>
</button>
</div>

<script>
const CLOSE_MODAL_DURATION = 500;

const docRoot = document.demoShadowRoot || document;

const showDialog = docRoot.querySelector('#showDialog');

let myTimeout;

const layerHTML = `
<div class="layer" role="dialog">
<div class="layer-box zoom">
<div class="panel panel-dialog danger m-0" role="dialog">
<div class="panel-body">
<div class="panel-content">
<div class="icogram">
<div
class="icon far fa-question-circle scale300p"
aria-hidden="true"
aria-label="account"
role="img"
></div>
<div class="text">Do you really want to delete XY?</div>
</div>
</div>
</div>
<div class="panel-footer no-bg row justify-between center">
<div class="loose-button-group">
<button
type="button"
class="button transparent outline cancel"
id="cancel"
>
<div class="icogram">
<span class="text">Cancel</span>
</div>
</button>
<button type="button" class="button danger delete" id="delete">
<div class="icogram">
<span class="text">Delete</span>
</div>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="layer-cover"></div>
`;

showDialog.addEventListener('click', () => {
if (myTimeout) {
clearTimeout(myTimeout);
}

showDialog.parentElement.insertAdjacentHTML('beforeend', layerHTML);

const layerCover = docRoot.querySelector('.layer-cover');
const layer = docRoot.querySelector('.layer');

const cancelBtn = docRoot.querySelector('#cancel');
const deleteBtn = docRoot.querySelector('#delete');

// Listeners
deleteBtn.addEventListener('click', () => {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(function () {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
});

cancelBtn.addEventListener('click', () => {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(() => {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
});

docRoot.onclick = (event) => {
if (event.target === layerCover || event.target === layer) {
layerCover.classList.add('fade-out-animation');
layer.classList.add('fade-out-animation');

myTimeout = setTimeout(() => {
layer.remove();
layerCover.remove();
}, CLOSE_MODAL_DURATION);
}
};
});
</script>
61 changes: 60 additions & 1 deletion packages/vcl/layer/index.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
@use "../theme.scss" as *;
@use '../theme.scss' as *;

/* ==== Entry animation ==== */
@starting-style {
.layer-cover,
.layer {
opacity: 0;
}
}

.layer-cover {
position: fixed;
Expand All @@ -8,6 +16,11 @@
right: 0;
bottom: 0;
background-color: $layer-cover-bg-color;

/* Add exiting animation */
transition: opacity $layer-cover-transition-duration,
display $layer-cover-transition-duration;
transition-behavior: allow-discrete;
}

.layer {
Expand All @@ -21,6 +34,10 @@
outline: none;
align-items: center;
justify-content: center;
/* Add exiting animation */
transition: opacity $layer-transition-duration,
display $layer-transition-duration;
transition-behavior: allow-discrete;

&.layer-stick-to-bottom {
& .layer-box {
Expand All @@ -33,6 +50,13 @@
}
}

/* Feature: The fade out animation for smooth transition*/
.layer-cover.fade-out-animation,
.layer.fade-out-animation {
opacity: 0;
display: none;
}

.layer-box {
max-height: 100vh;
max-width: 100vw;
Expand All @@ -49,3 +73,38 @@
padding: $layer-gutter-padding;
}
}

.zoom {
animation-name: animatetop;
animation-duration: $layer-box-animation-durations;
}

.fade-out-animation .zoom {
animation-name: animatedown;
animation-duration: $layer-box-animation-durations;
animation-fill-mode: forwards;
}

// Zoom in type animation
@keyframes animatetop {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}

// Zoom out and fade type animation
@keyframes animatedown {
0% {
opacity: 1;
transform: scale(1);
}
50% {
transform: scale(0.4);
}
100% {
opacity: 0;
}
}
3 changes: 3 additions & 0 deletions packages/vcl/theme/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ $popover-shadow-color: $glass-2 !default;
/* Layer */
$layer-cover-bg-color: $glass-1 !default;
$layer-gutter-padding: $grid-half-gutter-width !default;
$layer-cover-transition-duration: 0.4s !default;
$layer-transition-duration: 0.3s !default;
$layer-box-animation-durations: 0.2s !default;

/* Nag */
$nag-color: $text-primary-color !default;
Expand Down

0 comments on commit f095d40

Please sign in to comment.