It is a combination of CSS and a card that flips when you click on the icon button in the upper right-hand corner.
You can use angular app or create a new using ng new app-name. We first need an app to create a component.
Create a new component called GameCardComponent using the below command.
ng generate component game-card
export interface CardData {
imageId: string;
state: 'default' | 'flipped' | 'matched';
}
The interface consists of an image that represents the ID of the image on the front face of the card. And represents the state of the card.
Notice how the state has multiple values. Our IDE can give us helpful hints by declaring in this way when we are about to assign a value to them in code. It makes the development experience a lot better.
The states will correspond to angular animation states. Tapping on the card will allow us to transition from one state to another.
Making a 3D card UI with images
We first need to define a structure in house HTML to game cards for all of that to work by definition, our card has a front and a backside.
By using div for both sides contained in the parent.
<div class="card" (click)="cardClicked()">
<div class="face back">
<img src="assets/card-back.jpg">
</div>
<div class="face front">
<img [src]="'https://source.unsplash.com/' + data.imageId + '/200x300'">
</div>
</div>
There is an img element inside the div. There is a graphic store in my asset folder on the backside.
The front side uses the Unsplash API to fetch the image with id specified in the data.
app.component.html
<!--Rotating card-->
<div class="col-md-4">
<mdb-flipping-card #cards>
<!--Front Side-->
<div class="face front tp-box_side tp-box_front">
<!-- Image-->
<div class="card-up">
<img src="https://mdbootstrap.com/img/Photos/Horizontal/Nature/4-col/img%20%2859%29.jpg" class="img-fluid">
</div>
<!--Avatar-->
<div class="avatar">
<img src="https://mdbootstrap.com/img/Photos/Avatars/img%20%289%29.jpg" class="rounded-circle img-responsive">
</div>
<!--Content-->
<div class="card-body">
<h4>Jonathan Doe</h4>
<p>Web developer</p>
<!--Triggering button-->
<a class="rotate-btn" data-card="card-1" (click)="cards.toggle()">
<mdb-icon fas icon="redo"></mdb-icon> Click here to rotate</a>
</div>
</div>
<!--/.Front Side-->
<!--Back Side-->
<div class="back tp-box_side tp-box_back">
<!--Content-->
<h4>About me</h4>
<hr>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime quae, dolores dicta. Blanditiis rem
amet repellat,
quaerat?</p>
<hr>
<!--Social Icons-->
<ul class="list-inline">
<li class="list-inline-item">
<a class="icons-sm fb-ic">
<mdb-icon fab icon="facebook-f"></mdb-icon>
</a>
</li>
<li class="list-inline-item">
<a class="icons-sm tw-ic">
<mdb-icon fab icon="twitter"></mdb-icon>
</a>
</li>
<li class="list-inline-item">
<a class="icons-sm gplus-ic">
<mdb-icon fab icon="google-plus"></mdb-icon>
</a>
</li>
<li class="list-inline-item">
<a class="icons-sm li-ic">
<mdb-icon fab icon="linkedin-in"></mdb-icon>
</a>
</li>
</ul>
<!--Triggering button-->
<a class="rotate-btn" data-card="card-1" (click)="cards.toggle()">
<mdb-icon fas icon="undo"></mdb-icon> Click here to rotate back</a>
</div>
<!--/.Back Side-->
</mdb-flipping-card>
</div>
<!--/.Rotating card-->
Generate a new component
ng g c grid-car-layout
In the grid-card.layout.module.css
.grid-container {
margin: 20px;
}
.dashboard-card {
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
}
.more-button-right {
position: absolute;
top: 5px;
right: 10px;
}
.flippable-card {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform 1s;
}
.flippable-card mat-card {
margin: 0;
display: block;
position: absolute;
backface-visibility: hidden;
}
.flippable-card .back {
background: #fff;
transform: rotateY( 180deg );
}
.flippable-card.flipped {
transform: rotateY( 180deg );
}
grid-card.layout.module.ts
flipped: boolean;
constructor() { }
ngOnInit() {
this.flipped = false;
}
Here, the left card is plain and the right card has two sides.
grid-card.layout.module.html
<div class="grid-container">
<mat-grid-list cols="2" rowHeight="100px">
<mat-grid-tile [colspan]="1" [rowspan]="2">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="2" >
<div class='flippable-card' [ngClass]="{'flipped':flipped}" >
<mat-grid-tile [colspan]="6" [rowspan]="3">
<div class='flippable-card' [ngClass]="{'flipped':flipped}" >
<mat-card class="dashboard-card">
<!-- <mat-card-title><button class="more-button" mat-icon-button (click)='flipped = !flipped'><mat-icon>flip</mat-icon></button></mat-card-title> -->
<mat-card-title>
<button class="more-button-right" mat-icon-button (click)='flipped = !flipped'><mat-icon>flip_camera_android</mat-icon></button>
</mat-card-title>
<mat-card-content>
FRONT SIDE
</mat-card-content>
</mat-card>
<mat-card class='dashboard-card back'>
<mat-card-title>
<button class="more-button-right" mat-icon-button (click)='flipped = !flipped'><mat-icon>flip_camera_android</mat-icon></button>
</mat-card-title>
<mat-card-content>
</mat-card-content>
</mat-card>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
Example:
app.component.html
<section class="container">
<div class="card" onclick="flip()">
<div class="front">1</div>
<div class="back">2</div>
</div>
</section>
<button onclick="flip()">flip the card</button>
<a href="https://jsfiddle.net/james2doyle/qsQun/">Fiddle for reference</a>
app.component.css
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto;
border: 1px solid #ccc;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
border: 1px solid red;
}
.card {
width: 100%;
height: 100%;
position: absolute;
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: 50% 50%;
}
.card div {
display: block;
height: 100%;
width: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 140px;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
.card .front {
background: red;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg );
-moz-transform: rotateY( 180deg );
-o-transform: rotateY( 180deg );
transform: rotateY( 180deg );
}
.card.flipped {
-webkit-transform: rotateY( 180deg );
-moz-transform: rotateY( 180deg );
-o-transform: rotateY( 180deg );
transform: rotateY( 180deg );
}
a {display: block;}
button {margin-bottom: 50px;}
function flip() {
$('.card').toggleClass('flipped');
}
Output:
Leave a Reply