Simple Machines Community Forum

Customizing SMF => Tips and Tricks => Topic started by: drewactual on January 12, 2019, 07:54:58 PM

Title: Mini-preview when hovering over post link
Post by: drewactual on January 12, 2019, 07:54:58 PM
big thanks to Mr. Will Boyd for the original script offered up here.

another thread was looking for something like this.  this works but will benefit from some refinement.  right now, here are some issues with this:

as mention in the code, here is how it's done:


here it is:

add this to your index.template 'under the fold', which is to say just above the </html> line.
Code: [Select]
echo '
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<link href="./jquery.minipreview.css" rel="stylesheet">
<script src="./jquery.minipreview.js"></script>
<script type="text/javascript"> $(function() { $(\'.hubber a\').miniPreview({ prefetch: \'none\' });
            });
</script>
<script src="xxxxxx-link to location and file you saved the below js-xxxxxx"></script>
';

make an external file, and save it with this-

Code: [Select]
/*
 * MiniPreview v0.9
 * @author  Will Boyd
 * Shared by Codegena
 */

(function($) {
    var PREFIX = 'mini-preview';
    // implemented as a jQuery plugin
    $.fn.miniPreview = function(options) {
        return this.each(function() {
            var $this = $(this);
            var miniPreview = $this.data(PREFIX);
            if (miniPreview) {
                miniPreview.destroy();
            }
            miniPreview = new MiniPreview($this, options);
            miniPreview.generate();
            $this.data(PREFIX, miniPreview);
        });
    };
    var MiniPreview = function($el, options) {
        this.$el = $el;
        this.$el.addClass(PREFIX + '-anchor');
        this.options = $.extend({}, this.defaultOptions, options);
        this.counter = MiniPreview.prototype.sharedCounter++;
    };
    MiniPreview.prototype = {
        sharedCounter: 0,
        defaultOptions: {
            width: 256,
            height: 144,
            scale: .25,
            prefetch: 'pageload'
        },
        generate: function() {
            this.createElements();
            this.setPrefetch();
        },
        createElements: function() {
            var $wrapper = $('<div>', { class: PREFIX + '-wrapper' });
            var $loading = $('<div>', { class: PREFIX + '-loading' });
            var $frame = $('<iframe>', { class: PREFIX + '-frame' });
            var $cover = $('<div>', { class: PREFIX + '-cover' });
            $wrapper.appendTo(this.$el).append($loading, $frame, $cover);
            // sizing
            $wrapper.css({
                width: this.options.width + 'px',
                height: this.options.height + 'px'
            });
            // scaling
            var inversePercent = 100 / this.options.scale;
            $frame.css({
                width: inversePercent + '%',
                height: inversePercent + '%',
                transform: 'scale(' + this.options.scale + ')'
            });
            // positioning
            var fontSize = parseInt(this.$el.css('font-size').replace('px', ''), 10)
            var top = (this.$el.height() + fontSize) / 2;
            var left = (this.$el.width() - $wrapper.outerWidth()) / 2;
            $wrapper.css({
                top: top + 'px',
                left: left + 'px'
            });
        },
        setPrefetch: function() {
            switch (this.options.prefetch) {
                case 'pageload':
                    this.loadPreview();
                    break;
                case 'parenthover':
                    this.$el.parent().one(this.getNamespacedEvent('mouseenter'),
                        this.loadPreview.bind(this));
                    break;
                case 'none':
                    this.$el.one(this.getNamespacedEvent('mouseenter'),
                        this.loadPreview.bind(this));
                    break;
                default:
                    throw 'Prefetch setting not recognized: ' + this.options.prefetch;
                    break;
            }
        },
        loadPreview: function() {
            this.$el.find('.' + PREFIX + '-frame')
                .attr('src', this.$el.attr('href'))
                .on('load', function() {
                    // some sites don't set their background color
                    $(this).css('background-color', '#fff');
                });
        },
        getNamespacedEvent: function(event) {
            return event + '.' + PREFIX + '_' + this.counter;
        },
        destroy: function() {
            this.$el.removeClass(PREFIX + '-anchor');
            this.$el.parent().off(this.getNamespacedEvent('mouseenter'));
            this.$el.off(this.getNamespacedEvent('mouseenter'));
            this.$el.find('.' + PREFIX + '-wrapper').remove();
        }
    };
})(jQuery);

and the css:
Code: [Select]
.mini-preview-anchor {
    display: inline-block;
    position: relative;
    white-space: nowrap;
}

.mini-preview-wrapper {
    -moz-box-sizing: content-box;
    box-sizing: content-box;
    position: absolute;
    overflow: hidden;
    z-index: -1;
    opacity: 0;
    margin-top: -4px;
    border: solid 1px #000;
    box-shadow: 4px 4px 6px rgba(0, 0, 0, .3);
    transition: z-index steps(1) .3s, opacity .3s, margin-top .3s;
}

.mini-preview-anchor:hover .mini-preview-wrapper {
    z-index: 2;
    opacity: 1;
    margin-top: 6px;
    transition: opacity .3s, margin-top .3s;
}

.mini-preview-loading, .mini-preview-cover {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;   
}

.mini-preview-loading {
    display: table;
    height: 100%;
    width: 100%;
    font-size: 1.25rem;
    text-align: center;
    color: #f5ead4;
    background-color: #59513f;
}

.mini-preview-loading::before {
    content: 'Loading...';
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}

.mini-preview-cover {
    background-color: rgba(0, 0, 0, 0); /* IE fix */
}

.mini-preview-frame {
    border: none;
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}

 that should be enough to get you off and running.  Some tweaking by someone who wants to use it, and it'll work out well.
Title: Re: Mini-preview when hovering over post link
Post by: Steve on January 13, 2019, 01:14:22 PM
I can't decide if this should be a 'Tip and Trick' or a mod ...
Title: Re: Mini-preview when hovering over post link
Post by: drewactual on January 13, 2019, 01:18:56 PM
Thats up to you guys who, the experts!  Its simple enough to implement and remove, like a mod, but requires some effort in the backend that a mod doesn't. Maybe someone will make it such?  I dont know.,,,. I was playing with it Friday night and Saturday morning as a tool with intnet to credit sources posted on my site, but it doesnt "flow" right for me and the juice isnt worth the squeeze to fix it where it will, at least for my purposes...

Someone here May find use for it, though.