CircleType text remove whitespace after rotateY - javascript

I'm having this code:
<div id="curvy">
This is the curved text
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/circletype#2.2.0/dist/circletype.min.js"></script>
<script>
const circleType = new CircleType(document.getElementById('curvy'));
circleType.dir(-1).radius(1100);
$( document ).ready(function() {
var counter = 1;
var deg = -40;
$($($('#curvy div').find('span')).get().reverse()).each(function (index, value ) {
/* var css = $(this).css('transform');
css = css + ' rotateY(-50deg)'; */
if(counter > 5) {
var text = $(this).html();
$(this).html('');
$(this).css('display','flex');
$(this).css('vertical-align','top');
console.log(text);
//$(this).html('');
var newElem = $('<span></span>').append(text);
newElem.appendTo($(this));
/* newElem.css('position','relative');
newElem.css('z-index',counter); */
newElem.css('vertical-align','top');
newElem.css('transform','rotateY('+ deg +'deg)');
deg = deg - 2.5;
}
//console.log(value);
counter = counter + 1;
});
});
</script>
<style>
html, body {
font-size: 30px;
}
</style>
This is working fine but after I start rotating each letter using rotateY in its own span, the parent span seems to add a white space in between that I want to get rid of.
Check jsfiddle

Well I was approaching it totally incorrectly.
The issue wasnt the spans, the padding or any margins but the translateX or rotate value.
Since CircleType was using the initial size of the letter when rendering the effect, the manipulations that I did through jQuery later weren't taken into account by it.
I had to save the matrix and then decide if I would go for an increment on the rotate value or on the translateX value. I chose the latter because it felt less complicated to play with. Since I need that the rotation will begin after a specific amount of character, I use the appropriate checks.
<div id="curvy">
Curved text
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/circletype#2.2.0/dist/circletype.min.js"></script>
<script>
const circleType = new CircleType(document.getElementById('curvy'));
circleType.dir(-1).radius(900);
$( document ).ready(function() {
var counter = 1;
var deg = -40;
var padding = 0;
$($($('#curvy div').find('span')).get().reverse()).each(function (index, value ) {
var css = $(this).css('transform').replace(/[^0-9\-.,]/g, '').split(',');
var x = css[12] || css[4];
var y = css[13] || css[5];
var a = css[0];
var b = css[1];
var angle = Math.atan2(b, a) * (180/Math.PI);
if(counter > 5) {
if(counter >= 12) {
padding = padding + 6 ;
} else
padding = padding + 4 ;
var text = $(this).html();
$(this).html('');
$(this).css('display','flex');
x = parseFloat(x) + padding;
$(this).css('transform', 'translateX('+x+'px) rotate('+angle+'deg)');
var newElem = $('<span></span>').append(text);
newElem.appendTo($(this));
newElem.css('transform','rotateY('+ deg +'deg)');
deg = deg - 2.5;
}
counter = counter + 1;
});
});
</script>
<style>
html, body {
font-size: 30px;
top: 50%;
left: 50%;
position: absolute;
}
</style>
Updated jsFiddle

Related

change css class property increment

I have a small question!
I'am trying to change css width property using JavaScript like this:
document.getElementById("progressvalue").style.width = "80%";
.progress {
width: 100%;
max-width: 500px;
border: 3px solid black;
height: 20px;
padding: 1px;
}
#progressvalue {
height: 100%;
width: 0%;
background-color: #05e35e;
}
<div class="progress">
<div id="progressvalue"></div>
</div>
But instead of 80% in JavaScript code, I want to increase the width value by 20%.
Like (width = width + 20%)
I want to apply this changing once (So I can use it mutiple times using other conditions), and this is why I need it like this (width = width + 20%)
You can try to read the element's style.width property, by keeping only the numeric part of it and adding it to your step (eg 20%).
const step = 5;
const updateProgress = () => {
const currentWidth = Number(document.getElementById("progressvalue").style.width.replace( "%", ""));
if (currentWidth>=100) {
return;
}
else {
document.getElementById("progressvalue").style.width = `${currentWidth+step}%`;
}
}
You can check this out in this CodePen.
I guess you want to do some animation right ? If so you can use recursivity with setTimeout:
function progress(val) {
val += 20;
document.getElementById("progressvalue").style.width = val + "%";
if (val < 100) // To stop the loop when progress bar is full
setTimeout(function () {
progress(val);
}, 1000)
}
progress(0); // Start the animation
This will increase by 20% every 0.5 seconds.
let percent = 0;
setInterval(() =>
{
if(percent > 100) {
clearInterval();
return;
}
document.getElementById("progressvalue").style.width = percent + "%";
percent += 20;
}, 500);
You can use this:
var el = document.getElementById("progressvalue");
var elementWidth = el.style.width;
var newWidth = `${20+parseInt(elementWidth.substring(0, elementWidth.length-1))}%`
el.style.width=newWidth;
Assuming that you have set the width of the element initially to a percent value.
<button type="button" id="myBtn" onclick="myFunction()">Change the width</button>
<script>
function myFunction() {
let progress = document.getElementById("progressvalue");
let style = window.getComputedStyle(progress, null).getPropertyValue('width');
let currentSize = parseFloat(style);
progress.style.width = (currentSize + 20) + '%';
}
</script>
You can try it
//offsetWidth : returns the width of the element
var element_width=document.getElementById("progressvalue").offsetWidth
document.getElementById("progressvalue").style.width =element_width + (20*element_width/100) +'px' ;
You need to get the current width of <div id="progressvalue"></div>, put it in a variable and add 20 and reassign that value to <div id="progressvalue"></div>.

OnClick function to rotate a div element

I am new to Javascript. I am writing a code where I am trying to rotate a square with every click. I was able to do it by clicking the square div element itself. But I wanna rotate the element using the button only. I am stuck with this. Where am I going wrong?
var count=0;
function rot(e){
count++;
var deg = count * 30;
e.style.transform = "rotate("+deg+"deg)";}
function rotat(){
count++;
var deg = count * 30;
this.style.transform = "rotate("+deg+"deg)";
}
.rectangle{
position: relative;
margin: 60mm;
width:90mm;
height:90mm;
border:5px solid #24ddff;
}
<div class = "rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
<p id="demo"></p>
select div element . and use it in rotate function
var count=0;
const div = document.querySelector('div')
function rotat(){
count++;
var deg = count * 30;
div.style.transform = "rotate("+deg+"deg)";
}
.rectangle{
position: relative;
margin: 60px;
width:90px;
height:90px;
border:5px solid #24ddff;
}
<button onclick="rotat()">Rotate</button>
<div class = "rectangle"></div>
You should add id attribute to rectangle element that help you to recognize it within Javascript by getElementById
var count = 0;
function rot(e) {
count++;
var deg = count * 30;
e.style.transform = "rotate(" + deg + "deg)";
}
function rotat() {
const rectangle = document.getElementById("rectangle") //find rectangle element by id
count++;
var deg = count * 30;
rectangle.style.transform = "rotate(" + deg + "deg)";
}
.rectangle {
position: relative;
margin: 60mm;
width: 90mm;
height: 90mm;
border: 5px solid #24ddff;
}
<div class="rectangle" id="rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
Or you can use class="rectangle" and find it by querySelector, but this way is not 100% safe because you may have multiple elements having rectangle class
var count = 0;
function rot(e) {
count++;
var deg = count * 30;
e.style.transform = "rotate(" + deg + "deg)";
}
function rotat() {
const rectangle = document.querySelector(".rectangle") //find rectangle element by id
count++;
var deg = count * 30;
rectangle.style.transform = "rotate(" + deg + "deg)";
}
.rectangle {
position: relative;
margin: 60mm;
width: 90mm;
height: 90mm;
border: 5px solid #24ddff;
}
<div class="rectangle" id="rectangle" onclick="rot(this)"></div>
<button onclick="rotat()">Rotate</button>
For some reasons "transform" did not work properly.
Try to use ".webkitTransform" instead ".transform".
Tip 2: Also try to bind the element by ID, not with Event.
Here some example:
<script type="text/javascript">
var rotatingDiv = document.getElementById("rotatingDiv");
rotatingDiv.style.webkitTransform = "rotate(-1.6deg)";
function transform()
{
var x=document.getElementById("element1");
rotatingDiv.style.webkitTransform = "rotate("+x.value+"deg)";
}
</script>

