Rotate a container using CSS and JavaScript - javascript

There is a 2X2 grid container. I can not rotate container directly, I have to rotate these grids in such a way that It should look like I have rotated the container. Question: Rotate2
Look at this image, this is not a single image but 4. I want to rotate these images and result should be like I have rotated the main container Img
My solution:
Rotate the img1 with origin bottom-right, img2 with origin bottom-left, img3 with origin top-right and img4 with origin top-left, because this will make rotation along with center of container. image after rotating grids
.img1{
-webkit-transform: rotate(10deg);
-webkit-transform-origin: bottom right;
}
.img2{
-webkit-transform: rotate(10deg);
-webkit-transform-origin: bottom left;
}
.img3{
-webkit-transform: rotate(10deg);
-webkit-transform-origin: top right;
}
.img4{
-webkit-transform: rotate(10deg);
-webkit-transform-origin: top left;
}
This solution works as expected for 2x2 container, but what if container is 3x3 or 4x4, how can I find out the solution which will work for N x N grid? Question: Rotate3
Edit:
I am not able to explain the question properly. Here is question in simple form -
How to rotate the NxN grid along with center of container?

You actually just need to imagine where the origin is (which always has to be in the middle of the container), if let's say the grid is 2x2, the origin would be 1x the the first column and 1x of the first row. If the grid is 3x3, the origin would be 1.5x of the first column, and 1.5x of the first row. If the grid is 4x4, the origin would be 2x of the first column and 2x of the first row. And 1x = 100%, so 1.5x = 150%, and that's just the starting point, from that value, you can decrease it by 100% for each column and row.
3x3:
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
padding: 60px;
}
.img {
background: blue;
width: 30%;
height: 200px;
border: 2px solid black;
box-sizing: border-box;
}
.img1 {
transform-origin: 150% 150%;
transform: rotate(45deg);
}
.img2 {
transform-origin: 50% 150%;
transform: rotate(45deg);
}
.img3 {
transform-origin: -50% 150%;
transform: rotate(45deg);
}
.img4 {
transform-origin: 150% 50%;
transform: rotate(45deg);
}
.img5 {
transform-origin: 50% 50%;
transform: rotate(45deg);
}
.img6 {
transform-origin: -50% 50%;
transform: rotate(45deg);
}
.img7 {
transform-origin: 150% -50%;
transform: rotate(45deg);
}
.img8 {
transform-origin: 50% -50%;
transform: rotate(45deg);
}
.img9 {
transform-origin: -50% -50%;
transform: rotate(45deg);
}
<div class="container">
<div class="img img1"></div>
<div class="img img2"></div>
<div class="img img3"></div>
<div class="img img4"></div>
<div class="img img5"></div>
<div class="img img6"></div>
<div class="img img7"></div>
<div class="img img8"></div>
<div class="img img9"></div>
</div>
4x4
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
padding: 60px;
}
.img {
background: blue;
width: 25%;
height: 200px;
border: 2px solid black;
box-sizing: border-box;
}
.img1 {
transform-origin: 200% 200%;
transform: rotate(45deg);
}
.img2 {
transform-origin: 100% 200%;
transform: rotate(45deg);
}
.img3 {
transform-origin: 0% 200%;
transform: rotate(45deg);
}
.img4 {
transform-origin: -100% 200%;
transform: rotate(45deg);
}
.img5 {
transform-origin: 200% 100%;
transform: rotate(45deg);
}
.img6 {
transform-origin: 100% 100%;
transform: rotate(45deg);
}
.img7 {
transform-origin: 0% 100%;
transform: rotate(45deg);
}
.img8 {
transform-origin: -100% 100%;
transform: rotate(45deg);
}
.img9 {
transform-origin: 200% 0%;
transform: rotate(45deg);
}
.img10 {
transform-origin: 100% 0%;
transform: rotate(45deg);
}
.img11 {
transform-origin: 0% 0%;
transform: rotate(45deg);
}
.img12 {
transform-origin: -100% 0%;
transform: rotate(45deg);
}
.img13 {
transform-origin: 200% -100%;
transform: rotate(45deg);
}
.img14 {
transform-origin: 100% -100%;
transform: rotate(45deg);
}
.img15 {
transform-origin: 0% -100%;
transform: rotate(45deg);
}
.img16 {
transform-origin: -100% -100%;
transform: rotate(45deg);
}
<div class="container">
<div class="img img1"></div>
<div class="img img2"></div>
<div class="img img3"></div>
<div class="img img4"></div>
<div class="img img5"></div>
<div class="img img6"></div>
<div class="img img7"></div>
<div class="img img8"></div>
<div class="img img9"></div>
<div class="img img10"></div>
<div class="img img11"></div>
<div class="img img12"></div>
<div class="img img13"></div>
<div class="img img14"></div>
<div class="img img15"></div>
<div class="img img16"></div>
</div>
NxN:
const generate = document.getElementById('generate');
const container = document.getElementById('container');
generate.addEventListener('click', () => {
const angle = document.getElementById('angle').value;
const n = document.getElementById('n').value;
container.innerHTML = "";
const initialPercentage = Math.floor(Number(n) / 2) * 100;
const width = 100 / Number(n);
let yPercentage = initialPercentage;
for (let i = 0; i < Number(n); i++) {
let xPercentage = initialPercentage;
for (let j = 0; j < Number(n); j++) {
const div = document.createElement("div");
div.classList.add("img");
div.style.width = `${width}%`;
div.style.paddingBottom = `${width}%`;
div.style.transform = `rotate(${angle}deg)`;
div.style.transformOrigin = `${xPercentage}% ${yPercentage}%`;
xPercentage -= 100;
container.appendChild(div);
}
yPercentage -= 100;
}
});
#container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
padding: 60px;
}
.img {
background: blue;
border: 2px solid black;
box-sizing: border-box;
}
<input id="angle" type="number" placeholder="angle" />
<input id="n" type="number" placeholder="N" />
<button id="generate">generate</button>
<div id="container">
</div>
If my explanation was so hard to understand, you could see the pattern from the snippet I provided above.

