简体   繁体   中英

CSS Transform Rotate 3D - Hover on each corner of a card

I am trying to use css 3d rotation to simulate pushing down on a card when the mouse hovers over it divided into 4 quadrants. Top Left, Top Right, Bottom Left, Bottom Right. I got the top left/right to work but no matter what combination I try I can't get the bottom effects to work the same as the top. Any idea of how to get the bottom left/right to look correct like they are being pushed down the same way the top corners seem to look correct? Also, if there is a better way to do this altogether in css/js let me know I am just messing around with these css transformations for the first time.

I added shadows to try and help "sell" the effect of the bottom being pushed in while top pops out but it still looks wrong. Might just be me, trick of the eye of something.

 function ThzhotspotPosition(evt, el, percent) { var left = el.offset().left; var top = el.offset().top; if (percent) { x = (evt.pageX - left) / el.outerWidth() * 100; y = (evt.pageY - top) / el.outerHeight() * 100; } else { x = (evt.pageX - left); y = (evt.pageY - top); } return { x: Math.round(x), y: Math.round(y) }; } $(".card").mousemove(function(e) { var hp = ThzhotspotPosition(e, $(this), true); // true = percent | false or no attr = px if (hp.x >= 50 && hp.y >= 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-BR"); } else if (hp.x >= 50 && hp.y < 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-TR"); } else if (hp.x < 50 && hp.y >= 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-BL"); } else { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-TL"); } $('#debug').text(hp.x + '%x' + ' ' + hp.y + '%y'); }); $(".card").hover( function(e) { //$( this ).addClass( "roll-left" ); }, function() { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }); } );
 .card { width: 100px; height: 150px; background: red; position: relative; transition: transform 1s; transform-style: preserve-3d; }.card.roll-TL { transform: rotate3d(1, -1, 0, 20deg); -webkit-box-shadow: 5px 5px 13px 2px rgba(0,0,0,0.41); box-shadow: 5px 5px 13px 2px rgba(0,0,0,0.41); }.card.roll-TR { transform: rotate3d(-1, -1, 0, -20deg); -webkit-box-shadow: -5px 5px 13px 2px rgba(0,0,0,0.41); box-shadow: -5px 5px 13px 2px rgba(0,0,0,0.41); }.card.roll-BL { transform: rotate3d(-1, -1, 0, 20deg); -webkit-box-shadow: 5px -5px 13px 2px rgba(0,0,0,0.41); box-shadow: 5px -5px 13px 2px rgba(0,0,0,0.41); }.card.roll-BR { transform: rotate3d(1, -1, 0, -20deg); -webkit-box-shadow: -5px -5px 13px 2px rgba(0,0,0,0.41); box-shadow: -5px -5px 13px 2px rgba(0,0,0,0.41); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="card">Testing</div> <div id="debug"></div>

I assume your js code correct (as I don't see problem when I run it) and just adjust some css.

 function ThzhotspotPosition(evt, el, percent) { var left = el.offset().left; var top = el.offset().top; if (percent) { x = (evt.pageX - left) / el.outerWidth() * 100; y = (evt.pageY - top) / el.outerHeight() * 100; } else { x = (evt.pageX - left); y = (evt.pageY - top); } return { x: Math.round(x), y: Math.round(y) }; } $(".card").mousemove(function(e) { var hp = ThzhotspotPosition(e, $(this), true); // true = percent | false or no attr = px if (hp.x >= 50 && hp.y >= 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-BR"); } else if (hp.x >= 50 && hp.y < 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-TR"); } else if (hp.x < 50 && hp.y >= 50) { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-BL"); } else { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }).addClass("roll-TL"); } $('#debug').text(hp.x + '%x' + ' ' + hp.y + '%y'); }); $(".card").hover( function(e) { //$( this ).addClass( "roll-left" ); }, function() { $(this).removeClass(function(index, className) { return (className.match(/(^|\s)roll-\S+/g) || []).join(' '); }); } );
 .card { width: 200px; height: 280px; background: red; position: relative; transition: transform 1s; transform-style: preserve-3d; } /*the backside*/.card:after{ content:''; position:absolute; left:0;top:0;right:0;bottom:0; background: gray; transform: translateZ(-10px); }.card.roll-TL { transform: rotate3d(1, -1, 0, 20deg); }.card.roll-TR { transform: rotate3d(-1, -1, 0, -20deg); }.card.roll-BL { transform: rotate3d(-1, -1, 0, 20deg); }.card.roll-BR { transform: rotate3d(1, -1, 0, -20deg); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="card">Testing</div> <div id="debug"></div>

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