Skip to content

Add touch support #20

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

Open
wants to merge 4 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;
}
143 changes: 103 additions & 40 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,118 @@
marginTop: @dragger.outerWidth()/-2
marginLeft: @dragger.outerWidth()/-2

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

# 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', (e) =>

# 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 e.type == "mousedown"
unless e.which is 1
return
e.preventDefault()

if e.originalEvent && e.originalEvent.touches # jQuery users
@domDrag(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY)
else if e.touches # For Zepto users
@domDrag(e.touches[0].pageX, e.touches[0].pageY)
else
@domDrag(e.pageX, e.pageY, true)
@dragging = true
false

@dragger
.mousedown (e) =>
return unless e.which == 1
@dragging = true

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

# Update the slider position
@domDrag(e.pageX, e.pageY)
@dragger.on 'touchstart mousedown', (e) =>

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

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

# Update the slider position
if e.originalEvent && e.originalEvent.touches # jQuery users
@domDrag(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY)
else if e.touches # For Zepto users
@domDrag(e.touches[0].pageX, e.touches[0].pageY)
else
@domDrag(e.pageX, e.pageY, true)

false


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

$("body")
.mousemove (e) =>
if @dragging
# Update the slider position
# See note above re: preventDefault()
if e.type is "mousemove"
e.preventDefault();

if @dragging
# Update the slider position
if e.originalEvent && e.originalEvent.touches # jQuery users
@domDrag(e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY)
else if e.touches # For Zepto users
@domDrag(e.touches[0].pageX, e.touches[0].pageY)
else
@domDrag(e.pageX, e.pageY)

# Always show a pointer when dragging
$("body").css cursor: "pointer"
# 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 @@ -189,7 +250,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 +262,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 +292,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 +305,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 +316,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 +344,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 +368,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 +390,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