Related

Cannot convert images to a link using anchor tag in image carousel

first post on here!
I've been having issues when using the following codepen.
I tried putting the img inside an anchor tag to make the images of the carousel links to the pages I wanted, but when I do so it completely affects the way the pictures are displayed.
Here is what the carousel looks like when I add around img and change the code in the CSS replacing "img" by "a"
Here is what it looks like without the anchor tags
There might be a simple solution to this but I am a beginner hence my difficulty with this, would be more than grateful if anyone could help!
I have tried changing the CSS code, but I do not know if I need to change the js as well
var angle = 0;
function galleryspin(sign) {
spinner = document.querySelector("#spinner");
if (!sign) {
angle = angle + 45;
} else {
angle = angle - 45;
}
spinner.setAttribute("style", "-webkit-transform: rotateY(" + angle + "deg); -moz-transform: rotateY(" + angle + "deg); transform: rotateY(" + angle + "deg);");
}
div#carousel {
perspective: 1200px;
background: transparent;
padding-top: 5%;
font-size: 0;
margin-bottom: 3rem;
overflow: hidden;
}
figure#spinner {
transform-style: preserve-3d;
height: 400px;
transform-origin: 50% 50% -500px;
transition: 1s;
object-fit: contain;
}
figure#spinner img {
width: 40%;
max-width: 425px;
position: absolute;
left: 30%;
transform-origin: 50% 50% -500px;
outline: 1px solid transparent;
}
figure#spinner img:nth-child(1) {
transform: rotateY(0deg);
}
figure#spinner img:nth-child(2) {
transform: rotateY(45deg);
}
figure#spinner img:nth-child(3) {
transform: rotateY(90deg);
}
figure#spinner img:nth-child(4) {
transform: rotateY(135deg);
}
figure#spinner img:nth-child(5) {
transform: rotateY(180deg);
}
figure#spinner img:nth-child(6) {
transform: rotateY(225deg);
}
figure#spinner img:nth-child(7) {
transform: rotateY(270deg);
}
figure#spinner img:nth-child(8) {
transform: rotateY(315deg);
}
div#carousel~span {
color: #fff;
margin: 5%;
display: inline-block;
text-decoration: none;
font-size: 2rem;
transition: 0.6s color;
position: relative;
margin-top: -6rem;
border-bottom: none;
line-height: 0;
}
<div id="carousel">
<figure id="spinner">
<img src="./Resources/Images/weeks/week1.png" alt>
<img src="./Resources/Images/weeks/week2.png" alt>
<img src="./Resources/Images/weeks/week3.png" alt>
<img src="./Resources/Images/weeks/week4.png" alt>
<img src="./Resources/Images/weeks/week5.png" alt>
<img src="./Resources/Images/weeks/week6.png" alt>
<img src="./Resources/Images/weeks/week7.png" alt>
<img src="./Resources/Images/weeks/week8.png" alt>
</figure>
</div>
<span style="float:left" class="ss-icon" onclick="galleryspin('')"><</span>
<span style="float:right" class="ss-icon" onclick="galleryspin('-')">></span>
</div>

