Calculate font size based on characters in jquery - javascript

I'm trying to create method which will read the all characters in text box and return font size value.
my function is not working correct. Below is my code
function sizeInput(input) {
return shrinkToFill(input, 48, '', 'Impact');
}
function shrinkToFill(input, fontSize, fontWeight, fontFamily) {
var font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
var $input = $(input);
var maxWidth = $input.width() - 50;
// we're only concerned with the largest line of text.
var longestLine = $input.val().split('\n').sort(function (a, b) {
return measureText(a, font).width - measureText(b, font).width;
}).pop();
var textWidth = measureText(longestLine, font).width;
if (textWidth >= maxWidth) {
// if it's too big, calculate a new font size
// the extra .9 here makes up for some over-measures
fontSize = fontSize * maxWidth / textWidth * 0.9;
font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
// and set the style on the input
}
else {
font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
// and set the style on the input
}
$input.css({
'font-size': fontSize
});
return fontSize;
}
var measureText = function (str, font) {
str = str.replace(/ /g, ' ');
var id = 'text-width-tester';
var $tag = $('#' + id);
if (!$tag.length) {
$tag = $('<span id="' + id + '" style="display:none;font:' + font + ';">' + str + '</span>');
$('body').append($tag);
} else {
$tag.css({
font: font
}).html(str);
}
return {
width: $tag.width(),
height: $tag.height()
};
};
var topText = $('#topText');
var bottomText = $('#bottomText');
var textUpdated = function () {
var topFontSize = sizeInput(topText);
var bottomFontSize = sizeInput(bottomText);
};
It doesn't return any error but it doesn't work.

