how I animated and restart animation by clicking same button in gsap - gsap

I want to add gsap animation on my website, But I want to get the animation by clicking a button and then also restart the using the same button, how could I do it using gsap

Try this
const animation = gsap.to("div", { x: 600, paused: true });
const button = document.querySelector("button");
button.addEventListener("click", () => animation.restart());
div{width: 100px; height: 100px; background: teal; border-radius: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<div></div>
<button>Button</button>

Related

Vue - Moving Backgrounds With Mouse Position

I new to vuejs!. I would like to move the background image when mouse position is moving around, how to do this in vuejs.
const el = document.querySelector("#module");
el.addEventListener("mousemove", (e) => {
el.style.backgroundPositionX = -e.offsetX + "px";
el.style.backgroundPositionY = -e.offsetY + "px";
});
.module {
width: 300px;
height: 300px;
border: 1px solid white;
background-image: url(https://images.unsplash.com/photo-1499162526249-f5b8b9ba9923?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=865bf5c0b77ceb22e88de9fd41c5a671);
background-size: 1000px;
}
<div class="module" id="module">
</div>
Just add #mousemove to your div with link to method that will handle your behaviour. Also you can create reference to this element via ref. Sadly I can not create a block of code on tablet, but you can check out this answer here, that’s exactly what you need.

Flickity Slider Animation and Gsap

The slider I am building have the active slider bigger than the others. I managed to make it work without the animation with flkty.reposition(). However, I am trying now to add the animation where the next slide grows in and the active decrease out. For The animation I am using GSAP.
The issue I am facing is to overwrite the left property with gsap so that it continuous animate. As of now, the left property (controlled by Flickity) does not take into account the final size (controlled by GSAP) of the selected slide.
https://codepen.io/stefanomonteiro/pen/VwzwjLw?editors=0010
As the left property of each slide is controlled by Flickity, we could use margin-left with a minus value as an alternative property to pull the selected slide to the left. I know margin is not a good property to animate but it works in this case without digging too deep into the Flickity core.
Here is the GSAP code:
gsap.to(slides, {
duration: 1,
width: "220px",
height: "336px"
});
gsap.to(selectedSlide, {
duration: 1,
marginLeft: "-248px", // the empty space calculated by newWidth - oldWidth
width: "468px",
height: "630px",
onComplete: () => {
// once all animations have been settled, we reset the margin
gsap.set(selectedSlide, { marginLeft: "" });
// and tell Flickity to update
flkty.resize();
flkty.reposition();
}
});
And the snippets
const animate = () => {
const flkty = Flickity.data(".carousel");
const selectedSlide = flkty.selectedElement;
const slides = flkty.getCellElements();
// remove the selected slides
slides.splice(flkty.selectedIndex, 1);
gsap.to(slides, {
duration: 1,
width: "220px",
height: "336px"
});
gsap.to(selectedSlide, {
duration: 1,
marginLeft: "-248px", // the empty space calculated by newWidth - oldWidth
width: "468px",
height: "630px",
onComplete: () => {
// once all animations have been settled, we reset the margin
gsap.set(selectedSlide, {
marginLeft: ""
});
// and tell Flickity to update
flkty.resize();
flkty.reposition();
}
});
};
new Flickity(".carousel", {
cellAlign: "right",
wrapAround: true,
percentPosition: false,
on: {
ready: () => animate()
}
});
const nextButton = document.querySelector(".flickity-button.next");
nextButton.addEventListener("click", () => animate());
/* external css: flickity.css */
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
.carousel {
background: #EEE;
}
.carousel-cell {
width: 220px;
height: 336px;
margin-right: 20px;
background: #8C8;
border-radius: 5px;
counter-increment: carousel-cell;
}
.carousel-cell.is-selected {
width: 468px;
height: 630px;
z-index: 1;
}
/* cell number */
.carousel-cell:before {
display: block;
text-align: center;
content: counter(carousel-cell);
line-height: 200px;
font-size: 80px;
color: white;
}
<link href="https://npmcdn.com/flickity#2/dist/flickity.css" rel="stylesheet" />
<script src="https://unpkg.co/gsap#3/dist/gsap.min.js"></script>
<script src="https://npmcdn.com/flickity#2/dist/flickity.pkgd.js"></script>
<h1>Flickity - wrapAround</h1>
<!-- Flickity HTML init -->
<div class="carousel">
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
<div class="carousel-cell"></div>
</div>
And the Codepen
You can also notice that we have to wait until the animation is finished until we perform the next click, otherwise, it would mess up the whole process. This is predictable. Hence, I personally will try not to manipulate this Flickity slider for this kind of animation. Just want to give you a solution, anyway.

Fire event on Scrolling Vue.js overflow:auto height:100vh

Hi I have problem firing event when I scroll. I want event to fire when I scroll menu and not whole page. If you look at console, and disable overflow and height in CSS for #app, event will fire. Please check link.
Assign id of inner div element. Let's say longlist here.
<div id="app">
<div id="longlist" class="some-long-list">
<ul>
...
</ul>
</div>
</div>
Add scroll event to the longlist element. Here you should use mounted() instead of created()
new Vue({
el: "#app",
data: {
list: null
},
methods: {
handleScroll (event) {
// Any code to be executed when the window is scrolled
console.log(event)
console.log("metallica")
}
},
mounted () {
this.list = document.getElementById('longlist')
this.list.addEventListener('scroll', this.handleScroll);
},
destroyed () {
this.list.removeEventListener('scroll', this.handleScroll);
}
})
Also, change css to enable scrolling only inside inner div.
#app {
background: #fff;
border-radius: 4px;
/* padding: 20px; */
transition: all 0.2s;
height: 100vh;
/* overflow: auto; */
}
.some-long-list {
background:red;
width: 300px;
margin:0px auto;
overflow: auto;
height: 100%;
}
Hope this could help.
You currently have this in your pen:
...
created () {
window.addEventListener('scroll', this.handleScroll);
},
...
...so your event listener is attached to the whole window. Try selecting the relevant element first with something like document.getElementsByClassName('my-list')[0] or similar to attach the event listener to the element itself.
e.g.
...
created () {
const list = document.getElementsByClassName('my-list')[0]
list.addEventListener('scroll', this.handleScroll);
}
...

How to force ECharts charts to a fixed width when printing?

I'm using some echarts in my Vue application with vue-echarts. All charts have :autoresize="true".
My problem is, that if I try to print the page, the width of the charts are set to match the width of the browser. If browser is full screen then some charts get clipped.
CSS:
.echarts {
width: 100%;
min-height: 200px;
}
#media print {
#page { margin: 1cm }
body {
width: 110mm;
height: 297mm;
margin: 25mm 25mm 25mm 25mm;
}
.echarts {width: 600px !important;} /* This does not work! */
}
In the generated DOM there is a container, and inside that another div with the style: position: relative; width: 567px; height: 400px; padding: 0px; margin: 0px; border-width: 0px; cursor: pointer;
Width of the inner container is updated when browser is resized.
Yes, I have faced the same problem. I have also tried before print and after print and call function to redraw the chart but some times its break when Brower gets a zoom out and zoom in.
I say it's not the best solution but it works perfectly.
Solution -
Overwrite the window.print method in mounted.
window.print = function () {
setTimeout(function () {
_print();
}, 500);
};
use flag print_mode for printing.
let self = this;
window.addEventListener('afterprint', function () {
self.print_mode = false;
});
user ref of the chart instance to get base64 data. call getDataURL() to get image data.
chart = echarts.init(chart_dom);
chart_img = chart.getDataURL()
<img v-if="print_mode" class="print-only" :src="chart_img"></img>
so while printing it display image and print and in normal mode, it shows a chart.

Nuxt.js: add custom loading component

I have been trying to add loading spinner to my NuxtJS project using the loading configuration: https://nuxtjs.org/api/configuration-loading.
However, the documentation is hard to understand, I have no idea how to apply it to my project. Did any have any ideas of how to add loading spinner using that?
Thanks in advance,
So you can create a custom loading:
We can create our custom component in components/loading.vue:
<template lang="html">
<div class="loading-page" v-if="loading">
<p>Loading...</p>
</div>
</template>
<script>
export default {
data: () => ({
loading: false
}),
methods: {
start () {
this.loading = true
},
finish () {
this.loading = false
}
}
}
</script>
<style scoped>
.loading-page {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
text-align: center;
padding-top: 200px;
font-size: 30px;
font-family: sans-serif;
}
</style>
Then, we update our nuxt.config.js to tell Nuxt.js to use our component:
export default {
loading: '~/components/loading.vue'
}
And then in your compenent you can show and hide with the:
this.$nuxt.$loading.start() to start the loading bar and this.$nuxt.$loading.finish() to finish it.
You can put this in the callbacks of a request.
probably it's about z-index value