Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision for output and integral tooltips for display #17

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
44 changes: 43 additions & 1 deletion css/simple-slider.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,46 @@

border: 1px solid #aaa;
height: 4px;
}
}

.slider .tooltip {
background-color: #72A307;
border-radius: 3px;
color: #fff;
left: 100%;
margin-left: 15px;
padding: 1px 4px;
position: absolute;
}

.slider > .tooltip::before {
background-color: #72A307;
content: '';
display: block;
height: 7px;
left: -3px;
position: absolute;
top: 5px;
width: 7px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}

/**
* These are styles for when we're on a touch-capable device where we'd prefer
* a larger dragger
*/
html.touch .slider > .dragger {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 20px;
height: 32px;
width: 32px;
}

html.touch .slider > .tooltip {
top: 8px;
}
144 changes: 102 additions & 42 deletions js/simple-slider.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

(($, window) ->

# Adds a class 'touch' to the HTML tag if this is a touch-capable device,
# this allows our CSS to respond accordingly and, in this case, make the
# size of the dragger 2X the size.
if 'ontouchstart' in window
$('html').addClass 'touch'

#
# Main slider class
#
Expand Down Expand Up @@ -38,6 +44,10 @@
userSelect: "none"
boxSizing: "border-box"
.insertBefore @input
if @settings.tooltip
@tooltip = $("<div/>").addClass("tooltip")
@slider.append( @.tooltip)
@displayValue(Number(@input.val()))
@slider.attr("id", @input.attr("id") + "-slider") if @input.attr("id")

# Create the track
Expand Down Expand Up @@ -65,7 +75,7 @@
@slider.css
minHeight: @dragger.outerHeight()
marginLeft: @dragger.outerWidth()/2
marginRight: @dragger.outerWidth()/2
marginRight: @dragger.outerWidth()/2 + (56 if @settings.tooltip)

@track.css
marginTop: @track.outerHeight()/-2
Expand All @@ -74,67 +84,102 @@
marginTop: @dragger.outerWidth()/-2
marginLeft: @dragger.outerWidth()/-2

# Hook up drag/drop mouse events
@track
.mousedown (e) =>
return unless e.which == 1

@domDrag(e.pageX, e.pageY, true)
@dragging = true
false
# Hook up drag/drop mouse events AND touch events. Note, we use 'on'
# rather than 'bind', so this requires a more recent version of
# jQuery/Zepto.

@track.on 'touchstart mousedown', (evt) =>

# If this mouse down isn’t the left mouse button, ignore it. Also, If
# this is a mousedown event, we must preventDefault to prevent
# interacting accidentally with page content. We MUST allow the
# default action, however for touch-based input, otherwise, it will
# interfere with other gestures (page-scroll, pinch-to-zoom, etc.)

if evt.type == "mousedown"
unless evt.which is 1
return
evt.preventDefault()

@domDrag(evt, true)
@dragging = true


@dragger.on 'touchstart mousedown', (evt) =>

@dragger
.mousedown (e) =>
return unless e.which == 1
# See note above re: preventDefault() and left mouse button
if evt.type is "mousedown"
unless evt.which is 1
return
evt.preventDefault()

# We've started moving
@dragging = true
@dragger.addClass "dragging"
# We've started moving
@dragging = true
@dragger.addClass "dragging"

# Update the slider position
@domDrag(evt, true)

false


$("body").on 'touchmove mousemove', (evt) =>

# See note above re: preventDefault()
if evt.type is "mousemove"
evt.preventDefault();

if @dragging
# Update the slider position
@domDrag(e.pageX, e.pageY)
@domDrag(evt)

false
# Always show a pointer when dragging
$("body").css cursor: "pointer"

$("body")
.mousemove (e) =>
if @dragging
# Update the slider position
@domDrag(e.pageX, e.pageY)

# Always show a pointer when dragging
$("body").css cursor: "pointer"
$("body").on 'touchend mouseup', () =>

if @dragging
# Finished dragging
@dragging = false
@dragger.removeClass "dragging"

.mouseup (e) =>
if @dragging
# Finished dragging
@dragging = false
@dragger.removeClass "dragging"
# Revert the cursor
$("body").css cursor: "auto"

# Revert the cursor
$("body").css cursor: "auto"

# Set slider initial position
@pagePos = 0

# Fill in initial slider value
if @input.val() == ""
@value = @getRange().min
@input.val(@value)
@displayValue(@value)
else
@value = @nearestValidValue(@input.val())

@setSliderPositionFromValue(@value)

# We are ready to go
ratio = @valueToRatio(@value)
@input.trigger "slider:ready",
@input.trigger "slider:ready",
value: @value
ratio: ratio
position: ratio * @slider.outerWidth()
el: @slider

# Displays the value appropriately for the step value, if any, given.
displayValue: (value) ->
# If there is no step value, then we leave the value untouched.
# This will allow a default slider from 0->1 to work as it did previously.
if @settings.step && !isNaN(@settings.step)
precision = Math.max(0, Math.ceil(Math.log(1/@settings.step)/Math.log(10)));
value = value.toFixed(precision)
if (this.tooltip)
@tooltip.text(value)
@input.val(value)

# Set the ratio (value between 0 and 1) of the slider.
# Exposed via el.slider("setRatio", ratio)
setRatio: (ratio) ->
Expand Down Expand Up @@ -167,7 +212,20 @@
@valueChanged(value, ratio, "setValue")

# Respond to a dom drag event
domDrag: (pageX, pageY, animate=false) ->
domDrag: (evt, animate=false) ->
# jQuery users
if evt.originalEvent && evt.originalEvent.touches
{pageX, pageY} = evt.originalEvent.touches[0]

# For Zepto users
else if evt.touches
{pageX, pageY} = evt.touches[0]

# Not really sure when this would ever be used, but it probably should
# be here.
else
{pageX, pageY} = evt

# Normalize position within allowed range
pagePos = pageX - @slider.offset().left
pagePos = Math.min(@slider.outerWidth(), pagePos)
Expand All @@ -189,7 +247,7 @@
@setSliderPositionFromValue(value, animate)
else
@setSliderPosition(pagePos, animate)

# Set the slider position given a slider canvas position
setSliderPosition: (position, animate=false) ->
if animate and @settings.animate
Expand All @@ -201,7 +259,7 @@
setSliderPositionFromValue: (value, animate=false) ->
# Get the slide ratio from the value
ratio = @valueToRatio(value)

# Set the slider position
@setSliderPosition(ratio * @slider.outerWidth(), animate)

Expand Down Expand Up @@ -231,7 +289,7 @@
$.each @settings.allowedValues, ->
if closest == null || Math.abs(this - rawValue) < Math.abs(closest - rawValue)
closest = this

return closest
else if @settings.step
maxSteps = (range.max - range.min) / @settings.step
Expand All @@ -244,7 +302,7 @@

# Convert a value to a ratio
valueToRatio: (value) ->
if @settings.equalSteps
if @settings.equalSteps
# Get slider ratio for equal-step
for allowedVal, idx in @settings.allowedValues
if !closest? || Math.abs(allowedVal - value) < Math.abs(closest - value)
Expand All @@ -255,7 +313,7 @@
(closestIdx+0.5)/@settings.allowedValues.length
else
(closestIdx)/(@settings.allowedValues.length - 1)

else
# Get slider ratio for continuous values
range = @getRange()
Expand Down Expand Up @@ -283,15 +341,16 @@
@value = value

# Construct event data and fire event
eventData =
eventData =
value: value
ratio: ratio
position: ratio * @slider.outerWidth()
trigger: trigger
el: @slider

@displayValue(value);

@input
.val(value)
.trigger($.Event("change", eventData))
.trigger("slider:changed", eventData)

Expand All @@ -306,7 +365,7 @@
$(this).each ->
if settingsOrMethod and settingsOrMethod in publicMethods
obj = $(this).data("slider-object")

obj[settingsOrMethod].apply(obj, params)
else
settings = settingsOrMethod
Expand All @@ -328,6 +387,7 @@
settings.allowedValues = (parseFloat(x) for x in allowedValues.split(",")) if allowedValues
settings.range = $el.data("slider-range").split(",") if $el.data("slider-range")
settings.step = $el.data("slider-step") if $el.data("slider-step")
settings.tooltip = $el.data("slider-tooltip") if $el.data("slider-tooltip")
settings.snap = $el.data("slider-snap")
settings.equalSteps = $el.data("slider-equal-steps")
settings.theme = $el.data("slider-theme") if $el.data("slider-theme")
Expand Down
Loading