Reduce font-size based on number of div lines

As the title says, I wanted the font to be reduced based on the number of lines in the div and from a start size. (Each line reduces the font).
The function below is all I have and works based on the height of the div.
$.fn.resizeText = function (options) {
var settings = $.extend({ maxfont: 40, minfont: 17 }, options);
var style = $('<style>').html('.nodelays ' +
'{ ' +
'-moz-transition: none !important; ' +
'-webkit-transition: none !important;' +
'-o-transition: none !important; ' +
'transition: none !important;' +
'}');
function shrink(el, fontsize, minfontsize)
{
if (fontsize < minfontsize) return;
el.style.fontSize = fontsize + 'px';
if (el.scrollHeight > el.closest(".container").offsetHeight) shrink(el, fontsize - 1, minfontsize);
}
$('head').append(style);
$(this).each(function(index, el)
{
var element = $(el);
element.addClass('nodelays');
shrink(el, settings.maxfont, settings.minfont);
element.removeClass('nodelays');
});
style.remove();
}
The size you are looking for is relative to the font family, because it is not always the same number of lines if they are tested with different fonts in the same text. using the following solution:
How can I count text lines inside an DOM element? Can I?
This is an approximate solution, taking into account a maximum number of lines
<body>
<div id="content" style="width: 80px; font-size: 20px; line-height: 20px; visibility: hidden;">
hello how are you? hello how are you? hello how are you? hello how are you? how are you? how are you? how are you?
</div>
<script>
function countLines(elm) {
var el = document.getElementById(elm);
var divHeight = el.offsetHeight;
var lineHeight = parseInt(el.style.lineHeight);
var lines = divHeight / lineHeight;
return lines;
}
var max_lines = 10;
function auto_size_text(elm) {
var el = document.getElementById(elm);
var lines = countLines(elm);
var size = parseInt(el.style.fontSize.replace("px", ""));
if(lines > max_lines) {
size--;
el.style.fontSize = size + "px";
el.style.lineHeight = size + "px";
auto_size_text(elm);
}
}
function show_div (elm) {
var el = document.getElementById(elm);
el.style.visibility = "";
}
auto_size_text("content");
show_div("content");
</script>
</body>

random position of images

i found a script that would position divs / images randomly. However, it isn't completely working the way i want/need it to.
The images are loaded each within a div (which isn't ideal i guess). I have around 30 images.
But they don't load nicely and var posy = (Math.random() * ($(document).height() - 0)).toFixed(); doesn't work nicely either. The images mostly load on top (i think that the images in the blog don't count so it gets the height without images?)
So what I want: Load the in more nicely Randomize them so they get to the bottom of the page, too
var circlePosition = document.getElementsByClassName('circle');
console.log(circlePosition);
function position() {
for (var i = 0; i < circlePosition.length; i++ ) {
//give circle a random position
var posx = (Math.random() * ($(document).width() - 0)).toFixed();
var posy = (Math.random() * ($(document).height() - 0)).toFixed();
//apply position to circle
$(circlePosition[i]).css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
})
}
} //end function position
var circleTotal = circlePosition.length;
$('.circle').click(function() {
$(this).fadeOut();
circleTotal = circleTotal - 1;
console.log(circleTotal);
if(circleTotal == 0) {
position()
$('.circle').fadeIn();
}
});
position();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="//placehold.it/1x5000"> <!-- Placeholder image to show issue -->
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
A clean and readable and solution without a jQuery dependence might be something like this. It avoids unnecessarily wrapping your images in divs by positioning the images themselves. It includes a hidden element as a sort of "poor man's" shadow DOM.
http://jsfiddle.net/sean9999/yv9otwr7/9/
;(function(window,document,undefined){
"use strict";
var init = function(){
var canvas = document.querySelector('#x');
var icon_template = document.querySelector('#template');
var icon_width = 40;
var icon_height = 30;
var the_images = [
'http://static.tumblr.com/tensqk8/k8anq0438/01.png',
'http://static.tumblr.com/tensqk8/rYanq05el/04.png',
'http://static.tumblr.com/tensqk8/SYknq05py/05.png',
'http://static.tumblr.com/tensqk8/s7inq057d/03.png'
];
var pickRandomImage = function(){
var i = Math.floor( Math.random() * the_images.length );
return the_images[i];
};
var total_number_of_images = 10;
var max_height = canvas.offsetHeight - icon_height;
var max_width = canvas.offsetWidth - icon_width;
var randomCoordinate = function(){
var r = [];
var x = Math.floor( Math.random() * max_width );
var y = Math.floor( Math.random() * max_height );
r = [x,y];
return r;
};
var createImage = function(){
var node = icon_template.cloneNode(true);
var xy = randomCoordinate();
node.removeAttribute('id');
node.removeAttribute('hidden');
node.style.top = xy[1] + 'px';
node.style.left = xy[0] + 'px';
node.setAttribute('src',pickRandomImage());
canvas.appendChild(node);
};
for (var i=0;i<total_number_of_images;i++){
createImage();
};
};
window.addEventListener('load',init);
})(window,document);
body {
background-color: #fed;
}
#x {
border: 3px solid gray;
background-color: white;
height: 400px;
position: relative;
}
#x .icon {
position: absolute;
z-index: 2;
}
<h1>Randomly distributed images</h1>
<div id="x"></div>
<img src="#" class="icon" hidden="hidden" id="template" />
try moving your position(); call inside the $(window).load function.
I think maybe the images are being positioned before all the images have loaded, so the page is shorter then.

Making a 'div' go in a circle

I am working on a bit of code to have a dot circle around your cursor on a webpage, but I am having trouble getting the 'div' to follow the path I want; in fact, the object is not moving at all and I cannot figure out why my code does not work. Here is the code that is causing me trouble from what I've narrowed down:
<!DOCTYPE HTML>
<head>
<title>TEST SPACE</title>
<script src="jquery-1.10.2.min.js"></script>
</head>
<body>
<div id="test"></div>
<style>
#test {
background-color: black;
height: 10px;
width: 10px;
border-radius: 100%;
position: absolute;
top: 50%;
left: 50%;
}
</style>
<script>
const omega = Math.PI / 2000;
function dotRotation() {
var time = 0;
var x = 20*(Math.sin(omega*time));
var y = 20*(Math.cos(omega*time));
document.getElementById("test").style.marginLeft = x;
document.getElementById("test").style.marginTop = y;
time += 25;
};
$(document).ready(function() {
setInterval('dotRotation()',25);
});
</script>
</body>
JSFiddle
Two things are wrong
You need to move your time variable outside of the function
You need to give a unit to the value you pass to the margins so add +'px' after the variables .marginTop = y + 'px';
So altogether
const omega = Math.PI / 2000;
var time = 0;
function dotRotation() {
var x = 20*(Math.sin(omega*time));
var y = 20*(Math.cos(omega*time));
var style = document.getElementById("test").style;
style.marginLeft = x +'px';
style.marginTop = y +'px';
time += 25;
};
Demo at http://jsfiddle.net/mWC63/
Also you can cache references to the dom to avoid the searching
Your fiddle is set to run onload, it should be set up to run in the head. [drop down on left under jQuery selection.]
time is declared inside of the function so it is reset back to zero every single time it is called. Move it outside of dotRotation
var time = 0;
function dotRotation() {
var x = 20*(Math.sin(omega*time));
var y = 20*(Math.cos(omega*time));
$("#test").css({"marginLeft" : x + "px", "marginTop" : y + "px"});
time += 25;
};
$(function() {
setInterval(dotRotation,25);
});

Categories