Page Menu
Home
Code
Search
Configure Global Search
Log In
Files
F948951
SlideShow.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Subscribers
None
SlideShow.js
View Options
if
(
!
dojo
.
_hasResource
[
"dojox.image.SlideShow"
]){
//_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo
.
_hasResource
[
"dojox.image.SlideShow"
]
=
true
;
dojo
.
provide
(
"dojox.image.SlideShow"
);
//
// dojox.image.SlideShow courtesy Shane O Sullivan, licensed under a Dojo CLA
// For a sample usage, see http://www.skynet.ie/~sos/photos.php
//
// @author Copyright 2007 Shane O Sullivan (shaneosullivan1@gmail.com)
// @license Licensed under the Academic Free License 3.0 http://www.opensource.org/licenses/afl-3.0.php
//
// TODO: more cleanups
//
dojo
.
require
(
"dojo.fx"
);
dojo
.
require
(
"dijit._Widget"
);
dojo
.
require
(
"dijit._Templated"
);
dojo
.
declare
(
"dojox.image.SlideShow"
,
[
dijit
.
_Widget
,
dijit
.
_Templated
],
{
// imageHeight: Number
// The maximum height of an image
imageHeight
:
375
,
// imageWidth: Number
// The maximum width of an image.
imageWidth
:
500
,
// title: String
// the initial title of the SlideShow
title
:
""
,
// titleTemplate: String
// a way to customize the wording in the title. supported tags to be populated are:
// @title = the passed title of the image
// @current = the current index of the image
// @total = the total number of images in the SlideShow
//
// should add more?
titleTemplate
:
'@title <span class="slideShowCounterText">(@current of @total)</span>'
,
// noLink: Boolean
// Prevents the slideshow from putting an anchor link around the displayed image
// enables if true, though still will not link in absence of a url to link to
noLink
:
false
,
// loop: Boolean
// true/false - make the slideshow loop
loop
:
true
,
// hasNav: Boolean
// toggle to enable/disable the visual navigation controls
hasNav
:
true
,
// images: Array
// Contains the DOM nodes that individual images are stored in when loaded or loading.
images
:
[],
// pageSize: Number
// The number of images to request each time.
pageSize
:
20
,
// autoLoad: Boolean
// If true, then images are preloaded, before the user navigates to view them.
// If false, an image is not loaded until the user views it.
autoLoad
:
true
,
// fixedHeight: Boolean
// If true, the widget does not resize itself to fix the displayed image.
fixedHeight
:
false
,
// imageStore: Object
// Implementation of the dojo.data.api.Read API, which provides data on the images
// to be displayed.
imageStore
:
null
,
// linkAttr: String
// Defines the name of the attribute to request from the store to retrieve the
// URL to link to from an image, if any.
linkAttr
:
"link"
,
// imageLargeAttr: String
// Defines the name of the attribute to request from the store to retrieve the
// URL to the image.
imageLargeAttr
:
"imageUrl"
,
// titleAttr: String
// Defines the name of the attribute to request from the store to retrieve the
// title of the picture, if any.
titleAttr
:
"title"
,
// slideshowInterval: Number
// Time, in seconds, between image transitions during a slideshow.
slideshowInterval
:
3
,
templateString
:
"<div dojoAttachPoint=\"outerNode\" class=\"slideShowWrapper\">\n\t<div style=\"position:relative;\" dojoAttachPoint=\"innerWrapper\">\n\t\t<div class=\"slideShowNav\" dojoAttachEvent=\"onclick: _handleClick\">\n\t\t\t<div class=\"dijitInline slideShowTitle\" dojoAttachPoint=\"titleNode\">${title}</div>\n\t\t</div>\n\t\t<div dojoAttachPoint=\"navNode\" class=\"slideShowCtrl\" dojoAttachEvent=\"onclick: _handleClick\">\n\t\t\t<span dojoAttachPoint=\"navPrev\" class=\"slideShowCtrlPrev\"></span>\n\t\t\t<span dojoAttachPoint=\"navPlay\" class=\"slideShowCtrlPlay\"></span>\n\t\t\t<span dojoAttachPoint=\"navNext\" class=\"slideShowCtrlNext\"></span>\n\t\t</div>\n\t\t<div dojoAttachPoint=\"largeNode\" class=\"slideShowImageWrapper\"></div>\t\t\n\t\t<div dojoAttachPoint=\"hiddenNode\" class=\"slideShowHidden\"></div>\n\t</div>\n</div>\n"
,
// _tempImgPath: URL
// URL to the image to display when an image is not yet fully loaded.
_tempImgPath
:
dojo
.
moduleUrl
(
"dojox.image"
,
"resources/images/1pixel.gif"
),
// _imageCounter: Number
// A counter to keep track of which index image is to be loaded next
_imageCounter
:
0
,
// _tmpImage: DomNode
// The temporary image to show when a picture is loading.
_tmpImage
:
null
,
// _request: Object
// Implementation of the dojo.data.api.Request API, which defines the query
// parameters for accessing the store.
_request
:
null
,
postCreate
:
function
(){
// summary: Initilizes the widget, sets up listeners and shows the first image
this
.
inherited
(
"postCreate"
,
arguments
);
var
img
=
document
.
createElement
(
"img"
);
// FIXME: should API be to normalize an image to fit in the specified height/width?
img
.
setAttribute
(
"width"
,
this
.
imageWidth
);
img
.
setAttribute
(
"height"
,
this
.
imageHeight
);
if
(
this
.
hasNav
){
dojo
.
connect
(
this
.
outerNode
,
"onmouseover"
,
function
(
evt
){
try
{
_this
.
_showNav
();}
catch
(
e
){}
});
dojo
.
connect
(
this
.
outerNode
,
"onmouseout"
,
function
(
evt
){
try
{
_this
.
_hideNav
(
evt
);}
catch
(
e
){}
});
}
this
.
outerNode
.
style
.
width
=
this
.
imageWidth
+
"px"
;
img
.
setAttribute
(
"src"
,
this
.
_tempImgPath
);
var
_this
=
this
;
this
.
largeNode
.
appendChild
(
img
);
this
.
_tmpImage
=
img
;
this
.
_currentImage
=
img
;
this
.
_fitSize
(
true
);
this
.
_loadImage
(
0
,
function
(){
_this
.
showImage
(
0
);
});
this
.
_calcNavDimensions
();
},
setDataStore
:
function
(
dataStore
,
request
,
/*optional*/
paramNames
){
// summary: Sets the data store and request objects to read data from.
// dataStore:
// An implementation of the dojo.data.api.Read API. This accesses the image
// data.
// request:
// An implementation of the dojo.data.api.Request API. This specifies the
// query and paging information to be used by the data store
// paramNames:
// An object defining the names of the item attributes to fetch from the
// data store. The three attributes allowed are 'linkAttr', 'imageLargeAttr' and 'titleAttr'
this
.
reset
();
var
_this
=
this
;
this
.
_request
=
{
query
:
{},
start
:
((
request
.
start
)
?
request
.
start
:
0
),
count
:
((
request
.
count
)
?
request
.
count
:
this
.
pageSize
),
onBegin
:
function
(
count
,
request
){
_this
.
maxPhotos
=
count
;
}
};
if
(
request
.
query
){
dojo
.
mixin
(
this
.
_request
.
query
,
request
.
query
);
}
if
(
paramNames
&&
paramNames
.
imageLargeAttr
){
this
.
imageLargeAttr
=
paramNames
.
imageLargeAttr
;
}
var
_this
=
this
;
var
_complete
=
function
(
items
){
_this
.
showImage
(
0
);
_this
.
_request
.
onComplete
=
null
;
};
this
.
imageStore
=
dataStore
;
this
.
_request
.
onComplete
=
_complete
;
this
.
_request
.
start
=
0
;
this
.
imageStore
.
fetch
(
this
.
_request
);
},
reset
:
function
(){
// summary: Resets the widget to its initial state
// description: Removes all previously loaded images, and clears all caches.
while
(
this
.
largeNode
.
firstChild
){
this
.
largeNode
.
removeChild
(
this
.
largeNode
.
firstChild
);
}
this
.
largeNode
.
appendChild
(
this
.
_tmpImage
);
while
(
this
.
hiddenNode
.
firstChild
){
this
.
hiddenNode
.
removeChild
(
this
.
hiddenNode
.
firstChild
);
}
var
img
;
for
(
var
pos
=
0
;
pos
<
this
.
images
.
length
;
pos
++
){
img
=
this
.
images
[
pos
];
if
(
img
&&
img
.
parentNode
){
img
.
parentNode
.
removeChild
(
img
);
}
}
this
.
images
=
[];
this
.
isInitialized
=
false
;
this
.
_imageCounter
=
0
;
},
isImageLoaded
:
function
(
idx
){
// summary: Returns true if image at the specified index is loaded, false otherwise.
// idx:
// The number index in the data store to check if it is loaded.
return
this
.
images
&&
this
.
images
.
length
>
index
&&
this
.
images
[
idx
];
},
moveImageLoadingPointer
:
function
(
idx
){
// summary: If 'autoload' is true, this tells the widget to start loading
// images from the specified pointer.
// idx:
// The number index in the data store to start loading images from.
this
.
_imageCounter
=
idx
;
},
destroy
:
function
(){
// summary: Cleans up the widget when it is being destroyed
if
(
this
.
_slideId
)
{
this
.
_stop
();
}
this
.
inherited
(
"destroy"
,
arguments
);
},
showNextImage
:
function
(
inTimer
,
forceLoop
){
// summary: Changes the image being displayed to the next image in the data store
// inTimer: Boolean
// If true, a slideshow is active, otherwise the slideshow is inactive.
if
(
inTimer
&&
this
.
_timerCancelled
){
return
false
;}
if
(
this
.
imageIndex
+
1
>=
this
.
maxPhotos
){
if
(
inTimer
&&
(
this
.
loop
||
forceLoop
)){
this
.
imageIndex
=
-
1
;
}
else
{
if
(
this
.
_slideId
){
this
.
_stop
();
}
return
false
;
}
}
var
_this
=
this
;
this
.
showImage
(
this
.
imageIndex
+
1
,
function
(){
if
(
inTimer
){
_this
.
_startTimer
();
}
});
return
true
;
},
toggleSlideShow
:
function
(){
// summary: Switches the slideshow mode on and off.
if
(
this
.
_slideId
){
this
.
_stop
();
}
else
{
dojo
.
toggleClass
(
this
.
domNode
,
"slideShowPaused"
);
this
.
_timerCancelled
=
false
;
var
success
=
this
.
showNextImage
(
true
,
true
);
if
(
!
success
){
this
.
_stop
();
}
}
},
getShowTopicName
:
function
(){
// summary: Returns the topic id published to when an image is shown
// description:
// The information published is: index, title and url
return
(
this
.
widgetId
?
this
.
widgetId
:
this
.
id
)
+
"/imageShow"
;
},
getLoadTopicName
:
function
(){
// summary: Returns the topic id published to when an image finishes loading.
// description:
// The information published is the index position of the image loaded.
return
(
this
.
widgetId
?
this
.
widgetId
:
this
.
id
)
+
"/imageLoad"
;
},
showImage
:
function
(
idx
,
/* Function? */
callback
){
// summary: Shows the image at index 'idx'.
// idx: Number
// The position of the image in the data store to display
// callback: Function
// Optional callback function to call when the image has finished displaying.
if
(
!
callback
&&
this
.
_slideId
){
this
.
toggleSlideShow
();
}
var
_this
=
this
;
var
current
=
this
.
largeNode
.
getElementsByTagName
(
"div"
);
this
.
imageIndex
=
idx
;
var
showOrLoadIt
=
function
()
{
//If the image is already loaded, then show it.
if
(
_this
.
images
[
idx
]){
while
(
_this
.
largeNode
.
firstChild
){
_this
.
largeNode
.
removeChild
(
_this
.
largeNode
.
firstChild
);
}
_this
.
images
[
idx
].
style
.
opacity
=
0
;
_this
.
largeNode
.
appendChild
(
_this
.
images
[
idx
]);
_this
.
_currentImage
=
_this
.
images
[
idx
].
_img
;
_this
.
_fitSize
();
var
onEnd
=
function
(
a
,
b
,
c
)
{
var
img
=
_this
.
images
[
idx
].
firstChild
;
if
(
img
.
tagName
.
toLowerCase
()
!=
"img"
){
img
=
img
.
firstChild
;}
title
=
img
.
getAttribute
(
"title"
);
if
(
_this
.
_navShowing
){
_this
.
_showNav
(
true
);
}
dojo
.
publish
(
_this
.
getShowTopicName
(),
[{
index
:
idx
,
title
:
title
,
url
:
img
.
getAttribute
(
"src"
)
}]);
if
(
callback
)
{
callback
(
a
,
b
,
c
);
}
_this
.
_setTitle
(
title
);
};
dojo
.
fadeIn
({
node
:
_this
.
images
[
idx
],
duration
:
300
,
onEnd
:
onEnd
}).
play
();
}
else
{
//If the image is not loaded yet, load it first, then show it.
_this
.
_loadImage
(
idx
,
function
(){
dojo
.
publish
(
_this
.
getLoadTopicName
(),
[
idx
]);
_this
.
showImage
(
idx
,
callback
);
});
}
};
//If an image is currently showing, fade it out, then show
//the new image. Otherwise, just show the new image.
if
(
current
&&
current
.
length
>
0
){
dojo
.
fadeOut
({
node
:
current
[
0
],
duration
:
300
,
onEnd
:
function
(){
_this
.
hiddenNode
.
appendChild
(
current
[
0
]);
showOrLoadIt
();
}
}).
play
();
}
else
{
showOrLoadIt
();
}
},
_fitSize
:
function
(
force
){
// summary: Fits the widget size to the size of the image being shown,
// or centers the image, depending on the value of 'fixedHeight'
// force: Boolean
// If true, the widget is always resized, regardless of the value of 'fixedHeight'
if
(
!
this
.
fixedHeight
||
force
){
var
height
=
(
this
.
_currentImage
.
height
+
(
this
.
hasNav
?
20
:
0
));
dojo
.
style
(
this
.
innerWrapper
,
"height"
,
height
+
"px"
);
return
;
}
dojo
.
style
(
this
.
largeNode
,
"paddingTop"
,
this
.
_getTopPadding
()
+
"px"
);
},
_getTopPadding
:
function
(){
if
(
!
this
.
fixedHeight
){
return
0
;}
// summary: Returns the padding to place at the top of the image to center it vertically.
return
(
this
.
imageHeight
-
this
.
_currentImage
.
height
)
/
2
;
},
_loadNextImage
:
function
(){
//summary: Load the next unloaded image.
if
(
!
this
.
autoLoad
){
return
;
}
while
(
this
.
images
.
length
>=
this
.
_imageCounter
&&
this
.
images
[
this
.
_imageCounter
]){
this
.
_imageCounter
++
;
}
this
.
_loadImage
(
this
.
_imageCounter
);
},
_loadImage
:
function
(
idx
,
callbackFn
){
// summary: Load image at specified index
// description:
// This function loads the image at position 'idx' into the
// internal cache of images. This does not cause the image to be displayed.
// idx:
// The position in the data store to load an image from.
// callbackFn:
// An optional function to execute when the image has finished loading.
if
(
this
.
images
[
idx
]
||
!
this
.
_request
)
{
return
;
}
var
pageStart
=
idx
-
(
idx
%
this
.
pageSize
);
this
.
_request
.
start
=
pageStart
;
this
.
_request
.
onComplete
=
function
(
items
){
var
diff
=
idx
-
pageStart
;
if
(
items
&&
items
.
length
>
diff
){
loadIt
(
items
[
diff
]);
}
else
{
/* Squelch - console.log("Got an empty set of items"); */
}
}
var
_this
=
this
;
var
loadIt
=
function
(
item
){
var
url
=
_this
.
imageStore
.
getValue
(
item
,
_this
.
imageLargeAttr
);
var
img
=
document
.
createElement
(
"img"
);
var
div
=
document
.
createElement
(
"div"
);
div
.
_img
=
img
;
var
link
=
_this
.
imageStore
.
getValue
(
item
,
_this
.
linkAttr
);
if
(
!
link
||
_this
.
noLink
){
div
.
appendChild
(
img
);
}
else
{
var
a
=
document
.
createElement
(
"a"
);
a
.
setAttribute
(
"href"
,
link
);
a
.
setAttribute
(
"target"
,
"_blank"
);
div
.
appendChild
(
a
);
a
.
appendChild
(
img
);
}
div
.
setAttribute
(
"id"
,
_this
.
id
+
"_imageDiv"
+
idx
);
dojo
.
connect
(
img
,
"onload"
,
function
(){
_this
.
_fitImage
(
img
);
div
.
setAttribute
(
"width"
,
_this
.
imageWidth
);
div
.
setAttribute
(
"height"
,
_this
.
imageHeight
);
dojo
.
publish
(
_this
.
getLoadTopicName
(),
[
idx
]);
_this
.
_loadNextImage
();
if
(
callbackFn
){
callbackFn
();
}
});
_this
.
hiddenNode
.
appendChild
(
div
);
var
titleDiv
=
document
.
createElement
(
"div"
);
dojo
.
addClass
(
titleDiv
,
"slideShowTitle"
);
div
.
appendChild
(
titleDiv
);
_this
.
images
[
idx
]
=
div
;
img
.
setAttribute
(
"src"
,
url
);
var
title
=
_this
.
imageStore
.
getValue
(
item
,
_this
.
titleAttr
);
if
(
title
){
img
.
setAttribute
(
"title"
,
title
);
}
}
this
.
imageStore
.
fetch
(
this
.
_request
);
},
_stop
:
function
(){
// summary: Stops a running slide show.
if
(
this
.
_slideId
)
{
clearTimeout
(
this
.
_slideId
);
}
this
.
_slideId
=
null
;
this
.
_timerCancelled
=
true
;
dojo
.
removeClass
(
this
.
domNode
,
"slideShowPaused"
);
},
_prev
:
function
(){
// summary: Show the previous image.
// FIXME: either pull code from showNext/prev, or call it here
if
(
this
.
imageIndex
<
1
)
{
return
;}
this
.
showImage
(
this
.
imageIndex
-
1
);
},
_next
:
function
(){
// summary: Show the next image
this
.
showNextImage
();
},
_startTimer
:
function
(){
// summary: Starts a timeout to show the next image when a slide show is active
this
.
_slideId
=
setTimeout
(
"dijit.byId('"
+
this
.
id
+
"').showNextImage(true);"
,
this
.
slideshowInterval
*
1000
);
},
_calcNavDimensions
:
function
()
{
// summary:
// Calculates the dimensions of the navigation controls
dojo
.
style
(
this
.
navNode
,
"position"
,
"absolute"
);
//Place the navigation controls far off screen
dojo
.
style
(
this
.
navNode
,
"left"
,
"-10000px"
);
//Make the navigation controls visible
dojo
.
_setOpacity
(
this
.
navNode
,
99
);
this
.
navPlay
.
_size
=
dojo
.
marginBox
(
this
.
navPlay
);
this
.
navPrev
.
_size
=
dojo
.
marginBox
(
this
.
navPrev
);
this
.
navNext
.
_size
=
dojo
.
marginBox
(
this
.
navNext
);
dojo
.
_setOpacity
(
this
.
navNode
,
0
);
dojo
.
style
(
this
.
navNode
,
"position"
,
""
);
dojo
.
style
(
this
.
navNode
,
"left"
,
""
);
},
_setTitle
:
function
(
title
){
// summary: Sets the title of the image to be displayed
// title: String
// The String title of the image
this
.
titleNode
.
innerHTML
=
this
.
titleTemplate
.
replace
(
'@title'
,
title
)
.
replace
(
'@current'
,
String
(
Number
(
this
.
imageIndex
)
+
1
))
.
replace
(
'@total'
,
String
(
this
.
maxPhotos
));
},
_fitImage
:
function
(
img
)
{
// summary: Ensures that the image width and height do not exceed the maximum.
// img: Node
// The image DOM node to optionally resize
var
width
=
img
.
width
var
height
=
img
.
height
;
if
(
width
>
this
.
imageWidth
){
height
=
Math
.
floor
(
height
*
(
this
.
imageWidth
/
width
));
img
.
setAttribute
(
"height"
,
height
+
"px"
);
img
.
setAttribute
(
"width"
,
this
.
imageWidth
+
"px"
);
}
if
(
height
>
this
.
imageHeight
){
width
=
Math
.
floor
(
width
*
(
this
.
imageHeight
/
height
));
img
.
setAttribute
(
"height"
,
this
.
imageHeight
+
"px"
);
img
.
setAttribute
(
"width"
,
width
+
"px"
);
}
},
_handleClick
:
function
(
/* Event */
e
){
// summary: Performs navigation on the images based on users mouse clicks
// e:
// An Event object
switch
(
e
.
target
){
case
this
.
navNext
:
this
.
_next
();
break
;
case
this
.
navPrev
:
this
.
_prev
();
break
;
case
this
.
navPlay
:
this
.
toggleSlideShow
();
break
;
}
},
_showNav
:
function
(
force
){
// summary:
// Shows the navigation controls
// force: Boolean
// If true, the navigation controls are repositioned even if they are
// currently visible.
if
(
this
.
_navShowing
&&
!
force
){
return
;}
dojo
.
style
(
this
.
navNode
,
"marginTop"
,
"0px"
);
dojo
.
style
(
this
.
navPlay
,
"marginLeft"
,
"0px"
);
var
wrapperSize
=
dojo
.
marginBox
(
this
.
outerNode
);
var
margin
=
this
.
_currentImage
.
height
-
this
.
navPlay
.
_size
.
h
-
10
+
this
.
_getTopPadding
();
if
(
margin
>
this
.
_currentImage
.
height
){
margin
+=
10
;}
dojo
[
this
.
imageIndex
<
1
?
"addClass"
:
"removeClass"
](
this
.
navPrev
,
"slideShowCtrlHide"
);
dojo
[
this
.
imageIndex
+
1
>=
this
.
maxPhotos
?
"addClass"
:
"removeClass"
](
this
.
navNext
,
"slideShowCtrlHide"
);
var
_this
=
this
;
if
(
this
.
_navAnim
)
{
this
.
_navAnim
.
stop
();
}
if
(
this
.
_navShowing
){
return
;}
this
.
_navAnim
=
dojo
.
fadeIn
({
node
:
this
.
navNode
,
duration
:
300
,
onEnd
:
function
(){
_this
.
_navAnim
=
null
;}});
this
.
_navAnim
.
play
();
this
.
_navShowing
=
true
;
},
_hideNav
:
function
(
/* Event */
e
){
// summary: Hides the navigation controls
// e: Event
// The DOM Event that triggered this function
if
(
!
e
||
!
this
.
_overElement
(
this
.
outerNode
,
e
))
{
var
_this
=
this
;
if
(
this
.
_navAnim
)
{
this
.
_navAnim
.
stop
();
}
this
.
_navAnim
=
dojo
.
fadeOut
({
node
:
this
.
navNode
,
duration
:
300
,
onEnd
:
function
(){
_this
.
_navAnim
=
null
;}});
this
.
_navAnim
.
play
();
this
.
_navShowing
=
false
;
}
},
_overElement
:
function
(
/*DomNode*/
element
,
/*Event*/
e
){
// summary:
// Returns whether the mouse is over the passed element.
// Element must be display:block (ie, not a <span>)
//When the page is unloading, if this method runs it will throw an
//exception.
if
(
typeof
(
dojo
)
==
"undefined"
){
return
false
;}
element
=
dojo
.
byId
(
element
);
var
m
=
{
x
:
e
.
pageX
,
y
:
e
.
pageY
};
var
bb
=
dojo
.
_getBorderBox
(
element
);
var
absl
=
dojo
.
coords
(
element
,
true
);
var
left
=
absl
.
x
;
return
(
m
.
x
>=
left
&&
m
.
x
<=
(
left
+
bb
.
w
)
&&
m
.
y
>=
absl
.
y
&&
m
.
y
<=
(
top
+
bb
.
h
)
);
// boolean
}
});
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 26, 20:44 (2 d, 17 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24714
Default Alt Text
SlideShow.js (18 KB)
Attached To
rZEDHG ZedLegacy
Event Timeline
Log In to Comment