switchon@lavalamp.biz
+27(0) 83 419 4851 / +27(0) 21 036 1165
Application & software development
Get A Quote

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact
    asp.net
    ASP.NET
    Jan 17, 2023
    postman mock api
    Postman Mock API
    Jan 30, 2023

    How To Create An Interactive Postcard With Laravel Vue

    Categories
    • Web Design
    • Web Development
    Tags
    • css
    • css tricks
    • Front-End Development
    • laravel
    • vue
    • Web Design
    interactive postcard
    interactive postcard

    When creating a home page for a web application, it is always important to make it stand out, especially if the project in question is a portfolio website.

    There are various ways on how a developer can make a website unique and aesthetically pleasing. It would involve various elements such as colour palette, website layout, specific font usage, and the implementation and positioning of UX elements.

    In this blog, I will be taking you through the steps on how to implement an interactive postcard menu for a Laravel 8 Vue project.


    Table of Contents


    • Implementing the Postcard
    • Adding Animation and Links for Postcard
    • Additional Styling


    Implementing the Postcard


    As the title header suggests, this section will cover on how we will be implementing the postcard. It is very important to note that this project’s code is fully inspired by Andrew Canham’s Spread cards project, which you can visit if you are interested on how the original code has been implemented.

    The first we will need is to create a Vue component for our project, which in this case will be called PostcardComponent.vue. After the file has been created, we will need to add the file to the app.js file, which is located in the js folder within resources.

    When the necessary code from has been added, we will need to add the component’s name to the home page:

    home.blade.php
        @extends('layouts.app')
    
        @section('content')
          <postcard-component
            forgotten-city-url="{{ route('vp-portfolio.the-forgotten-city') }}"
            eastshade-url="{{ route('vp-portfolio.eastshade') }}"
            sable-url="{{ route('vp-portfolio.sable') }}"
            uncharted-url="{{ route('vp-portfolio.uncharted') }}"
          ></postcard-component>
        @endsection
    

    Now that the component has been added to the home page, we can start the implement our card container and cards. By adding the following code, we are adding two containers, the main container and the card container. The main container will consist of the card container and the perspective div element, while the card container will only consist of the cards that we will interact with.

    PostcardComponent.vue
    <template>
        <div class="container">
            <div class="perspective">
                <div class='card-container ' >
                    <div class="message">
                        INTERACTIVE POSTCARD
                    </div>
                    <div class='card card-card1'>
                        <div class='card__face card__face--top '>
                            
                        </div>
                    </div>
                    <div class='card card-card2'>
                        <div class='card__face card__face--top'>
                            
                        </div>
                    </div>
                    <div class='card card-card3'>
                        <div class='card__face card__face--top'>
                            
                        </div>
                    </div>
                    <div class='card card-card4'>
                        <div class='card__face card__face--top'>
    
                        </div>
    
                    </div>
                </div>
            </div>
        </div>
    </template>
    

    After the template code has been implemented, we will need to implement the styling for the cards in order for it to properly display. As you will see in the code below, we will be positioning the cards in a manner that they will be on top of one another when accessing the page. In the next section, we will go over how we reveal them.

    app.scss
    // Bootstrap
    @import "~bootstrap/scss/bootstrap";
    
    // Variables
    @import "base/typography";
    
    @import "component/btn";
    @import "component/card-menu";
    @import "component/form";
    @import "component/header";
    @import "component/modal";
    @import "component/postcard";
    @import "component/link";
    
    @import "layout/nav-bar";
    @import "layout/footer";
    
    @import "component/datatable";
    
    #app {
        overflow: visible;
      }
    
    html,body
    {
      width: 100%;
      height: 100%;
      margin: 0px;
      padding: 0px;
      overflow-x: hidden;
    }
    
    .fa {
      display: initial;
    }
    
    .auth-pages{
      background-color: #FFFFFF;
    }
    
    input:focus, textarea:focus, select:focus{
      outline: none;
    }
    
    textarea:focus{
      height: 99px!important;
      max-height: 150px!important;
    }
    
    body {
      background: #e7e7e7;
      font-family: 'Source Sans Pro', sans-serif;
      font-weight: 200;
      font-size: 1.4rem;
      height: 100vh;
      overflow: hidden;
      width: 100vw;
    }
    
    _postcard.scss
    @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,700,900');
    
    .message {
        color: #e7e7e7;
        text-shadow: 0 0 3px #b4b4b4;
        font-size: 70px;
        font-weight: 200;
        letter-spacing: -0.01em;
        line-height: 60px;
        position: absolute;
        transform: rotate(-31deg) translate3d(-64%, 532%, 0);
        width: 7em;
    }
    
    .card {
      background: #eeeae7;
      border-radius: 16px;
      box-shadow: 0 1px 2px 0 rgba(151,150,146,0.4);
      height: 43vw;
      max-height: 60vw;
      max-width: 80vw;
      min-height: 25vw;
      min-width: 16vw;
      position: absolute;
      transition: all ease-in 0.3s;
      width: 50vw;
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    
    .card-card1 {
      box-shadow:
        0 1px 2px 0 rgba(151,150,146,0.4),
        0 4px 12px 0 rgba(151,150,146,0.4)
        ;
      color: #635f5c;
      .card__value {
        transform: translatex(-2px);
      }
    }
    .card-card2 {
      color: #a68385;
      .card__value {
        transform: translatex(-2px);
      }
      .card__suit {
        margin-top: 0.8rem;
      }
    }
    
    .card-card3 {
      color: #635f5c;
      .card__value {
        transform: translatex(-2px);
      }
      .card__suit {
        margin-top: 0.8rem;
      }
    }
    .card-card4 {
      color: #a68385;
      .card__value {
        transform: translatex(-2px);
      }
      .card__suit {
        margin-top: 0.7rem;
      }
    }
    
    .card__face {
      padding: 1.8rem 1.6rem;
      position: absolute;
    }
    .card__face--btm {
      bottom: 0;
      right: 0;
      transform: rotate(180deg);
    }
    .card__value {
      display: block;
      text-align: left !important;
      width: 18vw !important;
      height: 5vw!important;
      font-size: 30px;
      font-weight: bold;
    }
    .card__suit {
      display: block;
      margin-top: 0.5rem;
    }
    
    div.perspective {
      height: 100vh;
      perspective: 2000px;
      position: absolute;
      width: 100vw;
    }
    .card-container {
      cursor: pointer;
      left: 31%;
      position: absolute;
      top: 15%;
      transform: rotateX(50deg) translate3d(-50%, -50%, 0);
      height: 45vw;
      width: 32vw;
      max-height: 450px;
      max-width: 320px;
    }
    
    // Positioning of the Cards
    .card-card1 {
      transform: rotate(-31deg) translate3d(-50%, -10%, 0);
    }
    .card-card2 {
      transform: rotate(-31deg) translate3d(-49.5%, -10.5%, 0);
    }
    .card-card3 {
      transform: rotate(-31deg) translate3d(-49%, -11%, 0);
    }
    .card-card4 {
      transform: rotate(-31deg) translate3d(-48.5%, -11.5%, 0);
    }
    


    Adding Animation and Links for Postcard


    Now that we have our cards setup, we will now need to implement code that will allow for the cards to change position when the user interacts with them. In the following example, we will be implementing the .card-container.spread class, which will be used to smoothly change the cards’ default position.

    _postcard.scss
    ...
    // Repositions the cards when clicking them
    .card-container.spread {
      .card-card1 {
        transform: rotate(-31deg) translate3d(-50%, -10%, 0);
        box-shadow:
          0 1px 2px 0 rgba(151,150,146,0.4),
          0 4px 12px 0 rgba(151,150,146,0.4)
          ;
      }
      .card-card2 {
        transform: rotate(-4.5deg) translatex(-22%);
        box-shadow:
          0 1px 2px 0 rgba(151,150,146,0.4),
          0 2px 6px 0 rgba(151,150,146,0.4)
          ;
      }
      .card-card3 {
        transform: rotate(5.8deg) translatex(10%);
        box-shadow:
          0 1px 2px 0 rgba(151,150,146,0.4),
          0 2px 4px 0 rgba(151,150,146,0.4)
          ;
      }
      .card-card4 {
        transform: rotate(22.5deg) translate3d(40%, -5%, 0);
        box-shadow:
          0 1px 2px 0 rgba(151,150,146,0.4),
          0 2px 4px 0 rgba(151,150,146,0.4)
          ;
      }
    }
    

    Now that have implemented the necessary class for the animation, we will now need to implement a toggle class function on the Vue component. First, we will need to add v-bind:class="[isSpread ? 'spread' : '']" to the card container and then add @click="toggleClass()" afterwards.

    By adding these two snippets of code, we added a way for the spread class to be added to the card container when the user clicks on the card. We will then proceed to add the toggleClass method the PostcardComponent’s script and have a isSpread prop to determine if the value is true or false. The code should look like the following:

    PostcardComponent.vue
    <template>
        <div class="container">
            <div class="perspective">
                <div class='card-container ' v-bind:class="[isSpread ? 'spread' : '']" @click="toggleClass()">
                    <div class="message">
                        INTERACTIVE POSTCARD
                    </div>
                    <div class='card card-card1'>
                        <div class='card__face card__face--top '>
                            
                        </div>
                    </div>
                    <div class='card card-card2'>
                        <div class='card__face card__face--top'>
                            
                        </div>
                    </div>
                    <div class='card card-card3'>
                        <div class='card__face card__face--top'>
                            
                        </div>
                    </div>
                    <div class='card card-card4'>
                        <div class='card__face card__face--top'>
    
                        </div>
    
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            props: {
                isSpread: {
                    type: Boolean,
                    default: false
                },
    
                forgottenCityUrl: String,
                eastshadeUrl: String,
                sableUrl: String,
                unchartedUrl: String,
            },
    
            data: function () {
                return {
                    mutableList: JSON.parse(this.isSpread)
                }
            },
    
    
            methods: {
                toggleClass: function(event){
                   this.isSpread = !this.isSpread;
                },
            }
        }
    </script>
    
    

    After implementing the code, you will see that the cards are being spread out. You can of course change the positioning and animation of the cards to whatever your heart desires, but for the sake of simplicity, we will be using the current positioning code.

    The next step would be the implementation of the page links. For projects such as portfolio websites, it is always best to capture the user’s eye. When a user interacts with the cards, they will need to be able to see the link immediately. So for that to happen, we will need to add the links like the following:

    PostcardComponent.vue
    <template>
        <div class="container">
            <div class="perspective">
                <div class='card-container ' v-bind:class="[isSpread ? 'spread' : '']" @click="toggleClass()">
                    <div class="message">
                        INTERACTIVE POSTCARD
                    </div>
                    <div class='card card-card1'>
                        <div class='card__face card__face--top '>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="unchartedUrl" @click="portfolioLinkClick()">Uncharted</a>
                                </span>
                        </div>
                    </div>
                    <div class='card card-card2'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="sableUrl" @click="portfolioLinkClick()">Sable</a>
                                </span>
                        </div>
                    </div>
                    <div class='card card-card3'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="eastshadeUrl" @click="portfolioLinkClick()">Eastshade</a>
                                </span>
                        </div>
                    </div>
                    <div class='card card-card4'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="forgottenCityUrl" @click="portfolioLinkClick()">The Forgotten City</a>
                                </span>
                        </div>
    
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            props: {
                isSpread: {
                    type: Boolean,
                    default: false
                },
                isLinkClicked: {
                    type: Boolean,
                    default: false
                },
    
                forgottenCityUrl: String,
                eastshadeUrl: String,
                sableUrl: String,
                unchartedUrl: String,
            },
    
            data: function () {
                return {
                    mutableList: JSON.parse(this.isSpread)
                }
            },
    
    
            methods: {
                toggleClass: function(event){
                    if(this.isLinkClicked === false) {
                        this.isSpread = !this.isSpread;
                    }
                },
    
                portfolioLinkClick: function(event){
                    this.isLinkClicked = !this.isLinkClicked;
                }
            }
        }
    </script>
    
    
    _link.scss
    /* CSS based from css-tricks.com article: https://css-tricks.com/css-link-hover-effects/ */
    
    a {
        background-image: linear-gradient(
          to right,
          #54b3d6,
          #54b3d6 50%,
          rgb(255, 255, 255) 50%
        );
        background-size: 200% 100%;
        background-position: -100%;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        transition: all 0.3s ease-in-out;
      }
    

    As you can see above, the url for each screen needs to be added to the component. You will also notice that a new method function has been added as well as an additional if statement for the toggleClass function.

    The reason for these new additions is to prevent the postcard from closing when the user clicks on the link. Therefore, the if statement ensures that the cards do not change position when someone has interacted with the link.

    And finally, the last step for the postcard to be completed is the adding of the desired image. To ensure that the image is consistent with a typical postcard design, we will need to add a div below the link, which will consist of the image.

    PostcardComponent.vue
    <template>
        <div class="container">
            <div class="perspective">
                <div class='card-container ' v-bind:class="[isSpread ? 'spread' : '']" @click="toggleClass()">
                    <div class="message">
                        INTERACTIVE POSTCARD
                    </div>
                    <div class='card card-card1'>
                        <div class='card__face card__face--top '>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="unchartedUrl" @click="portfolioLinkClick()">Uncharted</a>
                                </span>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Uncharted VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card2'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="sableUrl" @click="portfolioLinkClick()">Sable</a>
                                </span>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Sable VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card3'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="eastshadeUrl" @click="portfolioLinkClick()">Eastshade</a>
                                </span>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Eastshade VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card4'>
                        <div class='card__face card__face--top'>
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="forgottenCityUrl" @click="portfolioLinkClick()">The Forgotten City</a>
                                </span>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/The Forgotten City VP by Henlo Neethling.jpg'">
                        </div>
    
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            props: {
                isSpread: {
                    type: Boolean,
                    default: false
                },
                isLinkClicked: {
                    type: Boolean,
                    default: false
                },
    
                forgottenCityUrl: String,
                eastshadeUrl: String,
                sableUrl: String,
                unchartedUrl: String,
            },
    
            data: function () {
                return {
                    mutableList: JSON.parse(this.isSpread)
                }
            },
    
    
            methods: {
                toggleClass: function(event){
                    if(this.isLinkClicked === false) {
                        this.isSpread = !this.isSpread;
                    }
                },
    
                portfolioLinkClick: function(event){
                    this.isLinkClicked = !this.isLinkClicked;
                }
            }
        }
    </script>
    
    
    _postcard.scss
    ...
    .card-image{
        overflow: hidden;
        border-radius: 2%;
        border: 5px solid #eeeae7;
    }
    
    .card-image img{
        width: 153%;
    }
    

    As you can see above, additional css code needed to be implemented to ensure that image overflow is hidden and that there would be a border surrounding the image, which makes it easier for the image to be added to the cards without having to worry about adding borders for the image.

    Interactable Postcard_Basic by Henlo Neethling


    Additional Styling


    If you want to add a bit more flair to the card interaction, you can of course add additional code that changes the display of the link.

    You can make the text bigger, change its colour or maybe add a hover effect to the link. Let’s take a look on what we can add further to the postcard.

    As mentioned earlier, you will need to catch the user’s attention when working on this postcard interface. Naturally, that would mean we will need to add another animation to the postcard, which will be used to display the link when the user interacts with postcard. What we need to do is add the following code:

    PostcardComponent.vue
    <template>
        <div class="container">
            <div class="perspective">
                <div class='card-container ' v-bind:class="[isSpread ? 'spread' : '']" @click="toggleClass()">
                    <div class="message">
                        INTERACTIVE POSTCARD
                    </div>
                    <div class='card card-card1'>
                        <div class='card__face card__face--top '>
                            <Transition name="card-title">
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="unchartedUrl" @click="portfolioLinkClick()">Uncharted</a>
                                </span>
                            </Transition>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Uncharted VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card2'>
                        <div class='card__face card__face--top'>
                             <Transition name="card-title">
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="sableUrl" @click="portfolioLinkClick()">Sable</a>
                                </span>
                             </Transition>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Sable VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card3'>
                        <div class='card__face card__face--top'>
                             <Transition name="card-title">
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="eastshadeUrl" @click="portfolioLinkClick()">Eastshade</a>
                                </span>
                             </Transition>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/Eastshade VP by Henlo Neethling.jpg'">
                        </div>
                    </div>
                    <div class='card card-card4'>
                        <div class='card__face card__face--top'>
                              <Transition name="card-title">
                                <span class='card__value' v-if="isSpread" >
                                    <a :href="forgottenCityUrl" @click="portfolioLinkClick()">The Forgotten City</a>
                                </span>
                              </Transition>
                        </div>
                        <div class="card-image">
                            <img class="img-responsive" v-bind:src="'../images/The Forgotten City VP by Henlo Neethling.jpg'">
                        </div>
    
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            props: {
                isSpread: {
                    type: Boolean,
                    default: false
                },
                isLinkClicked: {
                    type: Boolean,
                    default: false
                },
    
                forgottenCityUrl: String,
                eastshadeUrl: String,
                sableUrl: String,
                unchartedUrl: String,
            },
    
            data: function () {
                return {
                    mutableList: JSON.parse(this.isSpread)
                }
            },
    
    
            methods: {
                toggleClass: function(event){
                    if(this.isLinkClicked === false) {
                        this.isSpread = !this.isSpread;
                    }
                },
    
                portfolioLinkClick: function(event){
                    this.isLinkClicked = !this.isLinkClicked;
                }
            }
        }
    </script>
    
    
    _postcard.scss
    ...
    /* Animations for Card Title transition tag */
    
    .card-title-enter-active {
        animation: card-title-in 0.9s;
      }
      .card-title-leave-active {
        animation: card-title-in 0.9s reverse;
      }
      @keyframes card-title-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.10);
        }
        100% {
          transform: scale(1);
        }
      }
    

    Since we have now added the v-if for the link’s div, the link will then be hidden until the user clicks on the postcards. When the user has clicked the top card, the link will scale in and out, giving it a bit of a bounce effect when being revealed. This animation will also do the same when the user has clicked on the postcard again, which will close the postcards and hide the links. This has been made possible thanks to the Transition component. By giving the component a name, we are able to apply the animation with transition classes such as enter-active and leave-active.

    Now that we have added an animation to the link, it would also be helpful to give the user an indication that the link is something they can interact with. For this example, we will be using a hover effect, which will change the link colour to a gradient light blue and give an underscore:

    _link.scss
    ...
    
      a:before {
        content: '';
        background: #54b3d6;
        display: block;
        position: absolute;
        bottom: -3px;
        left: 0;
        width: 0;
        height: 3px;
      }
    
      a:hover {
        background-position: 0;
      }
    
       a:hover::before {
        width: 100%;
       }
    

    And presto, you now have a postcard interface that can serve as a unique menu button.

    Interactable Postcard_Additional CSS by Henlo Neethling

    Of course, you can change the interaction, perspective, design, links and functionality of the cards however you see fit. It all depends on what project you would like to apply it for.

    I wish nothing but the best for your coding projects and hope that this blog has been very helpful.

    Contact us


      Related posts:

      dynamic doughnut graph using laravel vue componentDynamic Doughnut Graph Using Laravel Vue Component string valueMany Ways To Skin A Cat – If A Cat Was A String Value laravel livewireLaravel Livewire development teamThe Weird And Beautiful JavaScript Language
      Share
      63
      Henlo Neethling
      Henlo Neethling
      Henlo is a junior developer, learning to become a jack of all trades for front-end development, UI/UX design and backend development. Has an interest in learning techniques to make the development process go smoother.

      Leave a Reply Cancel reply

      Your email address will not be published. Required fields are marked *

      Lava Lamp Lab


      Like technology, a lava lamp constantly changes form, producing new conditions with every passing moment



      lava lamp lab facebook   lava lamp lab twitter   lava lamp lab linkedin   lava lamp lab instgram

      Services


      Application & software development

      Outsourced software development

      Project based resourcing

      Digital marketing & consulting

      Graphic design & consulting

      UI / UX design & consulting

      Contact Us


      +27(0) 83 419 4851

      +27(0) 21 036 1165


      switchon@lavalamp.biz


      Unit 4 Monaco Square,
      14 Church Street,
      Durbanville,
      Cape Town, 7550

      NBConsult Group


      nbconsult
      nbconnect msp
      nbclearning
      river broadband
      designer needed
      © 2023 Lava Lamp Lab (Pty) Ltd | All Rights Reserved | Privacy Policy
      Contact us now

        Application & software development

          Outsourced software development

            Project based resourcing

              Digital marketing & consulting

                Graphic design & consulting

                  UI/UX design & consulting

                    Lease an expert

                      Recruitment services

                        We are using cookies to give you the best experience on our website.

                        You can find out more about which cookies we are using or switch them off in settings.

                        Lava Lamp Lab
                        Powered by  GDPR Cookie Compliance
                        Privacy Overview

                        This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

                        Strictly Necessary Cookies

                        Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.

                        If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.

                        3rd Party Cookies

                        This website uses Google Analytics to collect anonymous information such as the number of visitors to the site, and the most popular pages.

                        Keeping this cookie enabled helps us to improve our website.

                        Please enable Strictly Necessary Cookies first so that we can save your preferences!

                        Cookie Policy

                        More information about our Cookie Policy