Reputation: 1841
I am making some 3D translated card , which has image and title on it,
the whole card has transform: rotateX(Xdeg) rotateY(Ydeg)
, and working correctly with mouseover
and mousemove
.
The problem occurred when I want to add translate3d
to title
or button
on the card , when mouse enter on card , translate3d
will not work !
I use transform
in another transformed
element before, but it seems did not work when it applies on inline element style
attribute(!), as I use js to produce inline transform
style on .card-beautiful
// https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/
(function() {
// Init
var container = document.getElementById("container"),
inner = document.querySelector(".beatiful-card");
// Mouse
var mouse = {
_x: 0,
_y: 0,
x: 0,
y: 0,
updatePosition: function(event) {
var e = event || window.event;
this.x = e.clientX - this._x;
this.y = (e.clientY - this._y) * -1;
},
setOrigin: function(e) {
this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
},
show: function() {
return "(" + this.x + ", " + this.y + ")";
}
};
// Track the mouse position relative to the center of the container.
mouse.setOrigin(container);
//----------------------------------------------------
var counter = 0;
var refreshRate = 10;
var isTimeToUpdate = function() {
return counter++ % refreshRate === 0;
};
//----------------------------------------------------
var onMouseEnterHandler = function(event) {
update(event);
};
var onMouseLeaveHandler = function() {
inner.style = "";
};
var onMouseMoveHandler = function(event) {
if (isTimeToUpdate()) {
update(event);
}
};
//----------------------------------------------------
var update = function(event) {
mouse.updatePosition(event);
updateTransformStyle(
(mouse.y / inner.offsetHeight / 2).toFixed(2),
(mouse.x / inner.offsetWidth / 2).toFixed(2)
);
};
var updateTransformStyle = function(x, y) {
var style = "rotateX(" + x + "deg) rotateY(" + y + "deg) perspective(1.1px)";
inner.style.transform = style;
inner.style.webkitTransform = style;
inner.style.mozTranform = style;
inner.style.msTransform = style;
inner.style.oTransform = style;
};
//--------------------------------------------------------
container.onmousemove = onMouseMoveHandler;
container.onmouseleave = onMouseLeaveHandler;
container.onmouseenter = onMouseEnterHandler;
})();
html, body {
width: 100%;
height: 100%;
}
body {
width: 100%;
min-height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background: #f1f1f1;
display: flex;
justify-content: center;
align-items: center;
}
#container {
perspective: 25px;
}
.beatiful-card {
display: flex;
width: 400px;
height: 250px;
position: relative;
border-radius: 20px;
background: #fff;
transition: transform 0.5s;
-webkit-transition: transform 0.5s;
box-shadow: 0 30px 35px -14px rgba(111, 208, 50, 0.58);
}
.beatiful-card:after, .beatiful-card:before {
content: " ";
position: absolute;
bottom: -13px;
left: 10px;
right: 10px;
margin: 0 5px;
background: #b8bd8d4f;
z-index: -3;
height: 13px;
border-bottom-left-radius: 14px;
border-bottom-right-radius: 14px;
}
.beatiful-card:after {
background: rgba(184, 189, 141, 0.25);
height: 21px;
bottom: -22px;
right: 25px;
left: 25px;
}
.beatiful-card .images {
position: absolute;
right: 0;
top: 0;
overflow: hidden;
width: 55%;
height: 100%;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.beatiful-card .images img {
width: 100%;
filter: sepia(40%);
height: 100%;
}
.beatiful-card .holderPart {
position: relative;
width: 45%;
}
.beatiful-card .holderPart svg {
position: absolute;
transform: rotate(270deg);
left: 83%;
top: 0;
height: 100%;
width: auto;
z-index: 0;
}
.beatiful-card .holderPart .title {
font-size: 22px;
padding: 0 16px;
font-family: "Roboto", tahoma, sans-serif;
display: block;
transition: -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
transition: transform 0.4s ease, filter 0.4s ease;
transition: transform 0.4s ease, filter 0.4s ease, -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: translate3d(0, 0, 1px);
transform: translate3d(0, 0, 1px);
}
.beatiful-card .holderPart .callToActionButton {
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: translate3d(0, 0, 1px);
transform: translate3d(0, 0, 1px);
color: #fff;
padding: 12px 11px 12px 24px;
background: #978ed3;
border-radius: 20px;
font-family: "Roboto", tahoma, sans-serif;
cursor: pointer;
box-shadow: 0 6px 14px -4px rgba(54, 55, 149, 0.42);
display: block;
position: relative;
left: 17px;
top: 4px;
}
.beatiful-card .holderPart .callToActionButton:hover {
background: #8378ca;
}
.beatiful-card .holderPart .callToActionButton:hover i {
transform: scale(1.08);
}
.beatiful-card .holderPart .callToActionButton i {
background: rgba(0, 0, 0, 0.5);
font-family: Material-Design-Iconic-Font;
padding: 9px 10px 8px 10px;
float: right;
border-radius: 100%;
position: relative;
transition: transform ease-in-out 0.3s;
top: -7px;
right: -6px;
}
.beatiful-card .holderPart p {
height: 98px;
overflow-y: hidden;
text-overflow: ellipsis;
font-weight: 200;
padding: 0 16px;
font-family: "Roboto", tahoma, sans-serif;
font-size: 14px;
position: relative;
z-index: 1;
}
.beatiful-card .holderPart p:after {
content: "";
text-align: right;
position: absolute;
bottom: 0;
right: 0;
width: 70%;
height: 1.2em;
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%);
}
<div id="container">
<div class="beatiful-card">
<div class="images"><img class="mainImage" src="https://rukminim1.flixcart.com/image/832/832/jbs96kw0/carpet-rug/v/3/f/carpetblu-03-supreme-home-collective-original-imaewgneqxtsvgfr.jpeg?q=70"/></div>
<div class="holderPart">
<h3 class="title">MyCode</h3>
<p class="description">Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</p>
<svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
<path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:#fff;"></path>
</svg>
<div class="callToActionButton">Hi , Jeffreson<i class="zmdi zmdi-favorite"></i></div>
</div>
</div>
</div>
Code on Codepen. [sass and pug]
Upvotes: 0
Views: 1088
Reputation: 272592
You need to add transform-style: preserve-3d;
and remove the perspective you are adding at the end of the dynamic transform. It's useless since it's at the end.
The perspective defined in the container is already doing the job.
// https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/
(function() {
// Init
var container = document.getElementById("container"),
inner = document.querySelector(".beatiful-card");
// Mouse
var mouse = {
_x: 0,
_y: 0,
x: 0,
y: 0,
updatePosition: function(event) {
var e = event || window.event;
this.x = e.clientX - this._x;
this.y = (e.clientY - this._y) * -1;
},
setOrigin: function(e) {
this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
},
show: function() {
return "(" + this.x + ", " + this.y + ")";
}
};
// Track the mouse position relative to the center of the container.
mouse.setOrigin(container);
//----------------------------------------------------
var counter = 0;
var refreshRate = 10;
var isTimeToUpdate = function() {
return counter++ % refreshRate === 0;
};
//----------------------------------------------------
var onMouseEnterHandler = function(event) {
update(event);
};
var onMouseLeaveHandler = function() {
inner.style = "";
};
var onMouseMoveHandler = function(event) {
if (isTimeToUpdate()) {
update(event);
}
};
//----------------------------------------------------
var update = function(event) {
mouse.updatePosition(event);
updateTransformStyle(
(mouse.y / inner.offsetHeight / 2).toFixed(2),
(mouse.x / inner.offsetWidth / 2).toFixed(2)
);
};
var updateTransformStyle = function(x, y) {
var style = "rotateX(" + x + "deg) rotateY(" + y + "deg) ";
inner.style.transform = style;
inner.style.webkitTransform = style;
inner.style.mozTranform = style;
inner.style.msTransform = style;
inner.style.oTransform = style;
};
//--------------------------------------------------------
container.onmousemove = onMouseMoveHandler;
container.onmouseleave = onMouseLeaveHandler;
container.onmouseenter = onMouseEnterHandler;
})();
html, body {
width: 100%;
height: 100%;
}
body {
width: 100%;
min-height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background: #f1f1f1;
display: flex;
justify-content: center;
align-items: center;
}
#container {
perspective: 25px;
}
.beatiful-card {
display: flex;
width: 400px;
height: 250px;
position: relative;
border-radius: 20px;
background: #fff;
transition: transform 0.5s;
-webkit-transition: transform 0.5s;
box-shadow: 0 30px 35px -14px rgba(111, 208, 50, 0.58);
transform-style: preserve-3d;
}
.beatiful-card:after, .beatiful-card:before {
content: " ";
position: absolute;
bottom: -13px;
left: 10px;
right: 10px;
margin: 0 5px;
background: #b8bd8d4f;
z-index: -3;
height: 13px;
border-bottom-left-radius: 14px;
border-bottom-right-radius: 14px;
}
.beatiful-card:after {
background: rgba(184, 189, 141, 0.25);
height: 21px;
bottom: -22px;
right: 25px;
left: 25px;
}
.beatiful-card .images {
position: absolute;
right: 0;
top: 0;
overflow: hidden;
width: 55%;
height: 100%;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
.beatiful-card .images img {
width: 100%;
filter: sepia(40%);
height: 100%;
}
.beatiful-card .holderPart {
position: relative;
width: 45%;
}
.beatiful-card .holderPart svg {
position: absolute;
transform: rotate(270deg);
left: 83%;
top: 0;
height: 100%;
width: auto;
z-index: 0;
}
.beatiful-card .holderPart .title {
font-size: 22px;
padding: 0 16px;
font-family: "Roboto", tahoma, sans-serif;
display: block;
transition: -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
transition: transform 0.4s ease, filter 0.4s ease;
transition: transform 0.4s ease, filter 0.4s ease, -webkit-transform 0.4s ease, -webkit-filter 0.4s ease;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: translate3d(0, 0, 1px);
transform: translate3d(0, 0, 1px);
}
.beatiful-card .holderPart .callToActionButton {
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: translate3d(0, 0, 1px);
transform: translate3d(0, 0, 1px);
color: #fff;
padding: 12px 11px 12px 24px;
background: #978ed3;
border-radius: 20px;
font-family: "Roboto", tahoma, sans-serif;
cursor: pointer;
box-shadow: 0 6px 14px -4px rgba(54, 55, 149, 0.42);
display: block;
position: relative;
left: 17px;
top: 4px;
}
.beatiful-card .holderPart .callToActionButton:hover {
background: #8378ca;
}
.beatiful-card .holderPart .callToActionButton:hover i {
transform: scale(1.08);
}
.beatiful-card .holderPart .callToActionButton i {
background: rgba(0, 0, 0, 0.5);
font-family: Material-Design-Iconic-Font;
padding: 9px 10px 8px 10px;
float: right;
border-radius: 100%;
position: relative;
transition: transform ease-in-out 0.3s;
top: -7px;
right: -6px;
}
.beatiful-card .holderPart p {
height: 98px;
overflow-y: hidden;
text-overflow: ellipsis;
font-weight: 200;
padding: 0 16px;
font-family: "Roboto", tahoma, sans-serif;
font-size: 14px;
position: relative;
z-index: 1;
}
.beatiful-card .holderPart p:after {
content: "";
text-align: right;
position: absolute;
bottom: 0;
right: 0;
width: 70%;
height: 1.2em;
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%);
}
<div id="container">
<div class="beatiful-card">
<div class="images"><img class="mainImage" src="https://rukminim1.flixcart.com/image/832/832/jbs96kw0/carpet-rug/v/3/f/carpetblu-03-supreme-home-collective-original-imaewgneqxtsvgfr.jpeg?q=70"/></div>
<div class="holderPart">
<h3 class="title">MyCode</h3>
<p class="description">Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</p>
<svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
<path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:#fff;"></path>
</svg>
<div class="callToActionButton">Hi , Jeffreson<i class="zmdi zmdi-favorite"></i></div>
</div>
</div>
</div>
Upvotes: 1