简体   繁体   中英

How to make an input and a slider together

I am experimenting with CSS 3D transforms and I am trying to make sliders to handle the transforms. I came up with the editor of Three.js and I liked the idea of how it handles the position, rotation and scale of each object. It's an input and a slider in the same time or I just assume.

I haven't figured out how this works even after checking the source code and I'd like to give me a code snippet achieving the same functionality. Concretely, to have an input value and by just sliding the value right/left the object moves or by giving manually a value.

Note: I am not interested in the functionality of transforms only how such an input-slider can be done.

Thank you in advance.

The input s are in a div and are styled to look like lables: no border, no background. There is a style on the input s that changes the cursor into a slider-cursor ( cursor:col-resize ).

There is probably an onmousedown/onmouseup listener on the input s and then an onmousemove to get the mouse position while the mouse is down. I've found that putting one global onmousemove handler on the body works best. If you put the onmousemove event on a small element you wont get the events when the mouse is no longer over the element. As you can see in the three.js editor you can mousedown and then move the mouse anywhere on the page.

You probably need to use event.preventDefault() to make sure the onmousedown doesn't trigger a focus on the input element.

Here's a (very) simple jQuery plugin that emulates what you're after (for integers). I'll leave extending it to handle Floats as an exercise for you.

JSFiddle with added CSS for cursors at http://jsfiddle.net/yRmHS/3/

jQuery.fn.slidingInput = function (opts) {

    var defaults = {
        step: 1,        // Increment value
        min: 0,         // Minimum value
        max: 100,       // Maximum value
        tolerance: 2    // Mouse movement allowed within a simple click
    };

    return this.each(function () {
        var $el = $(this),
            options = $.extend({}, defaults, opts, this),
            distance = 0,
            initialValue = 0;

        function mouseDown () {
            distance = 0;
            initialValue = parseInt($el.val(), 10);

            $(document).on('mousemove', mouseMove).on('mouseup', mouseUp);

            return false;
        }

        function mouseMove (e) {
            var currentValue = parseInt($el.val(), 10),
                event = e.originalEvent,
                movementX = event.movementX || event.webkitMovementX || event.mozMovementX || 0,
                movementY = event.movementY || event.webkitMovementY || event.mozMovementY || 0;

            distance += (movementX - movementY) * options.step;

            $el.val(Math.min(options.max, Math.max(initialValue + distance, options.min)));
        }

        function mouseUp () {
            $(document).off('mousemove mouseup');

            if (Math.abs(distance) < options.tolerance) {
                $el.focus();
            }
        }

        $el.on('mousedown', mouseDown);
    });
};

// How to use it
$(function () {
    // Initialise plugin
    // HTML sample: <input type="number" class="slidable" step="2" value="50" min="0" max="100" />
    $('.slidable').slidingInput();

    // Accepts options object that override defaults, but step/min/max on input override options
    /*
        $('.slidable').slidingInput({
            step: 1,
            min: 0,
            max: 100,
            tolerance: 2
        });
    */
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM