简体   繁体   中英

How to make an onclick event on child div affect the transparency of parent div?

I'm trying to modify a jquery plugin so that the background painting is visible through the ripple effect when clicked instead of just a black ripple. So I want the ripple to affect the transparency of the white columns. I'm not sure if it's even possible. Here's a quick SS illustrating what I mean: http://oi60.tinypic.com/34xhkdk.jpg .

http://codepen.io/anon/pen/gbOQOX

Thanks a lot for any insight.

The code:

html:

<h1>Ripple Click Effect</h1>
<ul>
    <li><a>Dashboard</a></li>
    <li><a>My Account</a></li>
    <li><a>Direct Messages</a></li>
    <li><a>Chat Rooms</a></li>
    <li><a>Settings</a></li>
    <li><a>Logout</a></li>
</ul>

<!-- jQuery -->
<script src="http://thecodeplayer.com/u/js/jquery-1.9.1.min.js" type="text/javascript"></script>

css:

/*custom fonts - Bitter, Montserrat*/
@import url('http://fonts.googleapis.com/css?family=Montserrat|Bitter');
/*basic reset*/
* {margin: 0; padding: 0;}
body {
    background: url('http://wallpaper4me.com/images/wallpapers/greekpainting-361526.jpeg') no-repeat center center fixed;
    background-size: cover;
}

/*nav styles*/
ul {
    background: rgba(255,255,255,1); border-top: 6px solid #70C2C2;
    width: 600px; margin: 0 auto;
}
ul li {
    list-style-type: none;
    /*relative positioning for list items along with overflow hidden to contain the overflowing ripple*/
    position: relative;
    overflow: hidden;
}
ul li a {
    font: normal 14px/28px Montserrat; color: #3D8F8F;
    display: block; padding: 10px 15px;
    text-decoration: none;
    cursor: pointer; /*since the links are dummy without href values*/
    /*prevent text selection*/
    user-select: none;
    /*static positioned elements appear behind absolutely positioned siblings(.ink in this case) hence we will make the links relatively positioned to bring them above .ink*/
    position: relative;
}

/*.ink styles - the elements which will create the ripple effect. The size and position of these elements will be set by the JS code. Initially these elements will be scaled down to 0% and later animated to large fading circles on user click.*/
.ink {
    display: block; position: absolute;
    background: rgba(0,0,0,1);
    border-radius: 100%;
    transform: scale(0);
}
/*animation effect*/
.ink.animate {animation: ripple 0.65s linear;}
@keyframes ripple {
    /*scale the element to 250% to safely cover the entire link and fade it out*/
    100% {opacity: 0; transform: scale(1.5);}
}

jquery:

//jQuery time
var parent, ink, d, x, y;
$("ul li a").click(function(e){
    parent = $(this).parent();
    //create .ink element if it doesn't exist
    if(parent.find(".ink").length == 0)
        parent.prepend("<span class='ink'></span>");

    ink = parent.find(".ink");
    //incase of quick double clicks stop the previous animation
    ink.removeClass("animate");

    //set size of .ink
    if(!ink.height() && !ink.width())
    {
        //use parent's width or height whichever is larger for the diameter to make a circle which can cover the entire element.
        d = Math.max(parent.outerWidth(), parent.outerHeight());
        ink.css({height: d, width: d});
    }

    //get click coordinates
    //logic = click coordinates relative to page - parent's position relative to page - half of self height/width to make it controllable from the center;
    x = e.pageX - parent.offset().left - ink.width()/2;
    y = e.pageY - parent.offset().top - ink.height()/2;

    //set the position and add class .animate
    ink.css({top: y+'px', left: x+'px'}).addClass("animate");
})

Demo: http://codepen.io/placidcow/pen/ogNRKL

Explanation:

Rather than append a span which is centered at the point you click and just grows and fades, have three spans:

  1. One that shrinks back from the click point to the left
  2. One in the centre that grows outward
  3. One that shrinks back to the right

The gaps between the three spans gives the impression of a transparent ripple. (gradients used to make transparency seem gradually rather than missing rectangles just moving.

On top of this, an extra animation is applied to the li to fade from transparent background to a solid one so the ripple appears to gradually disappear rather than be moving and then suddenly everything reverts back.

Edits to CSS:

ul {
    /*no background otherwise can't see through the links!*/
}
ul li {
    /*add background to this instead!*/
    background: #fff;
}
.ink {
    background: rgba(255,255,255,1);
    /*gradient*/
    background: linear-gradient(to left, transparent, #fff, #fff);
}
.rink {
    display: block; position: absolute;
    background: rgba(255,255,255,1);
    border-radius: 100%;
    background: linear-gradient(to right, transparent, #fff, #fff);
}

/*animation effect*/
.ink.animate {
    transform-origin: 0 50%;
    animation: ripple 0.65s linear;
}
.rink.animater {
    transform-origin: 100% 50%;
    animation: ripple 0.65s linear;
}
.cink.animate2 {
    animation: ripple2 0.65s linear;
}
.recover {
    animation: fade 0.65s linear;
}

@keyframes fade {
    0% {background: transparent;}
    100% { background: #fff;}
}

@keyframes ripple {
    100% {opacity: 1; transform: scale(0.1);}
}

@keyframes ripple2 {
    100% {opacity: 1; transform: scale(2.5);}
}

Newish JS:

var parent, ink, d, x, y, rink;
$("ul li a").click(function(e){
  parent = $(this).parent();

 this.parentNode.style.background = 'transparent';

  if(parent.find(".ink").length == 0)
    parent.prepend("<span class='ink'></span>"); //left slide
  if(parent.find(".rink").length == 0)
    parent.prepend("<span class='rink'></span>"); //right slide
  if(parent.find(".cink").length == 0)
    parent.prepend("<span class='cink'></span>"); //centre slide

  ink = parent.find(".ink");
  rink = parent.find(".rink");
  cink = parent.find(".cink");

  //in case of quick double clicks stop the previous animation
  ink.removeClass("animate");
  rink.removeClass("animater");
  cink.removeClass("animate2");
  parent.removeClass("recover");

  if(!ink.height() && !ink.width()) {
    d = Math.max(parent.outerWidth(), parent.outerHeight());
    ink.css({height: d, width: d});
    rink.css({height: d, width: d});
    cink.css({height: d, width: d/5});
  }

  parent.addClass("recover");

  //centre slide:
  x = e.pageX - parent.offset().left - cink.width()/2;
    y = e.pageY - parent.offset().top - cink.height()/2;

    //set the position and add class .animate
    cink.css({top: y+'px', left: x+'px'}).addClass("animate2");


  //left and right slides positions, widths and animation:
  x = -20;
  y = e.pageY - parent.offset().top - ink.height()/2;

  //set widths so fit edges/reach click point
  ink.css({width:e.pageX-parent.offset().left/2});
  rink.css({width:parent.width()-e.pageX+parent.offset().left+20});

  //set the position and add class .animate
  ink.css({top: y+'px', left: x+'px'}).addClass("animate"); 
  x=e.pageX-parent.offset().left;
  rink.css({top: y+'px', left: x+'px'}).addClass("animater");  

  //need cleaner way to reset back colour!
  var self = this;
  setTimeout(function() { self.parentNode.style.background = '#fff';},650);
})

演示结果

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM