I'm working on adding some image editing tools using the Pixastic library. The idea is that the user can choose an aspect of the image or tool they want from a select box, then the tool will show up below the select box (I'm using select2) and the user can edit via a slider. Here's what I have so far:
# This seeds the select2 options list
imageToolsList = [
{id: 'bl', text: 'Blur'}
{id: 'bc', text: 'Brightness/Contrast'}
{id: 'ca', text: 'Color Adjust (RGB)'}
...
]
#Creates a select box and calls imageTooler function when the value of the box is changed
$(".image_tools_select").each ->
$(@).select2
placeholder: "Select an adjustment tool."
data: imageToolsList
$(@).on("change", (i) ->
imageTooler JSON.stringify(
val: i.val
clipName: $(@).closest('.clip').attr('id')
)
)
# The function called on the value that the select box is changed to
imageTooler = (i) ->
imageData = jQuery.parseJSON(i)
iId = imageData.val
imageClipName = imageData.clipName
newTool = "<div id=#{iId}><label>#{iId}</label><div class='slider#{iId}'></div></div>"
$("##{imageClipName}").find(".imagetoolfields").append newTool
This succeeds in appending the name of the editing tool and the correct slider div beneath the select box when a tool is chosen, but what I'd really like is dynamically create a slider function for that particular tool and image (there are multiple images on a page, each with their own editing toolbelt). Here's a slider function that works for a the 'Blur' tool:
$('.sliderbl').slider
min: 0
max: 5
value: 0.5
step: 0.1
range: "min"
slide: (event, ui) ->
$("#img_snapshot_16").pixastic("blurfast", {amount:ui.value})
Is there a way to expand the imageToolsList so that it looks something like:
imageToolsList = [
{id: 'bl', text: 'Blur', tool: $("##{imageClipName}").pixastic("blurfast", {amount:ui.value}), sliderVals: {min: 0, max: 5, value: 0.5, step: 0.1, range: "min"} }
...
]
and then dynamically create the jQuery slider functions for each tool in imageTooler, as is being done with the div and slider div?
Comments get a little tedious for anything complicated so I'll just go ahead and map it all out. I've made a few assumptions about what is defined where and when but I don't think the assumptions matter that much.
We'll start with a simplified case: just one object similar to what you have in
imageToolsList:I've tweaked the order a little bit and switched
toolto a function which returns a function. We don't want thepixasticcall to happen while you're defining the object literals inimageToolsList, makingtoola function allows us to defer thepixasticexecution until later. Since we (presumably) don't know whatimageClipNameshould be when we defineimageToolsList, we need another function to allow us to fill that in with, again, callingpixasticuntil even later; hence the function returning a function trick.Given one of these, how do we build a
slidercall? All we need to do is copysliderVals(to avoid changingimageToolsList) and fill in theslidefunction:toolis a function which returns a callback function sosliderDef.tool(imageClipName)gives us the appropriatecallback function.
If we have an
idand we want the appropriate entry fromimageToolList, then we have to go looking for it:The
forloop gives you an array back and then the[sliderDef]unwraps that array and leaves the single result insliderDef. If theimageToolListis longer then you'd want to short-circuit the loop and bail out as soon as you have a result:or better, rework the structure of
imageToolListto allow direct access byid:and then we can do things like this:
Or, if you prefer to be terse:
Update for the comments: If you have this:
Then you can build the stuff that slider2 wants like this: