This is the 10th day of my participation in the First Challenge 2022, for more details: First Challenge 2022

preface

Hello everyone, I do not eat fish d cat, since the New Year. Cut off for a long time, come back, endless learning, as a programmer knowledge is to constantly update iteration. During this period, I contacted Vue for a few days, and it is really good. Today, I will tell you a fun one. In the process of doing the project, click the button, and you will definitely touch the effect of flowers. Let’s talk about the water ripple effect.

Custom instruction

Function of instruction

In a nutshell, it’s the underlying DOM

Of course, vue itself has very powerful command functions that do dom operations on your behalf, such asv-onBinding event right, this should be familiar with the instruction, 100% need to use, after all, JS is an event-driven language. And you can goThe official documentationGo and see

Water ripple

Water ripple effect

As shown in the image above, when the button is clicked, a circle will scatter around the mouse like a wave of water.

implementation

The principle of

We when click the mouse will radiate a circle, whether have the click event is triggered, at this time we will add a span tag, of course, to give him a set width is high, such as properties, and we watch, the color of the circle is not slowly, so there is opacity properties, and span is follow the mouse, so also add positioning properties.

The core

Notice that the circle diverting from span keeps getting larger, so its width and height keep changing. When changing, we can think of timer, which can control the width and height of the circle and make the properties of span change regularly. Of course, there should be critical value, as we can see in the following figure

We can look at the demand, the water ripple must cover the entire button, so the radius of divergence of the SPAN must be the maximum distance in the button, as shown in the figure, and the diagonal must be the longest side, which is clear at a glance. SQRT (a*a+b*b) so the width and height of span is 2 times the longest distance. So when a critical value is found, the timer is cleared so that the span property does not change. And delete span.

Code implementation

Above we analyzed the analysis, next we use code to implement. Structure:

 <div class="app">
        <h1>{{title}}</h1>
        <button v-shuibowen="">Dot me with ripples of water</button><! --<div class="box" v-shuibowen=""></div> -->
    </div>
Copy the code

Instantiate a VUE object.

 const vm = new Vue({
            data: {
                title: "Custom specified Settings of water ripples"
            }
        }).$mount(".app")
Copy the code

Custom instruction

 Vue.directive('shuibowen', {
                        // The variable data carried by the binding directive
            inserted: function(el, binding) {
                el.addEventListener('click'.function(e) {
                    let x = e.clientX - el.offsetLeft
                    let y = e.clientY - el.offsetTop

                    // Add a span tag to the mouse position
                    let span = document.createElement("span")
                    span.style.position = "absolute"
                    span.style.background = binding.value || 'rgba(150, 91, 91, .5)'
                    span.style.opacity = 1;
                    span.style.borderRadius = '50%'
                    el.append(span)
                    let width = 0
                    let height = 0
                    let opacity = 1
                    let max_length = Math.sqrt(el.offsetWidth * el.offsetWidth + el.offsetHeight * el.offsetHeight) * 2

                    let time = setInterval(() = > {
                        width += 5
                        height += 5
                        opacity -= 0.01
                        // If the maximum value is exceeded, clear the timing and delete the span
                        if (width < max_length) {
                            span.style.width = width + 'px'
                            span.style.height = height + 'px'
                            span.style.opacity = opacity;
                            span.style.left = x - span.offsetWidth / 2 + 'px'
                            span.style.top = y - span.offsetHeight / 2 + 'px'
                        } else {
                            clearInterval(time)
                            time = null;
                            span.remove()
                        }
                    }, 10)})}})Copy the code

conclusion

Just contacted Vue, the code is not optimized, please forgive me. The advantage of the custom water ripple directive is that the water ripple effect is applied wherever it is needed.