├── background.html ├── changelog.txt ├── coordinator.html ├── core.js ├── overlay.html ├── plugins ├── clock.js ├── obschat.js ├── obschatmod.js └── twitch.js ├── readme.txt ├── standby.html ├── styles └── default │ ├── default.css │ └── default │ ├── bg-box.png │ └── bg-wall.png └── user-example ├── config.html ├── credits.txt ├── img ├── gfx-chat.png ├── gfx-viewers.png ├── icon-twitch.png ├── icon-twitter.png └── icon-youtube.png └── readme.txt /background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | 2015-05-09 13:04 +0000 2 | - updated readme 3 | 4 | 5 | 2015-05-09 12:59 +0000 6 | - added statistics event recording 7 | 8 | 9 | 2015-03-26 16:58 +0000 10 | - obschatmod: handling relative script url 11 | 12 | 13 | 2015-02-02 15:11 +0000 14 | - updated readme with the illustrated guide blog post url 15 | 16 | 17 | 2015-01-29 13:30 +0000 18 | - fixed typo in readme 19 | 20 | 21 | 2015-01-28 19:59 +0000 22 | - Twitch plugin: vars are now initiated at startup and timeout is handled 23 | 24 | 25 | 2015-01-28 19:57 +0000 26 | - Improved fetchUrl timeout code 27 | 28 | 29 | 2015-01-28 19:47 +0000 30 | - Added default timeout of 20 seconds to fetchUrl 31 | 32 | 33 | 2015-01-28 19:40 +0000 34 | - Added timeout handling in fetchUrl 35 | 36 | 37 | 2015-01-28 19:32 +0000 38 | - Created main styles folder for possible future themes 39 | 40 | 41 | 2015-01-24 16:15 +0000 42 | - fixed strict null/zero value check 43 | 44 | 45 | 2015-01-24 15:33 +0000 46 | - plugin update: twitch: added value check 47 | 48 | 49 | 2015-01-24 04:09 +0000 50 | - fixed missing chat elements in obschatmod, mostly user icons 51 | 52 | 53 | 2015-01-24 02:31 +0000 54 | - fixed code injection logic in obschatmod 55 | 56 | 57 | 2015-01-24 02:06 +0000 58 | - fixed error in obschatmod description 59 | 60 | 61 | 2015-01-24 02:02 +0000 62 | - added obschatmod 63 | - added basic descriptions to plugins 64 | - updated user-example config for obschatmod 65 | 66 | 67 | 2015-01-20 23:48 +0000 68 | - updated user-example style 69 | 70 | 71 | 2015-01-19 17:03 +0000 72 | - updated user-example config 73 | 74 | 75 | 2015-01-19 16:45 +0000 76 | - fetchurl error handling 77 | - user plugins now use the following location: user/plugins/ 78 | - updated twitch plugin, handling null values 79 | - updated style handling 80 | 81 | 82 | 2015-01-18 09:46 +0000 83 | - added some comments 84 | 85 | 86 | 2015-01-17 16:20 +0000 87 | - updated documents with extra wrapper elements 88 | 89 | 90 | 2015-01-17 05:50 +0000 91 | - initial commit -------------------------------------------------------------------------------- /coordinator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /core.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | TODO 3 | - debug(): create shared queue, render in coordinator 4 | 5 | 6 | NOTES 7 | window.localStorage and window.sessionStorage { 8 | long length; // Number of items stored 9 | string key(long index); // Name of the key at index 10 | string getItem(string key); // Get value of the key 11 | void setItem(string key, string data); // Add a new key with value data 12 | void removeItem(string key); // Remove the item key 13 | void clear(); // Clear the storage 14 | }; 15 | *******************************************************************************/ 16 | 17 | 18 | var obsOverlay = { 19 | 20 | 21 | //*********************************************************** internal config 22 | cfg : { 23 | dir_base : document.location.href.match(/^(.*\/)/)[1], 24 | dir_user : 'user/', 25 | dir_user_plugins : 'user/plugins/', 26 | dir_user_styles : 'user/styles/', 27 | 28 | file_config : 'user/config.html', 29 | 30 | url_stat : 'http://spenibus.net/piwik/piwik.php?rec=1&idsite=2&url=' 31 | +encodeURIComponent('http://obs-overlay/'), 32 | }, 33 | 34 | 35 | 36 | 37 | //********************************************************************* debug 38 | debug : function(str) { 39 | 40 | var debugNode = document.getElementById('debug'); 41 | 42 | if(!debugNode) { 43 | return; 44 | } 45 | 46 | var node = document.createElement('div'); 47 | node.innerHTML = '' 48 | +''+(new Date().toISOString().replace('T',' ').slice(0,-5))+' ' 49 | +''+str+''; 50 | debugNode.insertBefore(node, debugNode.firstChild); 51 | 52 | // trim (for memory) 53 | while(debugNode.childNodes.length > 100) { 54 | debugNode.removeChild(debugNode.childNodes[debugNode.childNodes.length - 1]); 55 | } 56 | }, 57 | 58 | 59 | 60 | 61 | //******************************************** fetch node content by selector 62 | getNode : function(selector) { 63 | 64 | var nodes = document.querySelectorAll(selector); 65 | 66 | if(nodes) { 67 | var out = []; 68 | for(var i=0; i var2 > var1) 503 | if(++depth > 99) { 504 | return; 505 | } 506 | 507 | 508 | // querySelectorAll should return nodes in "depth-first pre-order traversal" 509 | // incremental looping should therefore not skip nodes in case of subtree modification 510 | var nodes = container.querySelectorAll('[data-var]'); 511 | var timestampData = obsOverlay.get('varsTimestamp'); 512 | 513 | 514 | for(var i=0; i 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 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /plugins/clock.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This plugin provides a clock. 3 | 4 | 5 | available variables: 6 | clock.date yyyy-mm-dd 7 | clock.time hh:mm:ss 8 | clock.zone +zzzz 9 | clock.dateTime yyyy-mm-dd hh:mm:ss 10 | clock.dateTimeZone yyyy-mm-dd hh:mm:ss +zzzz 11 | *******************************************************************************/ 12 | (function() { 13 | 14 | 15 | //*************************************************************************** 16 | function update() { 17 | 18 | var date = new Date(); 19 | 20 | var dateStr = 21 | date.getFullYear()+'-'+ 22 | ('00'+(date.getMonth()+1)).slice(-2)+'-'+ 23 | ('00'+date.getDate()).slice(-2); 24 | 25 | var timeStr = 26 | ('00'+date.getHours()).slice(-2)+':'+ 27 | ('00'+date.getMinutes()).slice(-2)+':'+ 28 | ('00'+date.getSeconds()).slice(-2); 29 | 30 | var zoneStr = date.getTimezoneOffset(); 31 | zoneStr = (zoneStr < 0 ? '+' : '-')+('0'+(Math.abs(zoneStr/60)*100 + zoneStr%60)).slice(-4); 32 | 33 | 34 | // export vars 35 | obsOverlay.setVar('clock.date', dateStr); 36 | obsOverlay.setVar('clock.time', timeStr); 37 | obsOverlay.setVar('clock.zone', zoneStr); 38 | obsOverlay.setVar('clock.dateTime', dateStr+' '+timeStr); 39 | obsOverlay.setVar('clock.dateTimeZone', dateStr+' '+timeStr+' '+zoneStr); 40 | } 41 | 42 | // at start 43 | update(); 44 | 45 | // on schedule 46 | setInterval(update, 100); 47 | 48 | })(); -------------------------------------------------------------------------------- /plugins/obschat.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This plugin allows to easily include NightDev's OBS Chat. 3 | 4 | 5 | required variable from user config: 6 | obschat.channel name of the twitch channel 7 | 8 | 9 | available variables: 10 | obschat.iframe.clear 11 | obschat.iframe.light 12 | obschat.iframe.dark 13 | *******************************************************************************/ 14 | (function() { 15 | 16 | 17 | //*************************************************************************** 18 | function update() { 19 | 20 | // get twitch channel from user config 21 | var channel = obsOverlay.getVar('obschat.channel'); 22 | 23 | 24 | // no channel 25 | if(!channel) { 26 | return; 27 | } 28 | 29 | 30 | // lowercase 31 | channel = channel.toLowerCase(); 32 | 33 | 34 | // vars 35 | obsOverlay.setVar( 36 | 'obschat.iframe.clear', 37 | '' 38 | ); 39 | obsOverlay.setVar( 40 | 'obschat.iframe.light', 41 | '' 42 | ); 43 | obsOverlay.setVar( 44 | 'obschat.iframe.dark', 45 | '' 46 | ); 47 | 48 | 49 | 50 | } 51 | 52 | // at start 53 | update(); 54 | 55 | // on schedule 56 | setInterval(update, 5000); 57 | 58 | })(); -------------------------------------------------------------------------------- /plugins/obschatmod.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This plugin extend NightDev's OBS Chat. 3 | 4 | 5 | modifications: 6 | time display 7 | compact style 8 | zebra highlighting (even/odd rows) 9 | 10 | 11 | required variable from user config: 12 | obschatmod.cfg.channel name of the twitch channel 13 | obschatmod.cfg.compact enable compact style 14 | "1" to enable 15 | obschatmod.cfg.zebra enable zebra highlighting 16 | "1" to enable 17 | obschatmod.cfg.timeFormat time format to use 18 | "d" for date as "2015-12-31" 19 | "t" for time as "23:59:59" 20 | "z" for timezone as "+1200" 21 | example: "d t" = "2015-12-31 23:59:59" 22 | obschatmod.cfg.style style to use 23 | "clear", "light", "dark" 24 | 25 | 26 | available variables: 27 | obschatmod.iframe 28 | *******************************************************************************/ 29 | obschatmod = { 30 | 31 | 32 | //*************************************************************************** 33 | baseUrl : 'https://www.nightdev.com/hosted/obschat/', 34 | 35 | 36 | 37 | 38 | //*************************************************************************** 39 | chatWindow : null, 40 | 41 | 42 | 43 | 44 | //*************************************************************************** 45 | vars : {}, 46 | 47 | 48 | 49 | 50 | //*************************************************************************** 51 | update : function() { 52 | 53 | 54 | var varsUser = obsOverlay.getVar('obschatmod.cfg'); 55 | 56 | 57 | // no channel 58 | if(!varsUser.channel) { 59 | return; 60 | } 61 | 62 | 63 | // lowercase 64 | varsUser.channel = varsUser.channel.toLowerCase(); 65 | 66 | 67 | // init 68 | var refresh = false; 69 | 70 | 71 | // check for vars change 72 | for(var i in varsUser) { 73 | if(varsUser[i] != obschatmod.vars[i]) { 74 | refresh = true; 75 | } 76 | } 77 | 78 | 79 | // save new vars 80 | obschatmod.vars = varsUser; 81 | 82 | 83 | // on refresh (init or config update) 84 | if(refresh) { 85 | 86 | 87 | // get chat document source 88 | var html = obsOverlay.fetchUrl(obschatmod.baseUrl); 89 | 90 | 91 | // make doc from source 92 | var parser = new DOMParser(); 93 | var doc = parser.parseFromString(html, "text/html"); 94 | 95 | 96 | // delete load 97 | doc.head.innerHTML = doc.head.innerHTML.replace(/Chat\.load\(.*\n/i, '\n'); 98 | 99 | 100 | // complete url of relative scripts (because the location is a data string) 101 | var scriptNodes = doc.querySelectorAll('script'); 102 | for(var i=0; i' 228 | +'.chat_line .header {text-align:right;}' 229 | +'.chat_line .header .time {font-size:90%; opacity:0.5;}' 230 | +'.chat_line.zebraEven {}' 231 | +'.chat_line.zebraOdd {background-color:rgba(0,0,0,0.2);}' 232 | +'' 233 | 234 | 235 | 236 | // add compact style 237 | if(obschatmod.vars.compact == '1') { 238 | doc.body.innerHTML += '' 239 | +'' 244 | } 245 | 246 | 247 | // add some code 248 | doc.body.innerHTML += '' 249 | +''; 266 | 267 | 268 | // turn source into string 269 | var docSrc = ''+doc.documentElement.innerHTML+''; 270 | var docSrcData64 = 'data:text/html;base64,'+window.btoa(docSrc); 271 | 272 | 273 | // get inline style 274 | var dataStyle = doc.getElementsByTagName('style')[0].outerHTML; 275 | 276 | 277 | // vars 278 | // we use data-update so the var content is updated even if base64 doesn't change 279 | obsOverlay.setVar( 280 | 'obschatmod.iframe', 281 | '' 282 | ); 283 | } 284 | }, 285 | 286 | 287 | }; 288 | 289 | 290 | // at start 291 | obschatmod.update(); 292 | 293 | // on schedule 294 | setInterval(obschatmod.update, 1000); -------------------------------------------------------------------------------- /plugins/twitch.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This plugin offers access to twitch stats. 3 | 4 | 5 | required variable from user config: 6 | twitch.channel name of the twitch channel 7 | 8 | 9 | available variables: 10 | twitch.chatters.count 11 | twitch.viewers.count 12 | *******************************************************************************/ 13 | (function() { 14 | 15 | 16 | //*************************************************************************** 17 | function update() { 18 | 19 | // get twitch channel from user config 20 | var channel = obsOverlay.getVar('twitch.channel'); 21 | 22 | 23 | // timestamp, trying to stay fresh 24 | var timestamp = Date.now(); 25 | 26 | 27 | // no channel 28 | if(!channel) { 29 | return; 30 | } 31 | 32 | 33 | // lowercase 34 | channel = channel.toLowerCase(); 35 | 36 | 37 | // load twitch streams data 38 | obsOverlay.fetchUrl( 39 | 'https://api.twitch.tv/kraken/streams/'+channel+'?t='+timestamp, 40 | // onload 41 | function(r) { 42 | r = JSON.parse(r.target.responseText); 43 | r = r && r.stream && r.stream.viewers != null ? r.stream.viewers : 'n/a' 44 | 45 | // export var 46 | obsOverlay.setVar('twitch.viewers.count', r); 47 | }, 48 | // timeout 49 | function(r) { 50 | obsOverlay.setVar('twitch.viewers.count', 'n/a'); 51 | } 52 | ); 53 | 54 | 55 | // load twitch chatters data 56 | obsOverlay.fetchUrl( 57 | 'http://tmi.twitch.tv/group/user/'+channel+'/chatters?t='+timestamp, 58 | // onload 59 | function(r) { 60 | r = JSON.parse(r.target.responseText); 61 | r = r && r.chatter_count != null ? r.chatter_count : 'n/a' 62 | 63 | // export var 64 | obsOverlay.setVar('twitch.chatters.count', r); 65 | }, 66 | // timeout 67 | function(r) { 68 | obsOverlay.setVar('twitch.chatters.count', 'n/a'); 69 | } 70 | ); 71 | } 72 | 73 | 74 | // init vars 75 | obsOverlay.setVar('twitch.viewers.count', 'n/a'); 76 | obsOverlay.setVar('twitch.chatters.count', 'n/a'); 77 | 78 | 79 | // at start 80 | update(); 81 | 82 | // on schedule 83 | setInterval(update, 10000); 84 | 85 | })(); -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | obs-overlay 2 | http://spenibus.net 3 | https://github.com/spenibus/obs-overlay-html-js 4 | https://gitlab.com/spenibus/obs-overlay-html-js 5 | 6 | 7 | *********************************************************************** Overview 8 | This is a customisable overlay for Open Broadcaster Software. 9 | https://obsproject.com/ 10 | It requires the CLR Browser Source Plugin. 11 | https://obsproject.com/forum/resources/clr-browser-source-plugin.22/ 12 | 13 | 14 | How it works: 15 | Core generate variables by reloading the configuration at a regular interval. 16 | Plugins generate variables at a regular interval (when enabled). 17 | Style is reloaded at a regular interval. 18 | 19 | When modifications are detected, the overlay is updated accordingly. This allows 20 | you to edit the configuration or the style without restarting the stream. 21 | 22 | 23 | ********************************************************* extra reading material 24 | OBS Overlay - The illustrated guide 25 | http://spenibus.net/b/p/p/OBS-Overlay-The-illustrated-guide 26 | 27 | 28 | ************************************************************************** Setup 29 | Create the file "user/config.html". 30 | These is the bare minimum required to make it work. 31 | You can use the files from "user-example/" to get started. 32 | 33 | 34 | Then in OBS, click "global sources", "add", "add CLR browser" for each of the 35 | following documents: 36 | - coordinator.html 37 | - background.html 38 | - standby.html 39 | - overlay.html 40 | Simply set the dimensions to your stream output dimensions. 41 | Don't touch the opacity. 42 | There is no need to run each document more than once, regardless of how many 43 | scenes in which they may be included, which is why they are added as global 44 | sources. 45 | 46 | 47 | 48 | coordinator.html 49 | This document is there for everything to work. It is not supposed to appear on 50 | the stream but it has to be running. 51 | Simply put it behind the background in one scene. 52 | 53 | 54 | background.html 55 | Something to put behind everything else. 56 | 57 | 58 | standby.html 59 | This is the document to be shown when the stream is live but idle. 60 | 61 | 62 | overlay.html 63 | This is the document to be shown when the stream is live and active. 64 | 65 | 66 | ************************************************************ user files overview 67 | obs-overlay/user/ user config folder 68 | obs-overlay/user/config.html user config file 69 | obs-overlay/user/styles user styles folder 70 | obs-overlay/user/plugins user plugins folder 71 | 72 | 73 | config.html 74 | This holds the overlay configuration. 75 | 76 | -- basic format: 77 | 78 | MyValue1 79 | MyValue2 80 | MyValue3 81 | 82 | 83 | -- set variable: 84 | bar 85 | 86 | -- use variable: 87 |
88 | the element's content will be replaced with the var's value, like this: 89 |
bar
90 | you can use any tag, like "span" 91 | 92 | -- you can nest variables to 99 levels deep, although you should avoid it for 93 | performance reasons. 94 | 95 | -- core variables 96 | variables generated from the overlay scripts are prefixed with "core" 97 | you should avoid creating custom variables prefixed with "core" 98 | 99 | -- core variables list 100 | 101 | -- core.elem.background.extra 102 | content of the extra empty box of the background screen 103 | 104 | -- core.elem.standby.extra 105 | content of the extra empty box of the standby screen 106 | -- core.elem.standby.top 107 | content of top box of the standby screen 108 | -- core.elem.standby.middle 109 | content of middle box of the standby screen 110 | -- core.elem.standby.bottom 111 | content of bottom box of the standby screen 112 | 113 | -- core.elem.overlay.extra 114 | content of the extra empty box of the overlay screen 115 | -- core.elem.overlay.top.left 116 | content of top left box of the overlay screen 117 | -- core.elem.overlay.top.middle 118 | content of top middle box of the overlay screen 119 | -- core.elem.overlay.top.right 120 | content of top right box of the overlay screen 121 | -- core.elem.overlay.bottom.left 122 | content of bottom left box of the overlay screen 123 | -- core.elem.overlay.bottom.middle 124 | content of bottom middle box of the overlay screen 125 | -- core.elem.overlay.bottom.right 126 | content of bottom right box of the overlay screen 127 | 128 | -- core.style.* 129 | explained below 130 | 131 | -- core.plugin.* 132 | explained below 133 | 134 | 135 | Note regarding variable names 136 | Choose variable names carefully. For example, if you use the clock plugin and 137 | create a custom variable clock.time, it will be overwritten by the plugin. 138 | Custom core.* variables are also strongly discouraged. 139 | 140 | 141 | Note regarding the use of variables 142 | When a variable is attached to an element with "data-var", the content of the 143 | element will be overwritten by the variable's value, it is therefore useless to 144 | write anything inside that element. For example: 145 | bar 146 | stuff 147 | "stuff" will be replaced with "bar" 148 | 149 | 150 | **************************************************************** Config examples 151 | Example: displaying a title in the top middle box of the overlay. 152 | My title 153 | 154 | 155 | Example: displaying the twitter logo and your twitter handle on the bottom right 156 | box of the overlay (you would need to include the logo in the user folder). 157 | 158 | myTwitterHandle 159 | 160 | 161 | 162 | Example: using a variable 163 | Mother of dragons 164 | 165 | 166 | 167 | 168 | 169 | Example: nesting variables 170 | Mother of dragons 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | ******************************************************************* Using styles 180 | To add a style sheet, create a css file in your user folder, then add this to 181 | the user config: 182 | 1 183 | 184 | For example, if you create the file "user/styles/myStyle.css", the config is: 185 | 1 186 | This will add "myStyle.css" to every document. 187 | 188 | You can disable a style by setting its value to something that is not "1". 189 | 190 | 191 | ****************************************************************** Using plugins 192 | To use a plugin, copy the plugin script file to the user folder, then add this 193 | to the user config: 194 | 1 195 | 196 | For example, to use the clock plugin, copy 197 | "plugins/clock.js" to "user/plugins/clock.js" 198 | then add this to "user/config.html": 199 | 1 200 | You should then have access to "clock.*" variables. 201 | 202 | You can disable a plugin by setting its value to something that is not "1". 203 | 204 | 205 | *************************************************************** Writing a plugin 206 | SECTION TO BE WRITTEN -------------------------------------------------------------------------------- /standby.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 |
13 |
ready
14 |
15 | 16 |
17 |
ready
18 |
19 | 20 |
21 |
ready
22 |
23 | 24 | 25 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /styles/default/default.css: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | using viewport unit "vh" to keep proportions relative to viewport height 3 | sometimes extended with percentages 4 | *******************************************************************************/ 5 | 6 | 7 | 8 | 9 | /********************************************************************* global */ 10 | html, body { 11 | width:100vw; 12 | height:100vh; 13 | margin:0; 14 | padding:0; 15 | } 16 | 17 | body { 18 | color:#FFF; 19 | font-size:3vh; 20 | font-family:arial; 21 | } 22 | 23 | * { 24 | vertical-align:middle; 25 | } 26 | 27 | 28 | 29 | 30 | /********************************************************************* common */ 31 | #myChat, 32 | #standby .box, 33 | #overlay .box { 34 | background-image:url('default/bg-box.png'); 35 | background-size:auto 10vh; 36 | } 37 | #myChat, 38 | #standby .box, 39 | #overlay .box { 40 | background-color:rgb(60,100,140); 41 | } 42 | #standby .box.middle { 43 | background-color:rgb(20,60,100); 44 | } 45 | 46 | 47 | 48 | 49 | /***************************************************************** background */ 50 | #background { 51 | background-image:url('default/bg-wall.png'); 52 | background-size:auto 10vh; 53 | background-color:rgb(20,30,40); 54 | } 55 | 56 | 57 | 58 | 59 | /******************************************************************** standby */ 60 | #standby { 61 | display:table-cell; 62 | } 63 | #standby .box { 64 | max-width:120vh; 65 | padding:1vh 2vh; 66 | box-shadow:inset 0 0 2vh 0vh #000, 0 0 4vh 1vh #000; 67 | border:0.25vh solid #FFF; 68 | border-left:0; 69 | border-radius:0 1vh 1vh 0; 70 | padding-left:11vh; 71 | margin-left:-10vh; 72 | } 73 | #standby .box.top { 74 | max-width:90vh; 75 | margin-bottom:-2vh; 76 | position:relative; 77 | z-index:101; 78 | } 79 | #standby .box.middle { 80 | max-width:120vh; 81 | position:relative; 82 | z-index:100; 83 | padding-top:3vh; 84 | padding-bottom:3vh; 85 | } 86 | #standby .box.bottom { 87 | max-width:60vh; 88 | margin-top:-2vh; 89 | position:relative; 90 | z-index:101; 91 | text-align:center; 92 | } 93 | 94 | 95 | 96 | 97 | /******************************************************************** overlay */ 98 | #overlay { 99 | display:table-cell; 100 | font-weight:bold; 101 | display:inline-block; 102 | } 103 | #overlay .box:empty { 104 | display:none; 105 | } 106 | 107 | 108 | #overlay .wrapper { 109 | position:fixed; 110 | } 111 | #overlay .wrapper.top { 112 | top:0; 113 | } 114 | #overlay .wrapper.bottom { 115 | bottom:0; 116 | } 117 | #overlay .wrapper.left { 118 | left:0; 119 | } 120 | #overlay .wrapper.middle { 121 | left:0; 122 | right:0; 123 | text-align:center; 124 | } 125 | #overlay .wrapper.right { 126 | right:0; 127 | } 128 | 129 | 130 | #overlay .box { 131 | font-size:2vh; 132 | line-height:2vh; 133 | display:inline-block; 134 | padding:0.25vh; 135 | white-space:nowrap; 136 | border:0.25vh solid #FFF; 137 | box-shadow:0 0 4vh 1vh #000; 138 | } 139 | #overlay .box.top { 140 | border-top-width:0; 141 | vertical-align:top; 142 | } 143 | #overlay .box.bottom { 144 | border-bottom-width:0; 145 | vertical-align:bottom; 146 | } 147 | #overlay .box.left { 148 | padding-right:3vh; 149 | border-left-width:0; 150 | } 151 | #overlay .box.middle { 152 | padding-right:3vh; 153 | padding-left:3vh; 154 | } 155 | #overlay .box.right { 156 | padding-left:3vh; 157 | border-right-width:0; 158 | } 159 | 160 | 161 | #overlay .box.top.left { 162 | border-radius:0 0 3vh 0; 163 | } 164 | #overlay .box.top.middle { 165 | border-radius:0 0 3vh 3vh; 166 | } 167 | #overlay .box.top.right { 168 | border-radius:0 0 0 3vh; 169 | } 170 | #overlay .box.bottom.left { 171 | border-radius:0 3vh 0 0; 172 | } 173 | #overlay .box.bottom.middle { 174 | border-radius:3vh 3vh 0 0; 175 | } 176 | #overlay .box.bottom.right { 177 | border-radius:3vh 0 0 0; 178 | } 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | /********************************************************************* myIcon */ 188 | .myIcon { 189 | max-width:3vh; 190 | max-height:3vh; 191 | } 192 | #overlay .myIcon { 193 | max-width:2vh; 194 | max-height:2vh; 195 | } 196 | 197 | 198 | 199 | 200 | /********************************************************************* myChat */ 201 | #myChat { 202 | position:fixed; 203 | bottom:4vh; 204 | right:1vh; 205 | width:40.5vh; 206 | height:90vh; 207 | padding:1vh; 208 | border-radius:1.5vh; 209 | box-shadow:0 0 4vh 1vh #000; 210 | } 211 | #overlay #myChat.small { 212 | width:41.5vh; 213 | height:20vh; 214 | bottom:1vh; 215 | padding:0.5vh; 216 | border-radius:1vh; 217 | } 218 | #myChat > iframe { 219 | background-color:#EEE; 220 | border:0; 221 | width:100%; 222 | height:100%; 223 | border-radius:0.5vh; 224 | } -------------------------------------------------------------------------------- /styles/default/default/bg-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/styles/default/default/bg-box.png -------------------------------------------------------------------------------- /styles/default/default/bg-wall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/styles/default/default/bg-wall.png -------------------------------------------------------------------------------- /user-example/config.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1 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 | 1 71 | 72 | 73 | 74 | 75 | 76 | 1 77 | twitch 78 | 79 | 80 | 81 | 82 | 83 | 1 84 | twitch 85 | 86 | 87 | 88 | 89 | 90 | 1 91 | twitch 92 | light 93 | 1 94 | 1 95 | d t z 96 | 97 | 98 | 99 | 100 | 101 | Tidily titling stuff 102 | 103 | 104 | This is a description, 105 |
it describes things with words. 106 |
Words ! 107 |
108 | 109 | 110 |
111 |
112 | 113 | 114 |
115 |
116 | 117 | 118 | @my_twitter 119 | /my_youtube 120 | /my_twitch 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /user-example/credits.txt: -------------------------------------------------------------------------------- 1 | https://openclipart.org/detail/35209/tango-inetrnet-group-chat-by-warszawianka 2 | https://openclipart.org/detail/63247/eye-sign-by-dbdeveloper 3 | https://openclipart.org/detail/182928/tv-cartoon-empty-by-justin-ternet-182928 -------------------------------------------------------------------------------- /user-example/img/gfx-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/user-example/img/gfx-chat.png -------------------------------------------------------------------------------- /user-example/img/gfx-viewers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/user-example/img/gfx-viewers.png -------------------------------------------------------------------------------- /user-example/img/icon-twitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/user-example/img/icon-twitch.png -------------------------------------------------------------------------------- /user-example/img/icon-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/user-example/img/icon-twitter.png -------------------------------------------------------------------------------- /user-example/img/icon-youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spenibus/obs-overlay-html-js/84632c557e99718e8079a8d73304717e1017945c/user-example/img/icon-youtube.png -------------------------------------------------------------------------------- /user-example/readme.txt: -------------------------------------------------------------------------------- 1 | This is a pre-made user profile. 2 | 3 | Simply copy its content to "user/". 4 | Then copy the files from "styles/default/" to "/user/styles/". 5 | Then copy the files from "plugins/" to "user/plugins/". 6 | 7 | You can then edit config.html to your liking. --------------------------------------------------------------------------------