Coder Social home page Coder Social logo

Bind to resize event about textfit HOT 16 CLOSED

intelligence avatar intelligence commented on May 30, 2024
Bind to resize event

from textfit.

Comments (16)

STRML avatar STRML commented on May 30, 2024

Hey, thanks for being a personal beta tester. Could you post a jsfiddle?

from textfit.

intelligence avatar intelligence commented on May 30, 2024

Ha! No problem :)

http://jsbin.com/EbaR/1
Will this suffice? It's alot of code but it's from the context it's being used.

from textfit.

STRML avatar STRML commented on May 30, 2024

See http://jsbin.com/EbaR/3/edit

I can't tell without context of the application this code is in, but it seems awfully complicated for what it does. You may be able to get much better results by simply using percentage widths and heights on your centered div, rather than using JS to resize it. For example:

.container {
  position: absolute;
  height: 20%;
  width: 30%;
  left: 50%;
  top: 50%;
  text-align: center;
  margin-left: -15%;
  margin-top: -10%;
}

I did commit a fix to a bug that occurs when you nest elements inside the element you're resizing - it needed to be display: inline-block so that it resized correctly to its contents.

For example, if I use percentages I can simplify your code dramatically: http://jsbin.com/uMiW/3/edit

from textfit.

STRML avatar STRML commented on May 30, 2024

I'm keeping this ticket open for now because I want to ensure this works with alignVert, and it doesn't seem to yet.

from textfit.

intelligence avatar intelligence commented on May 30, 2024

That did it! But as you say, there's a trouble with alignVert when you cannot use display: table. Not sure if it can be circumvented without js?

Thanks for your input by the way, my code is very complex for what it does in this demo, but on the site it handles images and videos with specific ratios, that's why, wasn't sure that any of it were interfering with your script.

from textfit.

intelligence avatar intelligence commented on May 30, 2024

@STRML Any idea of a work around? Been trying to hack my way around but with no luck. Really need the possibility to center both vertically and horizontally.

from textfit.

JBReading avatar JBReading commented on May 30, 2024

Hi STRML,

Firstly, this is a superb bit of JQuery. Love it.

I am relatively new to Javascript, and I have it working perfectly on initial page load, however, I also want the function to work on $(window).resize(function() ......

I have a one page website and the top element resizes dynamically with the window resize action as I wanted. As you will see below, the textFit call is in the same function, but does not work like the element resizing code does when resizing window.

function navNscroll(resizing){

        var homePage = ("#homepage");
        var headerHeight = $("#header").height(); // scrollHeight
        var viewportHeight = $(window).height(); //scrollHeight
        var homepagePadding = $(homepage).outerHeight() - $(homepage).height();  // scrollHeight
        //var homepagePadding = $(homepageh).outerHeight(true); 

        var percentFactor = 0.66;
        var heightAvailable = viewportHeight - headerHeight; 
        var homepageHeight = heightAvailable - homepagePadding; 
        homepageHeight = homepageHeight - parseInt($(".midbanner.one").css("margin-top"),10);  
        homepageHeight = homepageHeight * percentFactor;  
        remainder = heightAvailable - homepageHeight; 
        parseInt(homepageHeight);

        var paddingVal = 20; 
        var homepageWidth = parseInt($(homePage).innerWidth(), 10) - (paddingVal * 2);

    function fitText() {

        $(homePage).height(homepageHeight).css("margin-bottom",remainder); 

        $(".midbanner.one .text").css("padding", paddingVal); 

        $('.bigText').css("width",homepageWidth).css("height", (homepageHeight - (paddingVal *2)));

        $('.bigText').textFit({multiLine:true, alignVert:true, lineHeight:1.4, maxFontSize:40}); 

    }

    fitText();

    if (resizing == "yes"){ 
        fitText(); // tried this because I ran out of ideas
    }

}

$(window).resize(function() {
  navNscroll('yes');
});

I have also slightly changed your textFit.js code so I can control line-height:


(function($) {
    $.fn.textFit = function(options) {
        var settings = {
            alignVert: false, // if true, textFit will align vertically using css tables
            alignHoriz: false, // if true, textFit will set text-align: center
            multiLine: true, // if true, textFit will not set white-space: no-wrap
            detectMultiLine: true, // disable to turn off automatic multi-line sensing
            minFontSize: 6,
            maxFontSize: 80,
            reProcess: false, // if true, textFit will re-process already-fit nodes. Leave to 'false' for better performance
            widthOnly: false, // if true, textFit will fit text to element width, regardless of text height
            lineHeight: 1.2 // JBReading: default is 1.2 x font-size  
        };
        $.extend(settings, options);

        return this.each(function(){

            if (this.length === 0 || (!settings.reProcess && $(this).data('boxfitted'))) {
                return $(this);
            }
            if(!settings.reProcess){
                $(this).data('boxfitted', 1);
            }
            var innerSpan, originalHeight, originalText, originalWidth;
            var low, mid, high;

            originalText = $(this).html();
            $(this).html("");
            originalWidth = $(this).width();
            originalHeight = $(this).height();

            // Don't process if we can't find box dimensions
            if (!originalWidth || (!settings.widthOnly && !originalHeight)) {
                if (window.console != null) {
                    if(!settings.widthOnly)
                        console.info('Set a static height and width on the target element' + this.outerHTML +
                            ' before using textFit!');
                    else
                        console.info('Set a static width on the target element' + this.outerHTML +
                            ' before using textFit!');
                }
                return $(this).html(originalText);
            } else {
                // Add textfitted span
                if (originalText.indexOf('textfitted') === -1) {
                    innerSpan = $("<span></span>").addClass("textfitted").html(originalText);
                    $(this).html(innerSpan);
                } else {
                    $(this).html(originalText);
                    innerSpan = $(originalText).find('span.textfitted');
                    $(innerSpan).addClass("foundit"); 
                    // innerSpan = $("span.textfitted");
                }

                // Prepare & set alignment
                if (settings.alignVert) {
                    $(this).css("display", "table");
                    innerSpan.css("display", "table-cell");
                    innerSpan.css("vertical-align", "middle");
                }
                if (settings.alignHoriz) {
                    $(this).css("text-align", "center");
                    innerSpan.css("text-align", "center");
                }

                // Check if this string is multiple lines
                // Not guaranteed to always work if you use wonky line-heights
                if (settings.detectMultiLine && !settings.multiLine &&
                      innerSpan.height() >= parseInt(innerSpan.css('font-size'), 10) * 2){
                    settings.multiLine = true;
                }
                if (!settings.multiLine) {
                    $(this).css('white-space', 'nowrap');
                }



                low = settings.minFontSize + 1;
                high = settings.maxFontSize + 1;

                // Binary search for best fit
                while ( low <= high) {
                    mid = parseInt((low + high) / 2, 10);
                    innerSpan.css('font-size', mid);
                    if(innerSpan.width() <= originalWidth && (settings.widthOnly || innerSpan.height() <= originalHeight)){
                        low = mid + 1;
                    } else {
                        high = mid - 1;
                    }
                }
                // Sub 1
                subOne = mid - 1; 
                innerSpan.css('font-size', subOne);

                    // JBReading: 
                   newLineHeight = subOne * settings.lineHeight; 
                   $(this).css('line-height', newLineHeight+"px");

            }
        });
    };
})(jQuery);

The HTML:

<div class="midbanner one" id="homepage">
<div class="text fullwidth" >
<span class="bigText" style="width:300px;height:300px">
 In eget tellus quis diam imperdiet condimentum sed quis mauris. Praesent enim purus, aliquet et mauris nec, malesuada luctus purus. Sed nec sapien semper, mattis purus vel, vehicula enim. Nulla vitae sagittis eros. Morbi risus magna, convallis in fringilla vitae, tempor sit amet quam. Cras aliquet diam nulla, a accumsan eros elementum sit amet. Duis molestie leo ac lorem convallis, et porttitor enim dictum. 
</span>
<p class="clear">&nbsp;</p>
</div>
</div><!-- end of midbanner one -->

Any ideas on this?

Thanks in advance.

from textfit.

STRML avatar STRML commented on May 30, 2024

First of all, @intelligence, sorry for not getting back to you. I'm exploring a vertical alignment strategy that eschews the table and table-cell stylings for a simple margin-top property equal to the (height of the container - the height of the inner span) / 2. Should be relatively simple. You could probably hack something like that in yourself, or wait, I'll likely put it in later as your test case has shown that display:table is really quite fiddly. I will need to do some testing to be sure that it doesn't break anything.

If you want to fix it, try the following around your textFit() calls (with alignVert:false)

$(".textFitted").css("margin-top", 0);
textFit(...)
var margin = ($(".content").height() - $(".textFitted").height()) / 2;
$(".textFitted").css("margin-top", margin + "px");

from textfit.

STRML avatar STRML commented on May 30, 2024

@JBReading , feel free to open another issue if you have an unrelated question. But since you posted here, I'll answer here for now.

First, textFit has a reProcess option. If it's set to true, it will re-process an already-fitted node. This is necessary if you want to resize something again. I may flip the option in the future so it works this way by default; it won't break existing code though. In your case, you'll want to pass {reProcess: true}.

Secondly, no need to modify the code to add line-height. Simply use CSS to set a line height of 1.2em on the container.

from textfit.

intelligence avatar intelligence commented on May 30, 2024

Hey @STRML! That's no problem, I realize that you probably don't maintain the plugin for a living :)
I tried your quick fix, it works well! Although it seems it goes a bit off when you resize.

