The easiest way to change text with flip effect - javascript

I am looking for simple way to flip text.
For example I have currently "Hello" text in tag, and I need to flip it to "world", only once , I don't need to flip it back to "Hello", even if sometimes need I don't really need to save previous state. Just pass new text string and it should flip older to newer one.
I know that there are a lot of libraries like https://github.com/daynin/wodry , but for this I need to provide span inside it with specific style, and hardcode all possible flip text strings. I don't need specific part of the text, I need to flip it all at once.
Please suggest the best way to implement this.

Without using span, here is an example of what you are trying to achieve
- from Hello to word, without going back ( you can adjust it later to your needs: height, colour, width and the other attributes)
HTML:
<div class="flip">
<div class="item">
<div class="face front">Hello</div>
<div class="face back">word</div>
</div>
</div>
CSS:
.flip {
-webkit-perspective: 300;
width: 400px;
height: 200px;
}
.flip .item.flipped {
-webkit-transform: rotatex(-180deg);
}
.flip .item {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
}
.flip .item .face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden ;
z-index: 2;
text-align: center;
line-height: 200px;
}
.flip .item .front {
position: absolute;
z-index: 1;
background: black;
color: white;
cursor: pointer;
}
.flip .item .back {
-webkit-transform: rotatex(-180deg);
background-color: green;
color: black;
}
and a little JS to make it functional:
$('.flip').click(function () {
$(this).find('.item').addClass('flipped');
});
fiddle url: http://jsfiddle.net/GDdtS/9909/

Related

Is there a way I could trigger some effects similar to zoom effect, but doesn't change the image width and height?

I am creating a photo gallery.
let img = document.createElement('img')
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Wikipedia_logo_%28svg%29.svg/1250px-Wikipedia_logo_%28svg%29.svg.png"
// console.log(alldata[i].links[0].href)
let border = document.createElement('div')
border.appendChild(img)
border.className = 'gallery'
document.body.appendChild(border)
:root {
--wid: 300px;
}
.gallery{
background: grey;
width: var(--wid);
}
img{
height: 250px;
width: var(--wid);
}
img:hover {
transform: scale(1.5);
}
I want to trigger an effect where when user hover over the img, it will become bigger but keep the same width. I have tried to use transform: scale(1.5); or zoom:150%. Both of them work find, but they will make the width and height image become bigger.
Is there a way I could trigger the effect similar to zoom, but doesn't change the image width and height?
This is a photo gallery website where show the similar effect I want to make (when user hover the img, the img will zoom in a little bit like about 110%)
Thanks for any responds!
It is rather straightforward: you simply need to set .gallery to hide overflowing content, and then add a simple CSS transition to the img element.
p/s: You might want to use object-fit to ensure you don't end up skewing the aspect ratio of the image.
:root {
--wid: 300px;
}
.gallery {
background: grey;
width: var(--wid);
overflow: hidden;
}
img {
display: block;
height: 250px;
width: var(--wid);
transition: all .25s ease-in-out;
/* Optional: to avoid skewing of aspect ratio */
object-fit: contain;
}
img:hover {
transform: scale(1.5);
}
<div class="gallery">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Wikipedia_logo_%28svg%29.svg/1250px-Wikipedia_logo_%28svg%29.svg.png" />
</div>
:root {
--wid: 300px;
}
.gallery {
background: grey;
width: var(--wid);
overflow: hidden;
}
img {
display: flex;
height: 250px;
width: var(--wid);
transition: all .50s ease-in-out;
/* Optional: to avoid skewing of aspect ratio */
object-fit: contain;
}
img:hover {
transform: scale(2);
}
<div class="gallery">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Wikipedia_logo_%28svg%29.svg/1250px-Wikipedia_logo_%28svg%29.svg.png" />
</div>

HTML - Second IMG hover issue

I have 2 semicircles stuck next to each other forming a circle. When I hover on the left semicircle, the right one lowers it's opacity (which is what is supposed to do) but when I hover on the right one, the opacity doesn't change at all.
HTML:
<div id="animation-components">
<img src="leftball.svg" alt="" class="animation-item-01">
<img src="rightball.svg" alt="" class="animation-item-02">
</div>
CSS:
#animation-components {}
.animation-item-01 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-02 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-01:hover + .animation-item-02{
opacity: 50%;
}
.animation-item-02:hover + .animation-item-01{
opacity: 50%;
}
What can I alter to make this work?
The issue is that you can only select the next sibling with the adjacent sibling selector.
.element-1 + .element-2 /* good */
.element-2 + .element-1 /* not so good */
Since .animation-item-02 comes after .animation-item-01, there is no way to select the previous .animation-item-01 from .animation-item-02
Doing the following will fix the issue:
#animation-components:hover > div {
opacity: 50%;
}
#animation-components > div:hover {
opacity: 100%;
}
CSS Combinators can't be used to apply styles to elements before target element.
The adjacent sibling selector (+) will aply to all adjacent elements, not to it's opposite elements.
CSS It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
To achieve the desired, you can do the folowwing:
#animation-components:hover img {
opacity: .5;
}
#animation-components img:hover{
opacity: 1;
}
<div id="animation-components">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-01">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-02">
</div>
It might just be me but I find it heaps easier to throw in just a little bit of javascript and avoid messy css combinators. Heres my fix, script goes anywhere in your html file, I put it after the closing body tag.
<script>
function fadeOut(obj) {
document.getElementById(obj).style.animationName = "fadeOut";
}
function fadeIn(obj) {
document.getElementById(obj).style.animationName = "fadeIn";
}
</script>
#item1 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#item2 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes fadeOut {
0%{opacity: 1;}
100%{opacity: 0.5;}
}
#keyframes fadeIn {
0%{opacity: 0.5;}
100%{opacity: 1;}
}
<div id="animation-components">
<img src="leftball.svg" alt="" id="item1" onmouseover="fadeOut('item1')" onmouseout="fadeIn('item1')">
<img src="rightball.svg" alt="" id="item2" onmouseover="fadeOut('item2')" onmouseout="fadeIn('item2')">
</div>
Also its just a me thing, but you have class attributes where id attributes should be. If your applying seperate styles to two completely seperate elements its a good idea to use id, but if your applying same style to two elements

Wrap dynamic text around a spinning cylinder with CSS/Javascript (splitting.js)

I am fairly new to coding and don't have the in-depth knowledge to solve this problem on my own. I would be really grateful if somebody could help me out!
I am trying to wrap a dynamically loaded text without a fixed number of characters around a spinning cylinder using CSS and splitting.js. I tried following this tutorial and everything worked great until I started changing the text. The problem is that this method only works with text that doesn't change in length because it either gets cut off if the text is too long or a gap in the cylinder results if it is too short.
Here is the source code I have right now. Sadly it doesn't work properly when I paste it in jsfiddle. It does however work just fine in my code editor and is the same as in the tutorial I linked above.
<div class="circle" data-splitting>
Circle-Text-Animation-Effect-Cool-great
</div>
<script>
Splitting();
</script>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color:aqua;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
.circle .char {
position: absolute;
top: 0;
left: 0;
background: red;
color: blue;
font-size: 4em;
padding: 5px 12px;
border: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * 10deg)) translateZ(250px);
}
Is there any workaround for this problem? Maybe even without using splitting.js?
I hope I could describe my problem properly. English isn't my first language and I can't upload images to Stackoverflow yet so I wasn't able to describe the problem visually!
Thank you in advance for your help!
enter image description here
The trick here is to note that the number of degrees you need to rotate a character depends on the total number of characters in the string.
I don't have the splitter.js library so have put in a bit of JS which does the same thing - separates each character into its own div with a style that defines a CSS variable - the index of the character.
The JS also sets a new CSS variable, --numchs, which is used in the CSS to calculate the number of degrees to rotate each character, --deg. This is then used instead of the 10deg to decide where to place a character.
const circle = document.querySelector('.circle');
const text = circle.innerHTML;// Note I am being lazy here and assuming the string has no unwanted whitespace
circle.innerHTML = '';
circle.style.setProperty('--numchs', text.length);
for ( let i = 0; i < text.length; i++ ) {
circle.innerHTML = circle.innerHTML + '<div class="char" style="--char-index: ' + i + ';">' + text.charAt(i) + '</div>';
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color:aqua;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
--deg: calc(360deg / var(--numchs));
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
.circle .char {
position: absolute;
top: 0;
left: 0;
background: red;
color: blue;
font-size: 4em;
padding: 5px 12px;
border: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * var(--deg))) translateZ(250px);
}
<div class="circle" data-splitting>Circle-Text-Animation-Effect-Cool-great</div>

CSS - Toggle Multiple 3d Animations

I'm trying to have two 3d cards that trigger a flip with a toggle button. The problem is only the first cards button currently toggle's the 3d flipping animation, whereas the second cards button doesn't.
I'm following this tutorial, but he currently only uses one https://3dtransforms.desandro.com/card-flip
let flip = document.querySelector('.flip');
let card = document.querySelector('.card');
flip.addEventListener('click', function() {
card.classList.toggle('is-flipped');
});
/*The 3d Area Boundary*/
.container {
box-sizing: border-box;
width: 100%;
height: 170px;
padding: 0;
perspective: 800px;
}
/*The 3d Object - Flipping Card */
.card {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transform-origin: center right;
transition: transform 1s;
}
/*Sets Card face 2d, absolute and invisible
when until flipped*/
.card-face {
position: absolute;
height: 100%;
width: 100%;
backface-visibility: hidden;
}
.front-card {}
.back-card {
transform: rotateY(180deg);
}
.card.is-flipped {
transform: rotateY(180deg);
transform: translateX(-100%) rotateY(-180deg);
}
<div class="container">
<div class="card">
<div class="card-face front-card">
<p>Some Text.</p>
<a class="uk-button uk-button-default" class="flip">Flip</a>
</div>
<div class="card-face back-card">
<p>Some MORE TEXT.</p>
<a class="uk-button uk-button-default" class="flip">Flip</a>
</div>
</div>
</div>
The problem is only the first cards button currently toggle's the 3d flipping animation, whereas the second cards button doesn't
No, your code is throwing the following error:
Uncaught TypeError: Cannot read property 'addEventListener' of null
Having same attribute multiple times in an elements (class in a element) will simply ignored all the attributes except the first one.
querySelector() returns only the first matched element. You have to target all the elements with class, you can do so using querySelectorAll(). Then loop through them to attach the event to all of them.
let flip = document.querySelectorAll('.flip');
let card = document.querySelector('.card');
flip.forEach(function(el){
el.addEventListener('click', function() {
card.classList.toggle('is-flipped');
});
});
/*The 3d Area Boundary*/
.container {
box-sizing: border-box;
width: 100%;
height: 170px;
padding: 0;
perspective: 800px;
}
/*The 3d Object - Flipping Card */
.card {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transform-origin: center right;
transition: transform 1s;
}
/*Sets Card face 2d, absolute and invisible
when until flipped*/
.card-face {
position: absolute;
height: 100%;
width: 100%;
backface-visibility: hidden;
}
.front-card {}
.back-card {
transform: rotateY(180deg);
}
.card.is-flipped {
transform: rotateY(180deg);
transform: translateX(-100%) rotateY(-180deg);
}
<div class="container">
<div class="card">
<div class="card-face front-card">
<p>Some Text.</p>
<a class="uk-button uk-button-default flip">Flip</a>
</div>
<div class="card-face back-card">
<p>Some MORE TEXT.</p>
<a class="uk-button uk-button-default flip" >Flip</a>
</div>
</div>
</div>

Flip Menu with Fixed Top Menu

I have a doubt.
I need to implement a flip menu, but on the internet I found only examples using css transformations, and vendors prefix. But all examples show divs that are not fixed, and the css below have a fixed menu (copied and pasted code and reduce the net, is not very pretty) and when I have a menu and the approaches of put font and back divs don't work.
I need help with this. I need a way in which whole site (including the set menu) are replaced with other content (as a great turning of the page).
Example: http://davidwalsh.name/css-flip
I need a horizontal flip, and right horizontal flip.
Thank you so much.
CodePen: http://codepen.io/anon/pen/BuHql
HTML:
<div class="nav">
<ul>
<li>Home</li>
<li>CSS</li>
<li>PHP</li>
<li>SEO</li>
<li>jQuery</li>
<li>Wordpress</li>
<li>Services</li>
</ul>
<div class="clear"></div>
</div>
</div>
CSS:
body { height: 800px; background: black; }
.nav{ background: white; z-index: 9999; position: fixed; left: 0; top: 0; width: 100%;}
.nav { height: 42px; background: white;}
.nav ul { list-style: none; }
.nav ul li{float: left; margin-top: 6px; padding: 6px; border-right: 1px solid #ACACAC;}
.nav ul li:first-child{ padding-left: 0;}
.nav ul li a { }
.nav ul li a:hover{ text-decoration: underline;}
An easy way to do this, in otherwise case, is using the following construction:
HTML:
<div class="flipper">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>
CSS:
/*Placing colors to facilitate understanding.*/
.front { background: green; }
.back { background: red; }
/*Add this class to a ".flipper" element using the way that is well to you (using a click, a hover or any other trigger).*/
.flip {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
/*Add others vendors styles to more compatibility*/
}
/*Configuring the duration and the 3d mode of command*/
.flipper {
position: relative; /*relative is very important*/
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: 2s;
-webkit-transition: 0.6s;
}
/*Required for no appear both at the same time*/
.front {
z-index: 2;
}
/*Causes the back start hidden (it is rotated 180 degrees, so it will not appear)*/
.back {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
/*Hide the rear face during the flip.*/
.front, .back {
position: relative; /*Again, the relative position is very important to work on any layout without crash.*/
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
/*needed for webkit browsers understand what's in front and what is behind*/
body {
perspective: 1000;
-webkit-perspective: 1000;
}
JS (jQuery) use example:
$('body').hover(function () {
$('.flipper').addClass('flip');
});
$('body').click(function () {
$('.flipper').removeClass('flip');
});
There is a simple jquery plugin that can help you achieving this effect.
You can find it here:
http://guilhemmarty.com/flippy//
It is easy to use and you can choose what kind of flip you want. ;)

Categories