I want to create a vote system with jQuery but not working

I am trying to create a function with jQuery but I can't. When you press a button then an arrow will move to 36 degrees. I have 5 buttons and the circle is 180 degrees.
My code is working in one way but it's not in reverse, which means when you press button 1 to 5 it's working but when I try to click randomly then it is not working.
Here is what i am trying to build
$(document).ready(function() {
$("#ang36").click(function() {
$("#silder_image").removeClass("animate1");
$("#silder_image").addClass("animate1");
});
$("#ang72").click(function() {
$("#silder_image").removeClass("animate2");
$("#silder_image").addClass("animate2");
});
$("#ang108").click(function() {
$("#silder_image").removeClass("animate3");
$("#silder_image").addClass("animate3");
});
$("#ang144").click(function() {
$("#silder_image").removeClass("animate4");
$("#silder_image").addClass("animate4");
});
$("#ang180").click(function() {
$("#silder_image").removeClass("animate5");
$("#silder_image").addClass("animate5");
});
});
.slider_area {
width: 800px;
margin: 0 auto;
position: relative;
margin-top: 400px;
}
.silder_image {
width: 100px;
height: 100px;
}
.animate1 {
transform: rotate(36deg);
-ms-transform: rotate(36deg);
-webkit-transform: rotate(36deg);
transform-origin: center center;
transition-duration: 5s;
}
.animate1 img,
.animate2 img,
.animate3 img,
.animate4 img,
.animate5 img {
transform: rotate(-90deg);
}
.animate2 {
transform: rotate(72deg);
-ms-transform: rotate(72deg);
-webkit-transform: rotate(72deg);
transform-origin: center center;
transition-duration: 5s;
}
.animate3 {
transform: rotate(108deg);
-ms-transform: rotate(108deg);
-webkit-transform: rotate(108deg);
transform-origin: center center;
transition-duration: 5s;
}
.animate4 {
transform: rotate(144deg);
-ms-transform: rotate(144deg);
-webkit-transform: rotate(144deg);
transform-origin: center center;
transition-duration: 5s;
}
.animate5 {
transform: rotate(180deg);
-ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
transform-origin: center center;
transition-duration: 5s;
}
.triggrs {
position: relative;
width: 400px;
bottom: -171px;
left: 0;
}
<div class="slider_area">
<div id="silder_image">
<img src="Slider Vote.png" alt="">
</div>
<div class="triggrs">
<button id="ang36">button1</button>
<button id="ang72">button2</button>
<button id="ang108">button3</button>
<button id="ang144">button4</button>
<button id="ang180">button5</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
I created another approach which could also help you further (maybe).
let needle = document.querySelector('#needle ');
let btns = document.querySelectorAll('button')
btns.forEach( btn=>{ btn.addEventListener('click', function() {
let level = this.dataset.deg;
needle.style.transform = "rotate("+Number(level)+"deg)"});
})
#panel {
height: 50px;
overflow: hidden;
}
.circle{
width: 100px;
height: 100px;
border-radius: 100%;
border: 5px solid grey;
position: relative;
display: flex;
justify-content: center;
transform: rotate(-90deg);
background: #ffffff;
background: linear-gradient(to bottom, #ffffff 0%,#e8e000 50%,#e50000 100%);
}
#needle {
width: 6px;
height: 50px;
background: #4361ff;
transform-origin: bottom;
transition: transform .75s cubic-bezier(.31,-0.52,.84,1.55);
transform: rotate(30deg);
box-sizing: border-box;
margin-left: -3px;
}
.buttons {
margin-top: 2rem;
}
<div id="panel">
<div class="circle">
<div id="needle"></div>
</div>
</div>
<div class="buttons">
<button data-deg="30">1</button>
<button data-deg="60">2</button>
<button data-deg="90">3</button>
<button data-deg="120">4</button>
<button data-deg="150">5</button>
</div>

Modify element :before CSS rules programmatically in React

I have an element whose :before style has to be modified based on calculations.
export class Content extends React.Component {
render() {
return (
<div className="ring-base">
<div className="ring-left" style={{/* Change here */}}></div>
<div className="ring-right" style={{/* Change here */}}></div>
<div className="ring-cover">
<div className="ring-text">10%</div>
</div>
</div>
);
}
}
CSS Code:
.ring-base {
position: absolute;
height: 200px;
width: 200px;
border-radius: 50%;
background: red;
transform: rotate(90deg);
overflow:hidden;
}
.ring-cover {
position: absolute;
height: 180px;
width: 180px;
background: #fff;
border-radius: 50%;
top: 5%;
left: 5%;
}
.ring-cover .ring-text {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 2em;
display: flex;
justify-content:center;
align-content:center;
flex-direction:column;
transform: rotate(-90deg);
}
.ring-right, .ring-left {
height: 100px;
width: 200px;
overflow: hidden;
position: absolute;
}
.ring-right:before, .ring-left:before {
height: inherit;
width: inherit;
position: absolute;
content: "";
border-radius: 100px 100px 0 0;
background-color: grey;
transform: rotate(0deg);
}
.ring-right {
-webkit-transform-origin: 50% 0%;
-moz-transform-origin: 50% 0%;
-ms-transform-origin: 50% 0%;
transform-origin: 50% 0%;
transform: rotateZ(0deg);
}
.ring-left {
transform: rotate(180deg);
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
}
.ring-right:before {
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
transform: rotate(0deg);
}
.ring-left:before {
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
The ask is to be able to update the transform property for .ring-left:before and .ring-right:before via ReactJS.
If there is a way to not update the :before class and change the CSS to not make use of :before at all, then do suggest that as well.
Js-Fiddle
You can iterate document.styleSheets, set .style of .cssRules where .selectorText matches pseudo selector
let sheets = document.styleSheets;
let selector = "div::before";
let replacementContent = '"after"';
for (let sheet of sheets) {
for (let rule of sheet.cssRules) {
if (rule.selectorText === selector) {
rule.style["content"] = replacementContent;
}
}
}
div:before {
content: "before";
color: red;
font-weight: bold;
text-align: center;
text-shadow: 2px 2px 2px #000;
background: green;
width: 50px;
height: 50px;
display: block;
}
<div></div>

inserting a text box at top of the page

I have been trying this for a lot of time. How can I add a bigger text box on the top of the page ie it would be outside the div tag of the button which would be clicked
https://jsfiddle.net/Lx3rtLx0/2/
For eg on clicking one of the four emerging images it should display
a text box on the top of the page like the one shown below
I want the code given to arrive on the page on clicking one of the images. I.e. when you click on one of the images(jsfiddle) ..a text box(code given) should appear. on different clicks diff content.
#adbox {
width: 800px;
height: 150px;
border-width: 0;
border-color: red;
background-color:grey;
}
#adbox .adbox1 {
width: 200px;
height: 50px;
border-width: 0;
border-color: red;
float:left;
background-color:lightblue;
margin:0px 0px 0px 300px;
}
#adbox .adbox2 {
width: 200px;
height: 50px;
border-width: 0;
border-color: red;
float:right;
background-color:red;
margin:0px 60px 0px 0px;
}
.clear{
clear:both;
}
<!DOCTYPE html>
<html>
<head>
<title>BOX</title>
</head>
<body>
<div align=center><div id="adbox">
<h1><br> xyz sent you a hug</br></h1>
<div class="adbox1">
<br>Send a Hug Back</br>
</div>
<div class="adbox2">
<br>Ack | Dis</br>
</div>
<div class="clear"/>
</div></div>
</body>
</html>
Not super clear on your question, do you need to add an input to the jsfiddle in your question? or the code you have listed in your question? If it is in the jsfiddle, just add this to the top of the code:
<body>
<section id="header">
<div class="inner">
<div>
<input type="text" style="position:absolute; width:300px;" />
</div>
Otherwise, the attribute position:absolute should work out for you, if it isn't in the right place, add attributes like top:0; left:0, and that will put your input in the top left despite anything else in your code.
Simple, on your click button add the code as in https://jsfiddle.net/Lx3rtLx0/6/
var input = document.createElement('input'); // if you want label just change inpput to label
input.type='text';
input.value = 'hugs or whatever';
document.body.insertBefore(input, document.body.firstChild);
So the full JS become
$(document).ready(function() {
$(".trigger").click(function() {
$(".menu").toggleClass("active");
var input = document.createElement('input'); // if you want label just change inpput to label
input.type='text';
input.value = 'hugs or whatever';
document.body.insertBefore(input, document.body.firstChild);
});
});
You can use a data- attribute on your clickable divs to link them with a specific element (a textbox in this case). For example:
<div class="btn btn-icon" title="Send a hug to Mohammed" data-adbox="adbox1">
In the click handler, we can retreive this attribute and show the element with id adbox1.
Full example:
$(document).ready(function() {
$(".trigger").click(function() {
$(".menu").toggleClass("active");
});
$(".btn.btn-icon").click(function() {
$('.adbox').hide();
$('#' + $(this).data('adbox')).show();
});
$('.adbox').click(function() {
$(this).hide();
});
});
html,
body {
height: 100%;
overflow: hidden;
}
.absolute-center,
.menu,
.menu .btn .fa,
.menu .btn.trigger .line {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.menu {
width: 5em;
height: 5em;
}
.menu .btn {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
opacity: 0;
z-index: -10;
cursor: pointer;
-webkit-transition: opacity 1s, z-index 0.3s, -webkit-transform 1s;
transition: opacity 2s, z-index 1s, -webkit-transform 1s;
transition: opacity 2s, z-index 1s, transform 1s;
transition: opacity 2s, z-index 1s, transform 1s, -webkit-transform 1s;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.menu .btn.trigger {
opacity: 1;
z-index: 100;
cursor: pointer;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
content: url("http://i.stack.imgur.com/Yse7Q.jpg");
}
.menu .btn.trigger:hover {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
.menu .rotater {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
}
.menu.active .btn-icon {
opacity: 1;
z-index: 50;
}
.rotater:nth-child(1) {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.menu.active .rotater:nth-child(1) .btn-icon {
-webkit-transform: translateY(-12em) rotate(45deg);
transform: translateY(-12em) rotate(45deg);
background-image: url("http://i.stack.imgur.com/Yse7Q.jpg");
background-size: cover;
align: top;
}
.rotater:nth-child(2) {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.menu.active .rotater:nth-child(2) .btn-icon {
-webkit-transform: translateY(-12em) rotate(-45deg);
transform: translateY(-12em) rotate(-45deg);
background-image: url("http://i.stack.imgur.com/Yse7Q.jpg");
background-size: cover;
align: top;
}
.rotater:nth-child(3) {
-webkit-transform: rotate(135deg);
transform: rotate(135deg);
}
.menu.active .rotater:nth-child(3) .btn-icon {
-webkit-transform: translateY(-12em) rotate(-135deg);
transform: translateY(-12em) rotate(-135deg);
background-image: url("http://i.stack.imgur.com/Yse7Q.jpg");
background-size: cover;
align: top;
}
.rotater:nth-child(4) {
-webkit-transform: rotate(225deg);
transform: rotate(225deg);
}
.menu.active .rotater:nth-child(4) .btn-icon {
-webkit-transform: translateY(-12em) rotate(-225deg);
transform: translateY(-12em) rotate(-225deg);
background-image: url("http://i.stack.imgur.com/Yse7Q.jpg");
background-size: cover;
align: top;
}
.menu.active .rotater:nth-child(4) .btn-icon {
-webkit-transform: translateY(-12em) rotate(-225deg);
transform: translateY(-12em) rotate(-225deg);
background-image: url("http://i.stack.imgur.com/Yse7Q.jpg");
background-size: cover;
align: top;
}
.text-box {
text-align: center;
z-index: 3;
font-size: 18px;
font-weight: 900;
color: white;
padding-top: 30px;
opacity: 0;
-webkit-transition: all 0.5s ease;
/* Safari */
transition: all 0.5s ease;
}
.text-box:hover {
opacity: 1;
}
.adbox {
display: none;
position: absolute;
top: 10px;
width: 120px;
left: 50%;
margin-left: -70px;
background: grey;
padding: 10px;
color: white;
text-align: center;
border-radius: 10px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="header">
<div class="inner">
<div class="menu">
<div class="btn trigger">
<span class="line"></span>
</div>
<div class="icons">
<div class="rotater">
<div class="btn btn-icon" title="Send a hug to Mohammed" data-adbox="adbox1">
<p class="text-box">
Hello
</p>
</div>
</div>
<div class="rotater">
<div class="btn btn-icon" title="Send a kiss to Margaret" data-adbox="adbox2">
<p class="text-box">
This
</p>
</div>
</div>
<div class="rotater">
<div class="btn btn-icon" title="Wish Good Morning to your Family" data-adbox="adbox3">
<p class="text-box">
Doge
</p>
</div>
</div>
<div class="rotater">
<div class="btn btn-icon " title="Express your love" data-adbox="adbox4">
<p class="text-box">
Is
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="adbox" id="adbox1">
<h1>xyz sent you a hug</h1>
</div>
<div class="adbox" id="adbox2">
<h1>Send a Hug Back</h1>
</div>
<div class="adbox" id="adbox3">
<h1>Ack | Dis</h1>
</div>
<div class="adbox" id="adbox4">
</div>

How to draw heart with text in middle?

I found this answer "css: how to draw circle with text in middle?" , but I need the same, but with a heart shape. I found a lot of heart shape figures online, but none of this with text inside. At the same time, I need the heart only with borders, and when click, filled the background.
My code until now:
.heart {
width: 100px;
height: 90px;
font-size: 50px;
color: #fff;
line-height: 100px;
text-align: center;
}
.heart:before,
.heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
<div class="heart">Heart</div>
In order to get text to appear on the heart, you need to set the heart container as relative and the text inside of it as absolute as shown below.
I set the border of the :before and :after to give the heart a border.
The toggling of the fill uses functionality from YouMightNotNeedJQuery.com.
function toggleFill(heart, className) {
if (!hasClass(heart, className)) {
addClass(heart, className);
} else {
removeClass(heart, className);
}
}
function addClass(el, className) {
if (el.classList) {
el.classList.add(className);
} else {
el.className += ' ' + className;
}
}
function removeClass(el, className) {
if (el.classList) {
el.classList.remove(className);
} else {
el.className = el.className.replace(
new RegExp('(^|\\b)' + className.split(' ').join('|') +
'(\\b|$)', 'gi'), ' ');
}
}
function hasClass(el, className) {
if (el.classList) {
return el.classList.contains(className);
} else {
return new RegExp('(^| )' + className +
'( |$)', 'gi').test(el.className);
}
}
.unselectable {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.filled:before,
.filled:after {
background: red !important;
}
#wrapper {
width: 300px;
height: 180px;
background: #444;
}
.heart {
position: relative;
top: calc(50% - 45px); /* 1/2 height of wrapper - 1/2 height of heart */
left: calc(50% - 50px); /* 1/2 width of wrapper - 1/2 width of heart */
width: 100px;
height: 90px;
}
.heart:before,
.heart:after {
position: absolute;
content: "";
top: 0px;
width: 50px;
height: 80px;
background: inherit;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
}
.heart:before {
left: 50px;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
border-left: 2px solid red;
border-top: 2px solid red;
border-bottom: 1px solid red;
}
.heart:after {
left: 0px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
border-right: 2px solid red;
border-top: 2px solid red;
border-bottom: 1px solid red;
}
.heart-text {
position: absolute;
top: 0;
left: calc(50px - 30px); /* 1/2 width of heart - 1/2 width of text */
z-index: 100;
line-height: 66px;
text-align: center;
font-size: 24px;
font-weight: bold;
color: #FFF;
}
<div id="wrapper">
<div class="heart" onclick="toggleFill(this, 'filled')">
<div class="heart-text unselectable">
Heart
</div>
</div>
</div>
A quick search and there is a good article about creating shapes with CSS over # css-tricks.com that can be seen here.
If we take the example of how to create a heart and extend upon it a little we can get the following snippet that gives you a heart that starts out simply as a border;
(function(){
var heart = document.querySelector('#heart');
heart.addEventListener('click', function(e) {
this.className += ' is--filled'
});
}());
#heart {
position: relative;
width: 100px;
height: 90px;
text-align: center;
font-size: 16px;
position: relative;
}
#heart span {
width: 100%;
display: block;
top: 50%;
margin-top: -16px;
line-height: 16px;
left: 0;
right: 0;
position: absolute;
z-index: 1;
}
#heart.is--filled:before,
#heart.is--filled:after {
background-color: red;
}
#heart:before,
#heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
border: 1px solid red;
transition: background-color .25s ease 0s;
-webkit-transition: background-color .25s ease 0s;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
#heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin :100% 100%;
}
#heart:before {
border-right: none;
border-bottom: none;
}
#heart:after {
border-left: none;
border-bottom: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id='heart'>
<span>Hey</span>
</div>
</body>
</html>
However, as someone else has mentioned in the comments it may be an easier approach to use images or the canvas element. I say this purely because it may prove difficult to get just the heart border you desire before clicking the heart (easier to see if you run the snippet). You could opt for much softer opaque background color before you click and then transition to red maybe?
Hope this helps you out!
Use pseudo elements of css3.
.text {
position: absolute;
color: #eee;
z-index: 99;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
}
#heart {
position: relative;
width: 100px;
height: 90px;
}
#heart:before,
#heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
#heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
<div id="heart">
<div class="text">ABC</div>
</div>
Use this
HTML
$('#change').click(function() {
var className = $(this).attr('class');
if(className == "heart"){
$(this).removeClass('heart');
$(this).addClass('heart1');
}
else{
$(this).removeClass('heart1');
$(this).addClass('heart');
}
});
.txt{
z-index:1;
font-size: 20px;
color: #000;
position:relative;
text-align:center;
top:15px;
right:5px;
}
.heart {
width: 100px;
height: 90px;
}
.heart1 {
width: 100px;
height: 90px;
}
.heart:before,
.heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: yellow;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.heart1:before,
.heart1:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.heart1:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
.heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="change" class="heart"><div class="txt">Heart</div></div>

Categories