Have a look at my implementation here: http://eplusp.se/spotify-facebook/
Username is: dev
Password is: lolboy

from textfit.

STRML avatar STRML commented on May 30, 2024

I took a look at it. There's something bizarre going on - basically, here's what I see:

Your automatic resizer is moving the container element around and it'll end up with a negative margin of some fractional number of px. I'll give you an example from what I see right now:

style="width: 555px; height: 295.2127659574468px; margin-left: -277.5px; margin-top: -147.6063829787234px; text-align: center;"

The issue is that the browser is doing some rounding here. In this particular case, the container has an offsetWidth of 555px but the inner span has an offsetWidth of 556px! On every measurement cycle, textFit checks the width and sees if it has become bigger than its parent. The problem is, in every single case, it's bigger than its parent because of this bug, even when the text is too small to read. This is something I haven't seen before but it sort of makes sense; basically it's rounding on the fractional amounts a little incorrectly. Best I can tell is, the inner span is being aligned one px farther left on the pixel grid than its parent, resulting in it being one px larger when measured. Pretty weird!

The fix is pretty simple: in your resize function around line 1050, surround all your calculations that are being entered into .css() in parseInt(value, 10) calls. This will round them down to an integer value. Be especially careful to round the final values, not the intermediate ones. For example:

$this.find('section .content').each(function(){ // no need for additional $() wrapper
    var t = { width: 940, height: 500, retina: false }
    var d = ep.projects.calculate( t )
    $(this)
        .css('width', parseInt(d.w, 10))
        .css('height', parseInt(d.h, 10))
        .css({ marginTop: '-'+parseInt(d.h/2, 10)+'px', marginLeft: '-'+parseInt(d.w/2, 10)+'px' })
})

Good luck with the app!

Edit: You may have some luck with this novel centering technique.

Edit 2: I've illustrated the inner width problem. Play around with resizing the window and watch your console. It's achievable via simple percentage widths for the same reason. I've only tested in Chrome but it may happen elsewhere.

from textfit.

STRML avatar STRML commented on May 30, 2024

97a6ecf should help you with alignVert.

from textfit.

intelligence avatar intelligence commented on May 30, 2024

Wow, thanks, was not aware of that technique! The vertical align seems to work well but now it seems we're back to the issue where the font-size will not updated on resize. Stays on 32px while I'm narrowing the browser then it jumps straight to 6px.

from textfit.

STRML avatar STRML commented on May 30, 2024

You didn't update the textFit version.

from textfit.

intelligence avatar intelligence commented on May 30, 2024

Are you sure? I checked it and saw that a new class was applied with the new css. I grabbed the minified version.

.textFitAlignVert {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
}

Edit: Tried with the full aswell, but same issue.
Edit2: And the updated version seem to say v2.0.

from textfit.

STRML avatar STRML commented on May 30, 2024

Please open a new issue if you're still having problems.

from textfit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.