first-screen.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. const VS_LOGO = `
  2. attribute vec4 a_Position;
  3. attribute vec2 a_TexCoord;
  4. varying vec2 v_TexCoord;
  5. void main() {
  6. gl_Position = a_Position;
  7. v_TexCoord = a_TexCoord;
  8. }`;
  9. const FS_LOGO = `
  10. precision mediump float;
  11. uniform sampler2D u_Sampler;
  12. varying vec2 v_TexCoord;
  13. void main() {
  14. gl_FragColor = texture2D(u_Sampler, v_TexCoord);
  15. }`;
  16. const VS_PROGRESSBAR = `
  17. precision mediump float;
  18. attribute vec4 a_Position;
  19. attribute float a_Progress;
  20. varying float v_Progress;
  21. void main() {
  22. gl_Position = a_Position;
  23. v_Progress = a_Progress;
  24. }`;
  25. const FS_PROGRESSBAR = `
  26. precision mediump float;
  27. uniform float u_CurrentProgress;
  28. varying float v_Progress;
  29. uniform vec4 u_ProgressBarColor;
  30. uniform vec4 u_ProgressBackground;
  31. void main() {
  32. gl_FragColor = v_Progress <= u_CurrentProgress ? u_ProgressBarColor : u_ProgressBackground;
  33. }`;
  34. const options = {
  35. alpha: false,
  36. antialias: true,
  37. depth: true,
  38. stencil: true,
  39. premultipliedAlpha: false,
  40. preserveDrawingBuffer: false,
  41. powerPreference: 'default',
  42. failIfMajorPerformanceCaveat: false,
  43. };
  44. let gl = null;
  45. let image = null;
  46. let program = null;
  47. let programProgress = null;
  48. let rafHandle = null;
  49. let texture = null;
  50. let vertexBuffer = null;
  51. let vertexBufferProgress = null;
  52. let progress = 0.0;
  53. let progressBarColor = [61 / 255, 197 / 255, 222 / 255, 1];
  54. let progressBackground = [100 / 255, 111 / 255, 118 / 255, 1];
  55. let afterTick = null;
  56. function initShaders(vshader, fshader) {
  57. return createProgram(vshader, fshader);
  58. }
  59. function createProgram(vshader, fshader) {
  60. var vertexShader = loadShader(gl.VERTEX_SHADER, vshader);
  61. var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fshader);
  62. var program = gl.createProgram();
  63. gl.attachShader(program, vertexShader);
  64. gl.attachShader(program, fragmentShader);
  65. gl.linkProgram(program);
  66. var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  67. if (!linked) {
  68. var error = gl.getProgramInfoLog(program);
  69. console.log('Failed to link program: ' + error);
  70. gl.deleteProgram(program);
  71. program = null;
  72. }
  73. gl.deleteShader(fragmentShader);
  74. gl.deleteShader(vertexShader);
  75. return program;
  76. }
  77. function loadShader(type, source) {
  78. var shader = gl.createShader(type);
  79. gl.shaderSource(shader, source);
  80. gl.compileShader(shader);
  81. var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  82. if (!compiled) {
  83. var error = gl.getShaderInfoLog(shader);
  84. console.log('Failed to compile shader: ' + error);
  85. gl.deleteShader(shader);
  86. return null;
  87. }
  88. return shader;
  89. }
  90. function initVertexBuffer() {
  91. const widthRatio = 2 / canvas.width;
  92. const heightRatio = 2 / canvas.height;
  93. const vertices = new Float32Array([
  94. widthRatio, heightRatio, 1.0, 1.0,
  95. widthRatio, heightRatio, 1.0, 0.0,
  96. -widthRatio, heightRatio, 0.0, 1.0,
  97. -widthRatio, heightRatio, 0.0, 0.0,
  98. ]);
  99. vertexBuffer = gl.createBuffer();
  100. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  101. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  102. }
  103. function initProgressVertexBuffer() {
  104. const widthRatio = 0.405;
  105. const heightRatio = (window.devicePixelRatio >= 2 ? 6 : 3) / canvas.height;
  106. const heightOffset = -0.25;
  107. const vertices = new Float32Array([
  108. widthRatio, heightOffset - heightRatio, 1,
  109. widthRatio, heightOffset + heightRatio, 1,
  110. -widthRatio, heightOffset - heightRatio, 0,
  111. -widthRatio, heightOffset + heightRatio, 0,
  112. ]);
  113. vertexBufferProgress = gl.createBuffer();
  114. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferProgress);
  115. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  116. }
  117. function updateVertexBuffer() {
  118. const widthRatio = image.width / canvas.width;
  119. const heightRatio = image.height / canvas.height;
  120. const vertices = new Float32Array([
  121. widthRatio, -heightRatio, 1.0, 1.0,
  122. widthRatio, heightRatio, 1.0, 0.0,
  123. -widthRatio, -heightRatio, 0.0, 1.0,
  124. -widthRatio, heightRatio, 0.0, 0.0,
  125. ]);
  126. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  127. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  128. }
  129. function loadImage(imgPath) {
  130. return new Promise((resolve, reject) => {
  131. image = new Image();
  132. image.premultiplyAlpha = false;
  133. image.onload = function() {
  134. resolve(image);
  135. };
  136. image.onerror = function(err) {
  137. reject(err);
  138. };
  139. image.src = imgPath.replace('#', '%23');
  140. });
  141. }
  142. function initTexture() {
  143. texture = gl.createTexture();
  144. gl.activeTexture(gl.TEXTURE0);
  145. gl.bindTexture(gl.TEXTURE_2D, texture);
  146. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  147. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  148. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  149. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  150. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255]));
  151. }
  152. function updateTexture() {
  153. gl.activeTexture(gl.TEXTURE0);
  154. gl.bindTexture(gl.TEXTURE_2D, texture);
  155. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  156. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  157. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  158. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  159. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  160. }
  161. function draw() {
  162. gl.clearColor(0.0, 0.0, 0.0, 0.0);
  163. gl.clear(gl.COLOR_BUFFER_BIT);
  164. gl.useProgram(program);
  165. gl.activeTexture(gl.TEXTURE0);
  166. gl.bindTexture(gl.TEXTURE_2D, texture);
  167. var uSampler = gl.getUniformLocation(program, 'u_Sampler');
  168. gl.uniform1i(uSampler, 0);
  169. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  170. var vertexFormatLength = 4;
  171. var aPosition = gl.getAttribLocation(program, 'a_Position');
  172. gl.enableVertexAttribArray(aPosition);
  173. gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, vertexFormatLength * 4, 0);
  174. var aTexCoord = gl.getAttribLocation(program, 'a_TexCoord');
  175. gl.enableVertexAttribArray(aTexCoord);
  176. gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, vertexFormatLength * 4, vertexFormatLength * 2);
  177. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  178. // gl.useProgram(programProgress);
  179. // var uCurrentProgress = gl.getUniformLocation(programProgress, 'u_CurrentProgress');
  180. // gl.uniform1f(uCurrentProgress, progress);
  181. // var uProgressBarColor = gl.getUniformLocation(programProgress, 'u_ProgressBarColor');
  182. // gl.uniform4fv(uProgressBarColor, progressBarColor);
  183. // var uProgressBackground = gl.getUniformLocation(programProgress, 'u_ProgressBackground');
  184. // gl.uniform4fv(uProgressBackground, progressBackground);
  185. // gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferProgress);
  186. // aPosition = gl.getAttribLocation(programProgress, 'a_Position');
  187. // gl.enableVertexAttribArray(aPosition);
  188. // gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, vertexFormatLength * 3, 0);
  189. // var aProgress = gl.getAttribLocation(programProgress, 'a_Progress');
  190. // gl.enableVertexAttribArray(aProgress);
  191. // gl.vertexAttribPointer(aProgress, 1, gl.FLOAT, false, vertexFormatLength * 3, vertexFormatLength * 2);
  192. // gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  193. }
  194. function tick() {
  195. rafHandle = requestAnimationFrame(() => {
  196. draw();
  197. tick();
  198. if (afterTick) {
  199. afterTick();
  200. afterTick = null;
  201. }
  202. });
  203. }
  204. function end() {
  205. return setProgress(1).then(() => {
  206. cancelAnimationFrame(rafHandle);
  207. gl.useProgram(null);
  208. gl.bindTexture(gl.TEXTURE_2D, null);
  209. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  210. gl.deleteTexture(texture);
  211. gl.deleteBuffer(vertexBuffer);
  212. gl.deleteBuffer(vertexBufferProgress);
  213. gl.deleteProgram(program);
  214. gl.deleteProgram(programProgress);
  215. });
  216. }
  217. function setProgress(val) {
  218. progress = val;
  219. return new Promise((resolve, reject) => {
  220. afterTick = () => {
  221. resolve();
  222. };
  223. });
  224. }
  225. function start(alpha, antialias, useWebgl2) {
  226. options.alpha = alpha === 'true' ? true : false;
  227. options.antialias = antialias === 'false' ? false : true;
  228. if (useWebgl2 === 'true') {
  229. gl = window.canvas.getContext("webgl2", options);
  230. }
  231. // TODO: this is a hack method to detect whether WebGL2RenderingContext is supported
  232. if (gl) {
  233. window.WebGL2RenderingContext = true;
  234. } else {
  235. window.WebGL2RenderingContext = false;
  236. gl = window.canvas.getContext("webgl", options);
  237. }
  238. initVertexBuffer();
  239. // initProgressVertexBuffer();
  240. initTexture();
  241. program = initShaders(VS_LOGO, FS_LOGO);
  242. // programProgress = initShaders(VS_PROGRESSBAR, FS_PROGRESSBAR);
  243. tick();
  244. return loadImage('splash.jpg').then(() => {
  245. updateVertexBuffer();
  246. updateTexture();
  247. return setProgress(0);
  248. });
  249. }
  250. module.exports = { start, end, setProgress };