Here you go with the solution https://jsfiddle.net/5bdLomyp/2/
var sizeInput = function(input) {
return shrinkToFill(input, 48, '', 'Impact');
}
var shrinkToFill = function(input, fontSize, fontWeight, fontFamily) {
var font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
var $input = $(input);
var maxWidth = $input.width() - 50;
// we're only concerned with the largest line of text.
var longestLine = $input.val().split('\n').sort(function (a, b) {
return measureText(a, font).width - measureText(b, font).width;
}).pop();
var textWidth = measureText(longestLine, font).width;
if (textWidth >= maxWidth) {
// if it's too big, calculate a new font size
// the extra .9 here makes up for some over-measures
fontSize = fontSize * maxWidth / textWidth * 0.9;
font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
// and set the style on the input
}
else {
font = fontWeight + ' ' + fontSize + 'px ' + fontFamily;
// and set the style on the input
}
$input.css({
'font-size': fontSize
});
return fontSize;
}
var measureText = function (str, font) {
str = str.replace(/ /g, ' ');
var id = 'text-width-tester';
var $tag = $('#' + id);
if (!$tag.length) {
$tag = $('<span id="' + id + '" style="display:none;font:' + font + ';">' + str + '</span>');
$('body').append($tag);
} else {
$tag.css({
font: font
}).html(str);
}
return {
width: $tag.width(),
height: $tag.height()
};
};
var topText = $('#topText');
var bottomText = $('#bottomText');
$('#topText, #bottomText').keyup(function(){
var topFontSize = sizeInput(topText);
var bottomFontSize = sizeInput(bottomText);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="topText" class="hide text-tool top-text" type="text" placeholder="Top Text" />
<input id="bottomText" class="hide text-tool bottom-text" type="text" placeholder="Bottom Text" />
I guess this is what you are looking for.
Instead of using onkeyup or onchange in HTML, I have used jQuery keyup feature.

Here is the Answer :
function getFontSize(targetInput) {
var input = $("<input>").css({ "width": "570px", "height": "52px", "text-align": "center", "font-size": "48px" })
.val($(targetInput).val());
var topFontSize = sizeInput(input);
return topFontSize;
}

Related

jQuery hover only work with the first loop in for loop

My jQuery can change div height when it hover but when I create two divs with for loop it can only work with first loop.
I have JavaScript code that include jQuery.
It gets string from var result and create 1 div for image players and 1 div for stats of players.
I use loop to create player that when I hover the image it can active jQuery hover change stats div height from 0 to 20vw but it only working on first loop. I think it is because the id but the second loop id work fine with other jQuery.
The hover below:
var result =[
2,
"name:Tom;bc:67;lp:77;fn:37;ic:65;ag:45;sp:56;st:54;pc:66",
"name:Thomas;bc:70;lp:44;fn:70;ic:44;ag:60;sp:70;st:30;pc:30"
];
for (var a = 1; a < result[0] + 1; a++){
var players = result[a].split(";");
var playername = players[0].split(":");
var element = document.createElement("div");
var elementc = document.createElement("div");
var elements = document.createElement("div");
for (var s = 1; s < 8; s++){
var ps = document.createElement("p");
ps.innerHTML = players[s] + " ";
elements.appendChild(ps);
}
element.id = playername[1];
elementc.id = playername[1] + "id";
elements.id = playername[1] + "stats";
elementc.appendChild(element);
document.getElementById('manage').appendChild(elementc);
document.getElementById('manage').appendChild(elements);
document.getElementById(playername[1] + "id").style.position = "Relative";
document.getElementById(playername[1] + "id").style.position = "Relative";
document.getElementById(playername[1] + "id").style.width = "87vw";
document.getElementById(playername[1] + "id").style.margin = "0.5vw";
document.getElementById(playername[1] + "id").style.height = "10vw";
document.getElementById(playername[1] + "id").style.border = "1vw solid cyan";
document.getElementById(playername[1]).style.position = "Relative";
document.getElementById(playername[1]).style.cssFloat = "left";
document.getElementById(playername[1]).style.width = "10vw";
document.getElementById(playername[1]).style.height = "10vw";
document.getElementById(playername[1]).style.backgroundImage = "url(Players/" + playername[1] + ".jpg";
document.getElementById(playername[1]).style.backgroundSize = "cover";
document.getElementById(playername[1] + "stats").style.position = "Relative";
document.getElementById(playername[1] + "stats").style.backgroundColor = "lightgrey";
document.getElementById(playername[1] + "stats").style.overflowY = "scroll";
document.getElementById(playername[1] + "stats").style.width = "87vw";
document.getElementById(playername[1] + "stats").style.height = "20";
$("#" + playername[1] + "stats")
.children().css("background", "linear-gradient(to right,#0D7377 50%, #ffffff 50%)");
$("#" + playername[1] + "stats")
.children().css("width", "fit-content");
$("#" + playername[1] + "stats")
.children().css("float", "left");
$("#" + playername[1] + "stats")
.children().css("margin", "2vw");
$("#manage").children().css("margin-top", "30vw");
//The hover here
$("#" + playername[1] + "id").hover(
function(){
$("#" + playername[1] + "stats").animate({'height': '20vw'}, 'slow');
},
function(){
$("#" + playername[1] + "stats").animate({'height': '0vw'}, 'slow');
}
);
}
Give them a common class and then use that class directly for the hover event. (Single statement)
Working snippet:
var result = [
2,
"name:Tom;bc:67;lp:77;fn:37;ic:65;ag:45;sp:56;st:54;pc:66",
"name:Thomas;bc:70;lp:44;fn:70;ic:44;ag:60;sp:70;st:30;pc:30"
];
for (var a = 1; a < result[0] + 1; a++) {
var players = result[a].split(";");
var playername = players[0].split(":");
var element = document.createElement("div");
var elementc = document.createElement("div");
var elements = document.createElement("div");
for (var s = 1; s < 8; s++) {
var ps = document.createElement("p");
ps.innerHTML = players[s] + " ";
elements.appendChild(ps);
}
element.id = playername[1];
elementc.id = playername[1] + "id";
elementc.classList.add("player");
elements.id = playername[1] + "stats";
elements.classList.add("player-stats");
elementc.appendChild(element);
document.getElementById('manage').appendChild(elementc);
document.getElementById('manage').appendChild(elements);
document.getElementById(playername[1] + "id").style.position = "Relative";
document.getElementById(playername[1] + "id").style.position = "Relative";
document.getElementById(playername[1] + "id").style.width = "87vw";
document.getElementById(playername[1] + "id").style.margin = "0.5vw";
document.getElementById(playername[1] + "id").style.height = "10vw";
document.getElementById(playername[1] + "id").style.border = "1vw solid cyan";
document.getElementById(playername[1]).style.position = "Relative";
document.getElementById(playername[1]).style.cssFloat = "left";
document.getElementById(playername[1]).style.width = "10vw";
document.getElementById(playername[1]).style.height = "10vw";
document.getElementById(playername[1]).style.backgroundImage = "url(Players/" + playername[1] + ".jpg";
document.getElementById(playername[1]).style.backgroundSize = "cover";
document.getElementById(playername[1] + "stats").style.position = "Relative";
document.getElementById(playername[1] + "stats").style.backgroundColor = "lightgrey";
document.getElementById(playername[1] + "stats").style.overflowY = "scroll";
document.getElementById(playername[1] + "stats").style.width = "87vw";
document.getElementById(playername[1] + "stats").style.height = "20";
$("#" + playername[1] + "stats")
.children().css("background", "linear-gradient(to right,#0D7377 50%, #ffffff 50%)");
$("#" + playername[1] + "stats")
.children().css("width", "fit-content");
$("#" + playername[1] + "stats")
.children().css("float", "left");
$("#" + playername[1] + "stats")
.children().css("margin", "2vw");
$("#manage").children().css("margin-top", "30vw");
//The hover here
}
$(".player").hover(
function() {
$(this).next('.player-stats').animate({
'height': '20vw'
}, 'slow');
},
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="manage"></div>

Can't change css style with JS

<script>
var animate = function (element, target, callback) {
clearInterval(element.timer);
element.timer = setInterval(function () {
var step = (target - element.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
element.style.left = element.offsetLeft + step + 'px';
// console.log(element.offsetLeft);
if (element.offsetLeft == target) {
clearInterval(element.timer);
callback && callback();
}
}, 20)
};
window.addEventListener('load', function () {
var ul = document.querySelector('.local-nav');
console.log(ul);
for (var i = 0; i < ul.children.length; i++) {
ul.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var ul2 = document.querySelector('.subnav-entry ul');
console.log(ul2);
for (var i = 0; i < ul2.children.length; i++) {
console.log(ul2.children[i].children[0].children[0]);
ul2.children[i].children[0].children[0].style.backgroundPosition = '0 ' + -i * 32 + 'px';
}
var focus_ul = document.querySelector('.focus ul');
var ol = document.querySelector('.focus ol');
var count = 0;
var focus_timer = setInterval(function () {
if (count == 2) {
animate(focus_ul, focus_ul.offsetLeft - 375);
// console.log('i run');
// console.log(focus_ul.offsetLeft + ' ' + count);
// focus_ul.style.left = focus_ul.offsetLeft + 375 * 2 + 'px';
focus_ul.style.left = 0 + 'px'; // Here is my problem
console.log(focus_ul);
console.log(focus_ul.offsetLeft + ' ' + count);
}
else {
console.log('before animation ' + focus_ul.offsetLeft + ' ' + count);
animate(focus_ul, focus_ul.offsetLeft - 375);
console.log(focus_ul.offsetLeft + ' ' + count);
}
// focus_ul.style.left = focus_ul.offsetLeft + 375 + 'px';
count++;
count = count % 3;
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[count].className = 'current-choice';
console.log('after a round ' + focus_ul.offsetLeft + ' ' + count);
}, 2500)
})
</script>
I meant to do a photo show that can play automaticly, like a Carousel or swiper, The 375px means that the screen is 375px wide, according to the code, when comming to the last photo, as the animation end, it should change back to the initial one which style.left == 0px, but 0px only occur a small while, next time it would be -1125px, -1500px and so on, I'm confused why i set style.left to 0 but fruitless. I'm new in front end ,thanks helping
You can use more of CSS (and less JavaScript) for this animation.
Declare two separate CSS class definitions for focus_ul. Use JavaScript to change the className of focus_ul.
Use CSS transition for animation of CSS offset-left property.
See: https://www.w3schools.com/css/tryit.asp?filename=trycss3_transition1
Write that custom className instead :hover in above example.

How leaflet loads tile maps for custom rules?

Now there is a map of custom tile rules locally. There is already a custom JavaScript library that can be called normally. Now I need to replace this library with leaflet. How to use the algorithm in the old JavaScript library and leaflet to make the tile map Normal call?
The tile map projection rule is Mercator projection. The tile size is irregular. The width is 256 pixels. The height is the same on each line, but the different line heights are different. The old JavaScript library defines the ellipsoid parameters. Various levels of scale, rank number calculation rules, etc., now want to use leaflet to load these tile maps, how to use the old rules and leaflet combination?
MapBase defines various basic parameters, loadMapImage is a key function
function LoadMapImage() {
var tileLoadInfo = mapBase.getViewInfo();
MapInfo.Map.basemapslicedlayer.empty();
for (var i = 0; i < tileLoadInfo.TileInfo.length; i++) {
if (MapInfo.Map.Tiles[tileLoadInfo.TileInfo[i].Col + "_" + tileLoadInfo.TileInfo[i].Row + "_" + tileLoadInfo.Mode] == undefined) {
if (tileLoadInfo.Mode == 6) {
var src = DNCOptions.url + "&" + DNCOptions.paramX + "=" + tileLoadInfo.TileInfo[i].Row + "&" + DNCOptions.paramY + "=" + tileLoadInfo.TileInfo[i].Col + "&" + DNCOptions.paramZ + "=" + tileLoadInfo.TileInfo[i].Level + "&SessionID=" + WinfoDNCSessionID
} else if (tileLoadInfo.Mode == 8 || tileLoadInfo.Mode == 9) {
var level = tileLoadInfo.Level + 2;
if (tileLoadInfo.Mode == 9) {
level = tileLoadInfo.Level - 3
}
src = MapInfo.ServicePath + "?REQUEST=GetMap&SERVICE=CacheMap&Y=" + tileLoadInfo.TileInfo[i].Col + "&X=" + tileLoadInfo.TileInfo[i].Row + "&LEVEL=" + level + "&LAYERS=" + DNCOptions.layername + "&SessionID=" + WinfoDNCSessionID
} else {
var src = MapInfo.ServicePath + "?REQUEST=GetMap&SERVICE=WINFODNC&X=" + tileLoadInfo.TileInfo[i].Col + "&Y=" + tileLoadInfo.TileInfo[i].Row + "&LEVEL=" + tileLoadInfo.Level + "&LAYERS=" + tileLoadInfo.Mode + "&SessionID=" + WinfoDNCSessionID
}
MapInfo.Map.Tiles[tileLoadInfo.TileInfo[i].Col + "_" + tileLoadInfo.TileInfo[i].Row + "_" + tileLoadInfo.Mode] = w$("<img>").css({
position: "absolute",
left: tileLoadInfo.TileInfo[i].Offset_x,
top: tileLoadInfo.TileInfo[i].Offset_y
}).attr("src", src)
}
MapInfo.Map.basemapslicedlayer.append(MapInfo.Map.Tiles[tileLoadInfo.TileInfo[i].Col + "_" + tileLoadInfo.TileInfo[i].Row + "_" + tileLoadInfo.Mode].css({
position: "absolute",
left: tileLoadInfo.TileInfo[i].Offset_x,
top: tileLoadInfo.TileInfo[i].Offset_y
}))
}
}
function GetTileInfoByViewportParam(vp) {
var Box = {};
var i, row1, row2, col1, col2, hTileSize;
var L, R, T, B;
var LT = ScreenPoint2Coordinate(vp, 0, 0);
Box.Top = LT[0];
Box.Left = LT[1];
var RB = ScreenPoint2Coordinate(vp, vp.Width, vp.Height);
Box.Bottom = RB[0];
Box.Right = RB[1];
var rc = CalculateTile(LevelZeroTileSizeDegrees, Box, vp.Level);
row1 = rc[0];
row2 = rc[2];
col1 = rc[1];
col2 = rc[3];
var LRTB = CalculateTileExtend(LevelZeroTileSizeDegrees, vp.Level, row1, col1);
L = LRTB[0];
R = LRTB[1];
T = LRTB[2];
B = LRTB[3];
var Offset = Coordinate2ScreenPoint(vp, T, L);
vp.Offset_x = Offset[0];
vp.Offset_y = Offset[1];
MapViewInfo.Level = vp.Level;
MapViewInfo.Box = Box;
i = 0;
var offsety = vp.Offset_y;
MapViewInfo.TileInfo = [];
for (var j = row1; j >= row2; j--) {
hTileSize = CalculateTileSize(vp.Level, j, col1);
var offsetx = vp.Offset_x;
for (var z = col1; z <= col2; z++) {
var tileInfo = {};
tileInfo.Row = j;
tileInfo.Col = z;
tileInfo.Height = hTileSize;
tileInfo.Widht = TileSize;
tileInfo.Offset_x = offsetx;
tileInfo.Offset_y = offsety;
offsetx += TileSize;
MapViewInfo.TileInfo[i] = tileInfo;
i++
}
offsety += hTileSize
}
return MapViewInfo
};
According to the default initialization map method of leaflet, the parameters can only be retrieved to the blank tile.

How to create a pop up when I click on any item of this tree

I want to show a div when I click on any item of the tree here
the tree is loaded in the index.html via this iframe
<IFRAME NAME="treeframe" ID="treeframe" SRC="tree.htm?150921" CLASS="fullsize" FRAMEBORDER="0" SCROLLING="no"></IFRAME>
the element ('.di')
is generated with js
var v = document.createElement("div");
v.className = "di";
var s = v.style;
s.width = sz.Tew + "px";
s.height = sh + "px";
s.left = (sx - (sz.Tew / 2)) + "px";
s.top = (sy - (sh / 2)) + "px";
if (wp) {
v.onmousedown = TCT;
v.id = i;
v.pid = e.p.i;
o.ps[i] = {
x: sx,
y: sy
};
}
var tn = e.p.hp ? (mn ? fn : (e.p.h + (sn ? (" " + sn) : ""))) : e.p.h;
v.innerHTML = "<TABLE WIDTH=\"100%\" HEIGHT=\"100%\" STYLE=\"table-layout:fixed;\">" + "<TR><TD CLASS=\"" + cc + "\" STYLE=\"font-size:" + (e.d ? sz.Tds : sz.Tfs) + "px;color:" + _4 + "\"" + " TITLE=\"" + (e.d ? "Duplicate: " : "") + EH(fn) + "\">" + (e.d ? "<I>Duplicate:</I><BR>" : "") + (e.m ? "<B>" : "") + EL(tn) + (e.m ? "</B>" : "") + "</TD></TR>" + rs + "</TABLE>";
o.appendChild(v);
I typed this code but it's not working:
jQuery(window).load( function(){
jQuery('.di').on( 'click', function ( _ev ) {
jQuery('.sidebar-wrapper').fadeIn(500);
});
jQuery('.sidebar-wrapper .sidebar-close').on( 'click', function ( _ev ) {
jQuery('.sidebar-wrapper').fadeOut(500);
});
});
jQuery(document).ready( function(){
jQuery('body').on( 'click','.dcelld', function ( _ev ) {
jQuery('.sidebar-wrapper').fadeIn(500);
});
jQuery('body').on( 'click','.sidebar-wrapper .sidebar-close', function ( _ev ) {
jQuery('.sidebar-wrapper').fadeOut(500);
});
});

In bootstrap modal width is always 0

This is a function in the jqgrid in the load complete.
I have a bootstrap modal that is opened by clicking a button. In that modal I have a jqgrid. When I call a function in load complete, in that function, width of appending span is always 0. You can see the function below:
function columnresize(id) {
$(this).parent().append('<span id="widthTest" />');
gridName = this.id;
$('#gbox_' + gridName + ' .ui-jqgrid-htable' + gridName).css('width', 'inherit');
$('#' + gridName).parent().css('width', 'inherit');
var columnNames = $("#" + gridName).jqGrid('getGridParam', 'colModel');
var thisWidth;
var itmCount = columnNames.length;
/*var grid = $('#' + gridName);
var iids = grid.getDataIDs();*/
// Loop through Cols
for (var itm = 0; itm < itmCount; itm++) {
var curObj = $('[aria-describedby=' + gridName + '_' + columnNames[itm].name + ']');
var thisCell = $('#' + gridName + '_' + columnNames[itm].name + ' div');
$('#widthTest').html(thisCell.text()).css({
'font-family': thisCell.css('font-family'),
'font-size': thisCell.css('font-size'),
'width': thisCell.css('width'),
'font-weight': thisCell.css('font-weight')
});
var maxWidth = Width = $('#widthTest').width() + 17;
//var maxWidth = 0;
var itm2Count = curObj.length;
// Loop through Rows
for (var itm2 = 0; itm2 < itm2Count; itm2++) {
var thisCell = $(curObj[itm2]);
$('#widthTest').html(thisCell.html()).css({
'font-family': thisCell.css('font-family'),
'font-size': thisCell.css('font-size'),
'font-weight': thisCell.css('font-weight')
});
thisWidth = $('#widthTest').width();
if (thisWidth > maxWidth) {maxWidth = thisWidth+10;}
}
$('#' + gridName + ' .jqgfirstrow td:eq(' + itm + '), #' + gridName + '_' + columnNames[itm].name).width(maxWidth).css('min-width', maxWidth+17);
$('#' + gridName + ' .jqgfirstrow td:eq(' + 0 + '), #' + gridName + '_' + columnNames[0].name).width('30').css('min-width', '30px');
//grid.setRowData ( iids[itm], false, {height: 30} );
}
$('#widthTest').remove();
}
I call the above function in the load complete of jqgrid like this:
loadComplete: function() {
columnresize.call(this, 'Table');
}
The width $('#widthTest').width() in line:
var maxWidth = Width = $('#widthTest').width() + 17;
is always 0!
Any idea?
after a lot of research I found that because it is a hidden dom element, I have to use this
jquery to get the actual size of hidden dom element.
Thanks to #Justinas.

Categories