-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcssvid.js
More file actions
163 lines (138 loc) · 4.45 KB
/
cssvid.js
File metadata and controls
163 lines (138 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
;
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
module.exports = factory()
} else if (typeof define === 'function' && define.amd) {
define([], factory)
} else {
root.cssvid = factory()
}
}(this, function () {
function loadImages (imageList, callback) {
var imagesToLoad = Object.keys(imageList).length
for (var key in imageList) {
var image = imageList[key]
image.img = new Image
image.img.onload = checkCallback.bind(image)
image.img.onerror = error.bind(this, 'Error loading image: ' + key + ' (' + image.url + ')')
image.img.src = image.url
}
function checkCallback () {
this.rows = Math.ceil(this.frames / this.cols)
if (--imagesToLoad === 0) {
callback()
}
}
}
function error (msg) {
console.error ? console.error(msg) : console.log(msg)
}
var now = typeof Date.now === 'function' ? Date.now : function () {
return (new Date).getTime()
}
function cssVid (opts) {
var root = typeof opts.root === 'string' ? document.querySelector(opts.root) : opts.root
if (!root) return error('No root element found.')
if (!opts.videos || opts.videos.length === 0) return error('Needs list of videos.')
var defaultOpts = {
width: root.clientWidth,
height: root.clientHeight,
autoPlay: true
}
var defaultVideoOpts = {
fps: 25
}
for (var option in defaultOpts) {
if (defaultOpts.hasOwnProperty(option) && !opts[option]) {
opts[option] = defaultOpts[option]
}
}
var videos = opts.videos
for (var videoKey in videos) {
var video = videos[videoKey]
if (!video.url || !video.frames || !video.cols) {
return error('Videos need {url, frames, cols}.')
}
for (option in defaultVideoOpts) {
if (defaultVideoOpts.hasOwnProperty(option) && !video[option]) {
video[option] = defaultVideoOpts[option]
}
}
}
var playContainer = document.createElement('div')
playContainer.style.cssText = 'width:' + opts.width + 'px;height:' + opts.height + 'px;overflow:hidden'
root.appendChild(playContainer)
function notloaded () {
error('Not loaded yet.')
}
var controls = {
play: notloaded,
pause: notloaded,
isPlaying: notloaded
}
loadImages(videos, startPlayer)
var transform = (function () {
var possibleTransforms = ['transform', 'WebkitTransform', 'MozTransform', 'msTransform', 'OTransform']
var img = new Image
for (var i = 0; i < possibleTransforms.length; i++) {
var p = possibleTransforms[i]
if (typeof img.style[p] !== 'undefined') return p
}
}())
function drawFrame (vid, frame) {
var x = -(frame % vid.cols) * opts.width
var y = -Math.floor(frame / vid.cols) * opts.height
vid.img.style[transform] = 'translate3d(' + x + 'px,' + y + 'px,0)'
}
function startPlayer () {
var isPlaying = !!opts.autoPlay
var reverse
var currVid
var delay
var rafId
var currFrame = 0
var startTime = 0
function play () {
if (!isPlaying) return
requestAnimationFrame(play)
var newFrame = Math.floor((now() - startTime) / delay)
newFrame %= currVid.frames
if (newFrame !== currFrame) {
currFrame = newFrame
drawFrame(currVid, reverse ? currVid.frames - currFrame : currFrame)
}
}
controls.play = function (key, playReverse) {
if (typeof key === 'undefined' && currVid) {
rafId = requestAnimationFrame(play)
isPlaying = true
return
}
if (!videos[key]) return error('Video not found: ' + key)
if (currVid !== videos[key]) {
currFrame = 0
startTime = now()
}
currVid = videos[key]
reverse = !!playReverse
delay = 1000 / currVid.fps
isPlaying = true
playContainer.innerHTML = ''
playContainer.appendChild(currVid.img)
currVid.img.width = currVid.cols * opts.width
currVid.img.height = currVid.rows * opts.height
rafId = requestAnimationFrame(play)
}
controls.pause = function () {
isPlaying = false
cancelAnimationFrame(rafId)
}
controls.isPlaying = function () {
return isPlaying
}
if (isPlaying) controls.play(Object.keys(videos)[0], false)
}
return controls
}
return cssVid
}))