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>
Related
I have text that scrolls horizontally in a marquee style effect. This works great.
In addition to this I have a 'toggle' that when clicked adds the class .dark-mode to the html tag which basically inverts all the colours. So by default it's white page, black text. When toggled, black page, white text.
This works perfectly on my desktop browser. However I've noticed on iOS Safari and Chrome the text within the CSS Animation does not update with the rest of the copy. I haven't been able to test if that's the case on Android as well.
I've included the code for this but also put it on a CodePen here incase it's easier to view for people: https://codepen.io/moy/pen/eYjryXN
What's additional strange, if I scroll down the page then back up the text DOES change colour? Which indicates to me maybe once the animation is running, it leaving the viewport and re-entering somehow renders it again and corrects the colour?
I thought adding:
document.querySelector(‘.marquee’).offsetWidth;
Might force a 'reflow' of the page but it didn't do anything. Really appreciate some help on this. Strange one!
const html = document.querySelector('html');
const button = document.querySelector('.contrast__link');
button.addEventListener('click', e => {
e.preventDefault();
html.classList.toggle('dark-mode');
});
:root {
--color-primary: black;
--color-secondary: white;
--spacing: 24px;
}
.dark-mode {
--color-primary: white;
--color-secondary: black;
}
body {
background: var(--color-secondary);
color: var(--color-primary);
margin: 0 auto;
padding: 48px 24px;
max-width: 800px;
}
.marquee {
margin: 0 calc(var(--spacing) * -1);
margin-bottom: 120px;
}
.marquee h1 {
display: flex;
flex: 1 1 auto;
flex-wrap: nowrap;
overflow: hidden;
}
.marquee span {
-webkit-animation: 8s linear infinite 0s forwards running marquee;
animation: 8s linear infinite 0s forwards running marquee;
box-sizing: border-box;
flex: 1 0 50%;
padding: 0 var(--spacing);
white-space: nowrap;
text-align: center;
}
/**
* The looping animation for the marquee.
*/
#-webkit-keyframes marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
#keyframes marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
<div class="grid__item">
<div class="hgroup">
<div class="marquee">
<h1 class="page-title">
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
<span>Hello... is it me you're looking 404?</span>
</h1>
</div>
</div>
<p class="contrast">Toggle Here</p>
</div>
I am trying to get the text decoration to appear from left to right, as if it is being crossed out with a pen.
Is there a way to do this without making changes to the text behind it?
Thanks in advance!
document.querySelector('h1').addEventListener('click', (e) => {
e.target.classList.toggle('strikethrough')
})
.strikethrough {
text-decoration: line-through;
text-decoration-style: wavy;
text-decoration-thickness: 15%;
animation: strike 3s linear;
}
#keyframes strike {
0% {width: 0;}
100% {width: 100%;}
}
<h1>CROSS ME OUT</h1>
If you are willing to accept using a straight line as the strike through (instead of depending on the font's own strikethrough styles), then it is just a matter of overlaying a div on top of the <h1> element and offsetting it 100% to the side using transform: translateX(-100%). We give it a top border whose width is font-size dependent (i.e. use em units), and a color whose value is dependent on the current font color (i.e. use currentColor).
You can use CSS transitions set the duration and easing function of the entry of this line. When the .strikethrough class is added, the offset is simply set to transform: translateX(0).
A caveat is that this trick only works for non-breaking lines. If your h1 element will render across multiple lines, then it wouldn’t work.
See proof-of-concept example below:
document.querySelector('h1').addEventListener('click', (e) => {
e.target.classList.toggle('strikethrough')
});
h1 {
display: inline-block;
position: relative;
overflow: hidden;
}
h1::after {
position: absolute;
top: calc(50% - 0.05em);
left: 0;
width: 100%;
content: '';
display: block;
border-top: 0.1em solid currentColor;
transform: translateX(-100%);
transition: transform .25s ease-in-out;
}
h1.strikethrough::after {
transform: translateX(0);
}
<h1>CROSS ME OUT</h1>
I am working on slide animation for text in container infinitely.
However, I found it not working smoothly. When the text reaches the end, it seems like restarting instead of looping the text.
What I want is the text keep sliding to the right continuously.
How to solve it?
App.js
import "./styles.css";
export default function App() {
return (
<div className="App">
<div class="slide-right">
<h2>
<span>A</span>
<span>A</span>
<span>A</span>
<span>A</span>
<span>A</span>
<span>A</span>
</h2>
</div>
</div>
);
}
Styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.slide-right {
border: 1px solid grey;
width: 150px;
overflow: hidden;
}
.slide-right h2 {
animation: infinite slide-right 2s linear;
transform: translateX(-100%);
text-align: right;
}
.slide-right h2 span {
margin-right: 10px;
}
#keyframes slide-right {
to {
transform: translateX(0);
}
}
Codesandbox:
https://codesandbox.io/s/hidden-bird-qy3jy?file=/src/styles.css
Change your "slide-right" keyframes from transform: translateX(0); to transform: translateX(100%);
To get a continuous flow this snippet has two copies of the spans.
Initially the h2 is translated -50% so only the beginning of the second half is showing.
The animation moves it to the right so it ends up with the beginning of the first half showing.
Then on the repeat the beginning of the second half takes the place of the beginning of the first half, so it all looks continuous.
.App {
font-family: sans-serif;
text-align: center;
}
.slide-right {
border: 1px solid grey;
width: 150px;
overflow: hidden;
}
.slide-right h2 {
animation: infinite slide-right 2s linear;
transform: translateX(-50%);
display: inline-block;
}
.slide-right h2 span {
margin-right: 10px;
}
#keyframes slide-right {
to {
transform: translateX(0);
}
}
<div class="App"><div class="slide-right"><h2><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span><span>A</span></h2></div></div>
Note: to avoid problems with wrapping of text the spans are laid out continuously (as in the codesandbox in the question).
#keyframes slide-right {
to {
transform: translateX(100%);
}
}
Use this instead of translateX(0)
Double the number of A to make the effect continuous.
I have an odd issue with the JavaScript code I wrote. I am currently up to 1009 lines of code, so I would love to know where to start to fix this issue.
I am using getelementid to display to HTML from an external JS file, then using CSS to animate the JS client side.
display("<p>Welcome to TextHacker, a text based hacking simulation game</p>");
the code works but it only prints out up "Welcome to TextHacker, a text based hacking simulat" then stops in the browser. I have the same issue in Chrome, Firefox, Opera, and Valadi, so I'm not sure what I am doing wrong.
Here is the CSS code:
p {
color: lime;
font-family: "Courier";
font-size: 20px;
margin: 10px 0 0 10px;
white-space: nowrap;
overflow: hidden;
width: 30em;
animation: type 4s steps(60, end);
}
p:nth-child(2){
animation: type2 8s steps(60, end);
}
p a {
color: lime;
text-decoration: none;
}
span{
animation: blink 1s infinite;
}
#keyframes type {
from { width: 0; }
}
#keyframes type2 {
0%{width: 0;}
50%{width: 0;}
100%{ width: 100; }
}
#keyframes blink {
to{opacity: .0;}
}
::selection {
background: black;
}
Your width is cutting off the text.
p {
width: 60em;
}
https://jsfiddle.net/08y8yknn/
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/