PageSourceSearch

https://job77.net/js/jquery.nailthumb.1.1.js

js job77.net collected 2026-10-06 19:43:26 UTC 28,459 bytes, 706 lines download raw bytes

1/*	jQuery NailThumb Plugin - any image to any thumbnail
2 *  Examples and documentation at: http://www.garralab.com/nailthumb.php
3 *  Copyright (C) 2012  [email protected]
4 *
5 *  This program is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18(function($) {
19    var DEBUG = false;
20    var version = '1.1';
21    $.fn.nailthumb = function(options) {
22        var opts = $.extend({}, $.fn.nailthumb.defaults, options);
23        return this.each(function() {
24            var $this = $(this);
25            var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
26            thumbize($this,o)
27        });
28    };
29    function thumbize(element,options) {
30        var image = setImage(element,options);
31        var container = setContainer(element,options);
32        if (options.serverSideParams) {
33            $.fn.nailthumb.setServerSideParams(image,container,options);
34        }
35        debugObject('image',image);
36        debugObject('container',container);
37        if (options.onStart) options.onStart(container,options);
38        if (options.loadingClass) container.addClass(options.loadingClass);
39
40        if (options.preload || image.data('nailthumb.replaceto')) {
41            debug('wait on load');
42            image.one('load',function() {
43                debugObject('before check',image);
44                if(!image.data('nailthumb.working') && !image.data('nailthumb.replacing')) {
45                    image.data('nailthumb.working',true);
46                    debugObject('inside check',image);
47                    doThumb(image,container,options);
48                }
49            });
50            var src = image.attr('src');
51            image.attr('src',null).attr('src',src);
52        } else {
53            debug('nail thumb directly');
54            image.data('nailthumb.working',true);
55            doThumb(image,container,options);
56        }
57    };
58    function doThumb(image,container,options) {
59        resetImage(image,options);
60        resetContainer(container,options);
61        var imageDims = getImageDims(image,options);
62        debugObject('image',image);
63        debugObject('imageDims',imageDims);
64        if (imageDims.width==0 || imageDims.height==0) {
65            imageDims = getHiddenCloneDims(image);
66            debugObject('imageCloneDims',imageDims);
67        }
68        var containerDims = getContainerDims(container,options);
69        debugObject('container',container);
70        debugObject('containerDims',containerDims);
71        var prop = getProportion(containerDims,imageDims,options);
72        debug('proportions',prop);
73        resize(image, imageDims, container, containerDims, prop, options);
74        
75    };
76    function setImage(element,options) {
77        var image = element.find('img').first();
78        var finder = options.imageCustomFinder;
79        if (!finder && options.imageUrl) {
80            finder = imageUrlFinder;
81        } else if(!finder && options.imageFromWrappingLink) {
82            finder = imageFromWrappingLinkFinder;
83        }
84        if (finder) {
85            var img = finder(element,options);
86            debugObject('finder',img);
87            if (!img) img = [];
88            if (img.length>0) {
89                image = img;
90                image.css('display','none');
91                if(!image.data('nailthumb.replaceto')) image.data('nailthumb.replaceto',element);
92                image.data('nailthumb.originalImageDims',null);
93            }
94        }
95        if (image.length==0) {
96            if (element.is('img')) image = element;
97        }
98        
99        return image;
100    };
101    function imageUrlFinder(element,options) {
102        var image = $('<img />').attr('src',options.imageUrl).css('display','none').data('nailthumb.replaceto',element);
103        element.append(image);
104        return image;
105    };
106    function imageFromWrappingLinkFinder(element,options) {
107        var image;
108        var link = element.find('a').first();
109        if (link.length==0 && element.is('a')) {
110            link = element;
111        }
112        if (link.attr('href')) {
113            image = $('<img />').attr('src',link.attr('href')).css('display','none').data('nailthumb.replaceto',link);
114            if (link.attr('title')) image.attr('title',link.attr('title'));
115            link.append(image);
116        }
117        return image;
118    };
119    function resetImage(image,options) {
120        if (!options.nostyle) {
121            image.css({
122                'position':'relative'
123            });
124        }
125        if (!image.data('nailthumb.originalImageDims')) {
126            image.css({
127                'width':'auto',
128                'height':'auto',
129                'top':0,
130                'left':0
131            }).removeAttr('width')
132            .removeAttr('height');
133        }
134    };
135    function setContainer(element,options) {
136        var container = element;
137        if (element.is('img')) {
138            if (options.ifImageAddContainer) {
139                var c = $('<div></div>');
140                element.wrap(c);
141            } 
142            container = element.parent();
143        }
144        return container;
145    };
146    function resetContainer(container,options) {
147        if (options.containerClass) container.addClass(options.containerClass);
148        if (!options.nostyle) {
149            container.css({
150                'overflow':'hidden',
151                'padding':'0px'
152            });
153        }
154        
155        if (options.replaceAnimation == 'animate') {
156            if (options.width || options.height) {
157                container.animate({
158                    'width':options.width,
159                    'height':options.height
160                },options.animationTime,options.animation);
161            }
162        } else {
163            if (options.width) container.width(options.width);
164            if (options.height) container.height(options.height);
165        }
166        
167        container.find('span.'+options.titleClass).remove();
168    };
169    function resize(image, imageDims, container, containerDims, prop, options) {
170        var iw = imageDims.width * prop;
171        var ih = imageDims.height * prop;
172        var top = 0, left = 0, diff;
173        var direction = getDirections(options.fitDirection);
174        if (ih<containerDims.innerHeight) {
175            switch (direction.v) {
176                case 'center':
177                    top=-(ih-containerDims.innerHeight)/2;
178                    break;
179                case 'bottom':
180                    top=-(ih-containerDims.innerHeight);
181                    diff='bottom';
182                    break;
183                case 'top':
184                    top=0;
185                    diff='top';
186                    break;
187                default:
188                    break;
189            }
190        } else if (ih>containerDims.innerHeight) {
191            switch (direction.v) {
192                case 'center':
193                    top=-(ih-containerDims.innerHeight)/2;
194                    break;
195                case 'bottom':
196                    top=-(ih-containerDims.innerHeight);
197                    break;
198                default:
199                    break;
200            }
201        }
202        if (iw<containerDims.innerWidth) {
203            switch (direction.h) {
204                case 'center':
205                    left=-(iw-containerDims.innerWidth)/2;
206                    break;
207                case 'right':
208                    left=-(iw-containerDims.innerWidth);
209                    break;
210                default:
211                    break;
212            }
213        } else if (iw>containerDims.innerWidth) {
214            switch (direction.h) {
215                case 'center':
216                    left=-(iw-containerDims.innerWidth)/2;
217                    break;
218                case 'right':
219                    left=-(iw-containerDims.innerWidth);
220                    break;
221                default:
222                    break;
223            }
224        }
225        image.addClass(options.imageClass);
226        if (image.data('nailthumb.replaceto')) {
227            replaceImage(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
228        } else {
229            showImage(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
230        }
231    };
232    function replaceImage(image, imageDims, container, containerDims, ih, iw, left, top, diff, options) {
233        var element = image.data('nailthumb.replaceto');
234        var replaceto = findReplaceTo(element,options);
235        image.data('nailthumb.replacing',true);
236        image.load(function() {
237            image.data('nailthumb.replacing',null);
238        });
239        if (replaceto) {
240            replaceto.replaceWith(image);
241        } else {
242            element.append(image);
243        }
244        if (options.afterReplace) options.afterReplace(container, image, options);
245        showImage(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
246    };
247    function showImage(image, imageDims, container, containerDims, ih, iw, left, top, diff, options) {
248        
249        if (options.replaceAnimation == 'animate') {
250            image.css('display','inline');
251            container.animate({
252                'width':containerDims.innerWidth,
253                'height':containerDims.innerHeight
254            },options.animationTime,options.animation);
255            image.animate({
256                'width':iw,
257                'height':ih,
258                'top':top,
259                'left':left
260            },options.animationTime,options.animation,function(){
261                afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
262            });
263        } else {
264            container.css({
265                'width':containerDims.innerWidth,
266                'height':containerDims.innerHeight
267            });
268            if (options.replaceAnimation) image.css('display','none');
269            image.css({
270                'width':iw,
271                'height':ih,
272                'top':top,
273                'left':left
274            });
275            if (options.replaceAnimation == 'fade') {
276                image.fadeIn(options.animationTime,options.animation,function(){
277                    afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
278                });
279            } else if (options.replaceAnimation == 'slide') {
280                image.slideDown(options.animationTime,options.animation,function(){
281                    afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
282                });
283            } else if (options.replaceAnimation && options.replaceAnimation instanceof Function) {
284                options.replaceAnimation(image,function(){
285                    afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
286                },options);
287                if (!options.selfStartAfterAppear) {
288                    afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
289                }
290            } else {
291                image.css('display','inline');
292                afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
293            }
294        }
295    };
296    function afterAppear(image, imageDims, container, containerDims, ih, iw, left, top, diff, options) {
297        if (options.afterAppear) options.afterAppear(container, image, options);
298        image.data('nailthumb.replaceto',null);
299        decorate(image, imageDims, container, containerDims, ih, iw, left, top, diff, options);
300    };
301    function findReplaceTo(element,options) {
302        var rep = null; 
303        element.find('img').each(function() {
304            if (!rep && !$(this).data('nailthumb.replaceto')) {
305                rep = $(this);
306            }
307        });
308        return rep;
309    };
310    function decorate(image, imageDims, container, containerDims, ih, iw, left, top, diff, options) {
311        if (options.title || (options.titleAttr && image.attr(options.titleAttr)) ) {
312            var title = options.title?options.title:image.attr(options.titleAttr);
313            if (title) {
314                var span = $('<span class="'+options.titleClass+'">'+title+'</span>');
315                if (containerDims.innerHeight>ih) span.css('top',containerDims.innerHeight-ih);
316                else span.css('top','0px');
317                container.append(span);
318                var tit = getHiddenDims(span);
319                var im = getHiddenDims(image);
320                debugObject('decorate containerDims',containerDims);
321                debugObject('decorate imageDims',imageDims);
322                debugObject('decorate imageDims',im);
323                debugObject('decorate tit',tit);
324                var outbound = containerDims.offsetTop+containerDims.innerHeight-tit.offsetTop;
325                if (containerDims.height>containerDims.innerHeight) {
326                    outbound+=(containerDims.height-containerDims.innerHeight)/2
327                }
328                span.css('top','+='+outbound);
329                
330                if (iw < tit.width) span.css('width',iw);
331                if (left > 0) span.css('left',left);
332                
333                var delta = tit.height;
334                if (containerDims.innerHeight>ih && diff!='bottom') {
335                    delta += (containerDims.innerHeight-ih)/((diff=='top')?1:2);
336                }
337                
338                var clone = span.clone();
339                clone.css('width','auto').css('display','none').css('position','absolute');
340                container.append(clone);
341                var cloneDims = getHiddenDims(clone);
342                clone.remove();
343                debugObject('decorate cloneDims',cloneDims);
344                
345                if (options.titleWhen=='hover') {
346                    container.unbind('mouseenter mouseleave').hover(function(){
347                        span.find('span.'+options.titleScrollerClass).css('left',0);
348                        containerDims = getHiddenDims(container);
349                        tit = getHiddenDims(span);
350                        outbound = containerDims.offsetTop+containerDims.innerHeight-tit.offsetTop;
351                        if (containerDims.height>containerDims.innerHeight) {
352                            outbound+=(containerDims.height-containerDims.innerHeight)/2
353                        }
354                        debugObject('decorate hover tit',tit);
355                        debug('decorate hover outbound',tit);
356                        var doubleDelta = 0;
357                        if (outbound<0) {
358                            span.css('top','+='+outbound);
359                            doubleDelta = delta;
360                        } else {
361                            doubleDelta = delta-outbound;
362                        }
363                        if(options.animateTitle) {
364                            resetScrollTitle(span,options);
365                            span.stop(true).animate({
366                                top:'-='+doubleDelta
367                            },options.titleAnimationTime,options.titleAnimation,function(){
368                                scrollTitle(span, cloneDims.width, containerDims.innerWidth, options);
369                            });
370                        } else {
371                            span.css({
372                                top:'-='+doubleDelta
373                            });
374                            scrollTitle(span, cloneDims.width, containerDims.innerWidth, options);
375                        }
376                    },function(){
377                        if(options.animateTitle) {
378                            resetScrollTitle(span,options);
379                            span.animate({
380                                top:'+='+delta
381                            },options.titleAnimationTime,options.titleAnimation,function(){
382                                resetScrollTitle(span,options);
383                            });
384                        } else {
385                            resetScrollTitle(span,options);
386                            span.css({
387                                top:'+='+delta
388                            });
389                        }
390                    });
391                } else {
392                    if(options.animateTitle) {
393                        span.animate({
394                            top:'-='+delta
395                        },options.titleAnimationTime,options.titleAnimation,function(){
396                            scrollTitle(span, cloneDims.width, containerDims.innerWidth, options);
397                        });
398                    } else {
399                        span.css({
400                            top:'-='+delta
401                        });
402                        scrollTitle(span, cloneDims.width, containerDims.innerWidth, options);
403                    }
404                }
405            }
406        }
407        if (options.onFinish) options.onFinish(container,options);
408        if (options.loadingClass) container.removeClass(options.loadingClass);
409        image.data('nailthumb.working',null);
410    };
411    function resetScrollTitle(span,options) {
412        span.find('span.'+options.titleScrollerClass).stop();
413    };
414    function scrollTitle(span, width, visibleWidth, options) {
415        if (width > visibleWidth && options.titleScrolling) {
416            if (span.find('span.'+options.titleScrollerClass).length==0) {
417                span.wrapInner('<span class="'+options.titleScrollerClass+'" />');
418                span.find('span.'+options.titleScrollerClass).width(width).css('position','relative').css('white-space','nowrap');
419            }
420            span.find('span.'+options.titleScrollerClass).css('left',0);
421            setTimeout(scrollFunction(span, width, visibleWidth, options),1000);
422        }
423    };
424    function scrollFunction(span, width, visibleWidth, options) {
425        return function() {
426            var indent = Number(span.find('span.'+options.titleScrollerClass).css('left').replace(/[^-\d]/g,''));
427            debug('indent',indent);
428            debug('width',width);
429            debug('visibleWidth',visibleWidth);
430            debug('width <= -indent',(width <= -indent));
431            var delta = width + indent;
432            if (delta <= 0) {
433                span.find('span.'+options.titleScrollerClass).css('left',visibleWidth);
434                delta = width + visibleWidth;
435            }
436            delta += 10;
437            span.find('span.'+options.titleScrollerClass).animate({
438                'left':'-='+delta
439            },width*1000/30,'linear',scrollFunction(span, width, visibleWidth, options));
440        };
441    };
442    function getProportion(containerDims, imageDims, options) {
443        if (options.proportions != null && options.proportions > 0) {
444            return options.proportions;
445        } else {
446            var prop = containerDims.innerWidth/imageDims.width;
447            if (options.method && options.method=='resize') {
448                if (containerDims.innerHeight/imageDims.height < prop) {
449                    prop = containerDims.innerHeight/imageDims.height;
450                }
451            } else {
452                if (containerDims.innerHeight/imageDims.height > prop) {
453                    prop = containerDims.innerHeight/imageDims.height;
454                }
455            }
456            if (options.maxEnlargement && options.maxEnlargement < prop) prop = options.maxEnlargement;
457            if (options.maxShrink && options.maxShrink > prop) prop = options.maxShrink;
458            return prop;
459        }
460    };
461    function getDirections(option) {
462        var dir = {
463            h:'center',
464            v:'center'
465        };
466        if (option) {
467            var opts = option.split(' ');
468            if (opts.length > 0) {
469                dir = getDirection(opts[0],dir);
470            }
471            if (opts.length > 1) {
472                dir = getDirection(opts[1],dir);
473            }
474        }
475        return dir;
476    };
477    function getDirection(str,d) {
478        switch (str) {
479            case 'top':
480                d.v = 'top';
481                break;
482            case 'bottom':
483                d.v = 'bottom';
484                break;
485            case 'left':
486                d.h = 'left';
487                break;
488            case 'right':
489                d.h = 'right';
490                break;
491            default:
492                break;
493        }
494        return d;
495    };
496    function getImageDims(image,options) {
497        var imageDims;
498        if (!image.data('nailthumb.originalImageDims') ) {
499            imageDims = getHiddenDims(image);
500            image.data('nailthumb.originalImageDims',imageDims);
501            if (!options.keepImageDimensions) {
502                image.one('load',function(){
503                    image.data('nailthumb.originalImageDims',null);
504                });
505            }
506        } else {
507            imageDims = image.data('nailthumb.originalImageDims');
508        }
509        return imageDims;
510    };
511    function getContainerDims(container,options) {
512        var containerDims = getHiddenDims(container)
513        if (options.width) containerDims.innerWidth = options.width;
514        if (options.height) containerDims.innerHeight = options.height;
515        return containerDims;
516    };
517    function getDims(elem) {
518        var offset = $(elem).offset();
519        return {
520            offsetTop: offset.top,
521            offsetLeft: offset.left,
522            width: $(elem).outerWidth(),
523            height: $(elem).outerHeight(),
524            innerWidth: $(elem).innerWidth(),
525            innerHeight: $(elem).innerHeight()
526        };
527    };
528    function getHiddenDims(elems) {
529        var dims = null, i = 0, offset, elem;
530
531        while ((elem = elems[i++])) {
532            var hiddenElems = $(elem).parents().andSelf().filter(':hidden');
533            if ( ! hiddenElems.length ) {
534                dims = getDims(elem);
535            } else {
536                var backupStyle = [];
537                hiddenElems.each( function() {
538                    var style = $(this).attr('style');
539                    style = typeof style == 'undefined'? '': style;
540                    backupStyle.push( style );
541                    $(this).attr( 'style', style + ' display: block !important;' );
542                });
543
544                hiddenElems.eq(0).css( 'left', -10000 );
545
546                dims = getDims(elem);
547
548                hiddenElems.each( function() {
549                    $(this).attr( 'style', backupStyle.shift() );
550                });
551            }
552            
553        }
554
555        return dims;
556    };
557    function getHiddenCloneDims(elems) {
558        var dims = null, i = 0, offset, elem;
559
560        while ((elem = elems[i++])) {
561            var hiddenElems = $(elem).parents().andSelf().filter(':hidden');
562            if ( ! hiddenElems.length ) {
563                dims = getDims(elem);
564            } else {
565                var backupStyle = [];
566                hiddenElems.each( function() {
567                    var style = $(this).attr('style');
568                    style = typeof style == 'undefined'? '': style;
569                    backupStyle.push( style );
570                    $(this).attr( 'style', style + ' display: block !important;' );
571                });
572
573                hiddenElems.eq(0).css( 'left', -10000 );
574                
575                var clone = hiddenElems.eq(0).clone();
576                $('body').append(clone);
577
578                dims = getDims(clone);
579
580                hiddenElems.each( function() {
581                    $(this).attr( 'style', backupStyle.shift() );
582                });
583                clone.remove();
584            }
585            
586        }
587
588        return dims;
589    };
590    $.fn.nailthumb.evalServerSideParams = function(image,container,options) {
591        if (options.serverSideParams) {
592            var params = {};
593            if (!options.serverSideParams.noServerResize) {
594                var w = null, h = null;
595                if (options.serverSideParams.width) w = options.serverSideParams.width;
596                else if (options.width) w = options.width;
597                if (options.serverSideParams.height) h = options.serverSideParams.height;
598                else if (options.height) h = options.height;
599                if (!(w && h)) {
600                    resetContainer(container,options);
601                    var containerDims = getContainerDims(container,options);
602                    w = containerDims.innerWidth;
603                    h = containerDims.innerHeight;
604                }
605                if (w && h) {
606                    params.w = w;
607                    params.h = h;
608                    if (options.serverSideParams.mode!='resize') {
609                        if (options.method=='crop') params.mode = 'crop';
610                        if (options.serverSideParams.mode) params.mode = options.serverSideParams.mode;
611                    }
612                }
613            }
614            
615            $.each(options.serverSideParams, function(key,val) {
616                if (key!='width' && key!='height' && key!='mode' && key!='noServerResize' && val) {
617                    params[key]=val;
618                }
619            });
620            var pars = "";
621            $.each(params, function(key,val) {
622                pars+=";"+key+"="+val;
623            });
624            debug(pars,params);
625            return pars;
626        } else {
627            return "";
628        }
629    };
630    $.fn.nailthumb.setServerSideParams = function(image,container,options) {
631        if (options.serverSideParams) {
632            var url = image.attr("src");
633            if (image.data('nailthumb.originalImageUrl')) {
634                url = image.data('nailthumb.originalImageUrl');
635            }
636            image.data('nailthumb.originalImageUrl',url);
637            var pars = $.fn.nailthumb.evalServerSideParams(image,container,options);
638            url += pars;
639            image.attr("src",url);
640        }
641    };
642    $.fn.nailthumb.toggleDebug = function() {
643        DEBUG = !DEBUG;
644    };
645    $.fn.nailthumb.doThumb = function(image,container,options) {
646        doThumb(image,container,options);
647    };
648    $.fn.nailthumb.defaults = {
649        onStart: null,
650        onFinish: null,
651        loadingClass: 'nailthumb-loading',
652        imageUrl: null,
653        imageFromWrappingLink: false,
654        imageCustomFinder: null/*function(element,options){
655            return null;
656        }*/,
657        imageClass:'nailthumb-image',
658        afterReplace: null,
659        afterAppear: null,
660        replaceAnimation: 'fade',
661        selfStartAfterAppear: false,
662        animationTime: 1000,
663        animation: 'swing',
664        keepImageDimensions: false,
665        method: 'crop',
666        fitDirection: null,
667        proportions: null,
668        ifImageAddContainer: true,
669        containerClass: 'nailthumb-container',
670        maxEnlargement: null,
671        maxShrink: null,
672        preload: true,
673        nostyle: false,
674        width: null,
675        height: null,
676        title: null,
677        titleClass: 'nailthumb-title',
678        titleAttr: 'title',
679        titleWhen: 'hover',
680        titleScrolling: true,
681        titleScrollerClass: 'nailthumb-title-scroller',
682        animateTitle: true,
683        titleAnimationTime: 500,
684        titleAnimation: 'swing',
685        serverSideParams: null
686    };
687    function log(log, jQueryobj) {
688        try {
689            debug(log, jQueryobj, true);
690        } catch(ex) {}
691    };
692    function debug(log, jQueryobj, force) {
693        try {
694            if ((DEBUG && window.console && window.console.log) || force)
695                window.console.log(log + ': ' + jQueryobj);
696        } catch(ex) {}
697    };
698    function debugObject(log, jQueryobj, force) {
699        try {
700            if (!jQueryobj) jQueryobj=log;
701            debug(log, jQueryobj);
702            if ((DEBUG && window.console && window.console.log) || force)
703                window.console.debug(jQueryobj);
704        } catch(ex) {}
705    };
706})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.