├── .gitignore ├── test └── test.js ├── .travis.yml ├── dist ├── vidBg.min.css ├── vidBg.css ├── vidBg.min.js └── vidBg.js ├── src ├── vidBg.scss ├── vidBgTemplate.html └── vidBg.coffee ├── bower.json ├── package.json ├── demo └── index.html ├── karma.conf.js ├── gulpfile.coffee └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | bower_components 3 | node_modules 4 | .sass-cache 5 | .DS_Store -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | describe('sorting the list of users', function() { 2 | it('sorts in descending order by default', function() { 3 | var users = ['jack', 'igor', 'jeff']; 4 | expect(users.length).toBe(3); 5 | }); 6 | }); -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_install: 5 | - npm install -g bower 6 | - npm install -g gulp 7 | - npm install 8 | - bower install 9 | script: 10 | - gulp test 11 | after_script: 12 | - gulp coveralls -------------------------------------------------------------------------------- /dist/vidBg.min.css: -------------------------------------------------------------------------------- 1 | video.vidBg-body{background-size:cover;-webkit-transition:1s opacity;transition:1s opacity}video.vidBg-fade{opacity:.5}video.vidBg-fullScreen{position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;width:auto;height:auto}video.vidBg-autoWidth{width:100%;height:auto} -------------------------------------------------------------------------------- /src/vidBg.scss: -------------------------------------------------------------------------------- 1 | video.vidBg-body { 2 | background-size: cover; 3 | transition: 1s opacity; 4 | } 5 | 6 | video.vidBg-fade { 7 | opacity: .5; 8 | } 9 | 10 | video.vidBg-fullScreen { 11 | position: fixed; 12 | right: 0; 13 | bottom: 0; 14 | min-width: 100%; 15 | min-height: 100%; 16 | width: auto; 17 | height: auto; 18 | } 19 | 20 | video.vidBg-autoWidth { 21 | width: 100%; 22 | height: auto; 23 | } -------------------------------------------------------------------------------- /dist/vidBg.css: -------------------------------------------------------------------------------- 1 | video.vidBg-body { 2 | background-size: cover; 3 | -webkit-transition: 1s opacity; 4 | transition: 1s opacity; 5 | } 6 | 7 | video.vidBg-fade { 8 | opacity: .5; 9 | } 10 | 11 | video.vidBg-fullScreen { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | min-width: 100%; 16 | min-height: 100%; 17 | width: auto; 18 | height: auto; 19 | } 20 | 21 | video.vidBg-autoWidth { 22 | width: 100%; 23 | height: auto; 24 | } 25 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-vidbg", 3 | "version": "0.0.12", 4 | "authors": [ 5 | "2013gangli@gmail.com" 6 | ], 7 | "description": "Video background", 8 | "keywords": [ 9 | "angular", 10 | "video", 11 | "background" 12 | ], 13 | "dependencies": { 14 | "angular": "*" 15 | }, 16 | "devDependencies": { 17 | "angular-mocks": "*" 18 | }, 19 | "license": "MIT", 20 | "main": [ 21 | "dist/vidBg.css", 22 | "dist/vidBg.js" 23 | ], 24 | "ignore": [ 25 | "**/.*", 26 | "node_modules", 27 | "bower_components", 28 | "test", 29 | "src", 30 | "Gruntfile.coffee", 31 | "gulpfile.coffee" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /src/vidBgTemplate.html: -------------------------------------------------------------------------------- 1 |
video element."}).directive("vidBg",["$log","vidBgDefaults",function(e,r){return{restrict:"E",templateUrl:"vidBgTemplate.html",scope:{resources:"=",fullScreen:"=",poster:"=",pausePlay:"=",playInfo:"="},compile:function(e,n){var t,a,o,l;return o=e.children().children(),l=o.eq(0),a=function(e){var r;return r={},angular.isArray(e)&&angular.forEach(e,function(e,n){angular.isString(e)&&(-1!==e.toUpperCase().indexOf(".WEBM",e.length-".WEBM".length)?r.webm=e:-1!==e.toUpperCase().indexOf(".MP4",e.length-".MP4".length)?r.mp4=e:-1!==e.toUpperCase().indexOf(".OGV",e.length-".OGV".length)?r.ogv=e:-1!==e.toUpperCase().indexOf(".SWF",e.length-".SWF".length)&&(r.swf=e))}),r},t=function(e){return o.children().eq(0).attr("src",e.webm?e.webm:""),o.children().eq(1).attr("src",e.mp4?e.mp4:""),o.children().eq(2).attr("src",e.ogv?e.ogv:""),o.children().eq(3).children().eq(0).attr("value",e.swf?e.swf:"")},{pre:function(e,n,t){e.posterUrl=e.poster?e.poster:"",e.resourceMap=a(e.resources),e.muted=e.$parent.$eval(t.muted)||r.muted,e.control=e.$parent.$eval(t.control)||r.control,e.loop=e.$parent.$eval(t.loop)||r.loop,e.autoPlay=e.$parent.$eval(t.autoPlay)||r.autoPlay,e.zIndex=+e.$parent.$eval(t.zIndex)||r.zIndex,e.errorMsg=e.$parent.$eval(t.errorMsg)||r.errorMsg,e.playInfo={buffer:0,played:0}},post:function(e,r,n){return t(e.resourceMap),e.loop||l.on("ended",function(){return this.addClass("vidBg-fade")}),e.$watch("pausePlay",function(e){return e?(l.addClass("vidBg-fade"),l[0].pause()):(l.removeClass("vidBg-fade"),l[0].play())}),e.$watch("resources",function(e){return l.removeClass("vidBg-fade"),l[0].pause(),t(a(e)),l[0].load(),l[0].play()},!0),l.on("progress",function(){return this.buffered.length>0?(e.playInfo.buffer=this.buffered.end(0)/this.duration,e.$apply()):void 0}),l.on("timeupdate",function(){return e.playInfo.played=this.currentTime/this.duration,e.$apply()})}}}}}])}).call(this),function(e){try{e=angular.module("vidBgTemplate")}catch(r){e=angular.module("vidBgTemplate",[])}e.run(["$templateCache",function(e){e.put("vidBgTemplate.html",'video element.'
11 | .directive 'vidBg', ['$log', 'vidBgDefaults', ($log, vidBgDefaults) ->
12 | restrict: 'E'
13 | templateUrl: 'vidBgTemplate.html'
14 | scope:
15 | resources: '='
16 | fullScreen: '='
17 | poster: '='
18 | pausePlay: '='
19 | playInfo: '='
20 | compile: (ele, attr) ->
21 | vid = do ele.children().children
22 | vidEle = vid.eq 0
23 | processResources = (resources) ->
24 | resourceMap = {}
25 | if angular.isArray resources
26 | angular.forEach resources, (ele, index) ->
27 | if angular.isString ele
28 | if ele.toUpperCase().indexOf(
29 | '.WEBM', ele.length - '.WEBM'.length) isnt -1
30 | resourceMap.webm = ele
31 | return
32 | else if ele.toUpperCase().indexOf(
33 | '.MP4', ele.length - '.MP4'.length) isnt -1
34 | resourceMap.mp4 = ele
35 | return
36 | else if ele.toUpperCase().indexOf(
37 | '.OGV', ele.length - '.OGV'.length) isnt -1
38 | resourceMap.ogv = ele
39 | return
40 | else if ele.toUpperCase().indexOf(
41 | '.SWF', ele.length - '.SWF'.length) isnt -1
42 | resourceMap.swf = ele
43 | return
44 | return resourceMap
45 | appendResourceToDom = (resourceMap) ->
46 | # Need to mannually add src because of
47 | # https://docs.angularjs.org/api/ng/service/$sce
48 | vid.children()
49 | .eq(0).attr('src', if resourceMap.webm then resourceMap.webm else '')
50 |
51 | vid.children()
52 | .eq(1).attr('src', if resourceMap.mp4 then resourceMap.mp4 else '')
53 |
54 | vid.children()
55 | .eq(2).attr('src', if resourceMap.ogv then resourceMap.ogv else '')
56 |
57 | vid.children()
58 | .eq(3).children().eq(0)
59 | .attr('value', if resourceMap.swf then resourceMap.swf else '')
60 |
61 | pre: (scope, ele, attr) ->
62 | scope.posterUrl = if scope.poster then scope.poster else ''
63 | scope.resourceMap = processResources scope.resources
64 | scope.muted = (scope.$parent.$eval attr.muted) ||
65 | vidBgDefaults.muted
66 | scope.control = (scope.$parent.$eval attr.control) ||
67 | vidBgDefaults.control
68 | scope.loop = (scope.$parent.$eval attr.loop) ||
69 | vidBgDefaults.loop
70 | scope.autoPlay = (scope.$parent.$eval attr.autoPlay) ||
71 | vidBgDefaults.autoPlay
72 | scope.zIndex = +(scope.$parent.$eval attr.zIndex) ||
73 | vidBgDefaults.zIndex
74 | scope.errorMsg = (scope.$parent.$eval attr.errorMsg) ||
75 | vidBgDefaults.errorMsg
76 | scope.playInfo =
77 | buffer: 0
78 | played: 0
79 | return
80 |
81 | post: (scope, ele, attr) ->
82 | appendResourceToDom scope.resourceMap
83 | if !scope.loop
84 | vidEle.on 'ended', ->
85 | this.addClass 'vidBg-fade'
86 |
87 | scope.$watch 'pausePlay', (val) ->
88 | if (val)
89 | vidEle.addClass 'vidBg-fade'
90 | do vidEle[0].pause
91 | else
92 | vidEle.removeClass 'vidBg-fade'
93 | do vidEle[0].play
94 | scope.$watch 'resources', (val) ->
95 | vidEle.removeClass 'vidBg-fade'
96 | do vidEle[0].pause
97 | appendResourceToDom processResources val
98 | do vidEle[0].load
99 | do vidEle[0].play
100 | , true
101 |
102 | vidEle.on 'progress', ->
103 | if this.buffered.length > 0
104 | scope.playInfo.buffer = this.buffered.end(0) / this.duration
105 | do scope.$apply
106 | vidEle.on 'timeupdate', ->
107 | scope.playInfo.played = this.currentTime / this.duration
108 | do scope.$apply
109 |
110 | ]
111 |
--------------------------------------------------------------------------------
/dist/vidBg.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | angular.module('ngVidBg', ['vidBgTemplate']).constant('vidBgDefaults', {
3 | muted: true,
4 | control: false,
5 | loop: true,
6 | autoPlay: true,
7 | zIndex: -1000,
8 | errorMsg: 'Your browser does not support the video element.'
9 | }).directive('vidBg', [
10 | '$log', 'vidBgDefaults', function($log, vidBgDefaults) {
11 | return {
12 | restrict: 'E',
13 | templateUrl: 'vidBgTemplate.html',
14 | scope: {
15 | resources: '=',
16 | fullScreen: '=',
17 | poster: '=',
18 | pausePlay: '=',
19 | playInfo: '='
20 | },
21 | compile: function(ele, attr) {
22 | var appendResourceToDom, processResources, vid, vidEle;
23 | vid = ele.children().children();
24 | vidEle = vid.eq(0);
25 | processResources = function(resources) {
26 | var resourceMap;
27 | resourceMap = {};
28 | if (angular.isArray(resources)) {
29 | angular.forEach(resources, function(ele, index) {
30 | if (angular.isString(ele)) {
31 | if (ele.toUpperCase().indexOf('.WEBM', ele.length - '.WEBM'.length) !== -1) {
32 | resourceMap.webm = ele;
33 | } else if (ele.toUpperCase().indexOf('.MP4', ele.length - '.MP4'.length) !== -1) {
34 | resourceMap.mp4 = ele;
35 | } else if (ele.toUpperCase().indexOf('.OGV', ele.length - '.OGV'.length) !== -1) {
36 | resourceMap.ogv = ele;
37 | } else if (ele.toUpperCase().indexOf('.SWF', ele.length - '.SWF'.length) !== -1) {
38 | resourceMap.swf = ele;
39 | }
40 | }
41 | });
42 | }
43 | return resourceMap;
44 | };
45 | appendResourceToDom = function(resourceMap) {
46 | vid.children().eq(0).attr('src', resourceMap.webm ? resourceMap.webm : '');
47 | vid.children().eq(1).attr('src', resourceMap.mp4 ? resourceMap.mp4 : '');
48 | vid.children().eq(2).attr('src', resourceMap.ogv ? resourceMap.ogv : '');
49 | return vid.children().eq(3).children().eq(0).attr('value', resourceMap.swf ? resourceMap.swf : '');
50 | };
51 | return {
52 | pre: function(scope, ele, attr) {
53 | scope.posterUrl = scope.poster ? scope.poster : '';
54 | scope.resourceMap = processResources(scope.resources);
55 | scope.muted = (scope.$parent.$eval(attr.muted)) || vidBgDefaults.muted;
56 | scope.control = (scope.$parent.$eval(attr.control)) || vidBgDefaults.control;
57 | scope.loop = (scope.$parent.$eval(attr.loop)) || vidBgDefaults.loop;
58 | scope.autoPlay = (scope.$parent.$eval(attr.autoPlay)) || vidBgDefaults.autoPlay;
59 | scope.zIndex = +(scope.$parent.$eval(attr.zIndex)) || vidBgDefaults.zIndex;
60 | scope.errorMsg = (scope.$parent.$eval(attr.errorMsg)) || vidBgDefaults.errorMsg;
61 | scope.playInfo = {
62 | buffer: 0,
63 | played: 0
64 | };
65 | },
66 | post: function(scope, ele, attr) {
67 | appendResourceToDom(scope.resourceMap);
68 | if (!scope.loop) {
69 | vidEle.on('ended', function() {
70 | return this.addClass('vidBg-fade');
71 | });
72 | }
73 | scope.$watch('pausePlay', function(val) {
74 | if (val) {
75 | vidEle.addClass('vidBg-fade');
76 | return vidEle[0].pause();
77 | } else {
78 | vidEle.removeClass('vidBg-fade');
79 | return vidEle[0].play();
80 | }
81 | });
82 | scope.$watch('resources', function(val) {
83 | vidEle.removeClass('vidBg-fade');
84 | vidEle[0].pause();
85 | appendResourceToDom(processResources(val));
86 | vidEle[0].load();
87 | return vidEle[0].play();
88 | }, true);
89 | vidEle.on('progress', function() {
90 | if (this.buffered.length > 0) {
91 | scope.playInfo.buffer = this.buffered.end(0) / this.duration;
92 | return scope.$apply();
93 | }
94 | });
95 | return vidEle.on('timeupdate', function() {
96 | scope.playInfo.played = this.currentTime / this.duration;
97 | return scope.$apply();
98 | });
99 | }
100 | };
101 | }
102 | };
103 | }
104 | ]);
105 |
106 | }).call(this);
107 |
108 | (function(module) {
109 | try {
110 | module = angular.module('vidBgTemplate');
111 | } catch (e) {
112 | module = angular.module('vidBgTemplate', []);
113 | }
114 | module.run(['$templateCache', function($templateCache) {
115 | $templateCache.put('vidBgTemplate.html',
116 | '