first-screen.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 progressBarColor = [200 / 255, 154 / 255, 113 / 255, 1];
  55. //let progressBackground = [100 / 255, 111 / 255, 118 / 255, 1];
  56. let progressBackground = [249 / 255, 246 / 255, 227 / 255, 1];
  57. let afterTick = null;
  58. function initShaders(vshader, fshader) {
  59. return createProgram(vshader, fshader);
  60. }
  61. function createProgram(vshader, fshader) {
  62. var vertexShader = loadShader(gl.VERTEX_SHADER, vshader);
  63. var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fshader);
  64. var program = gl.createProgram();
  65. gl.attachShader(program, vertexShader);
  66. gl.attachShader(program, fragmentShader);
  67. gl.linkProgram(program);
  68. var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  69. if (!linked) {
  70. var error = gl.getProgramInfoLog(program);
  71. console.log('Failed to link program: ' + error);
  72. gl.deleteProgram(program);
  73. program = null;
  74. }
  75. gl.deleteShader(fragmentShader);
  76. gl.deleteShader(vertexShader);
  77. return program;
  78. }
  79. function loadShader(type, source) {
  80. var shader = gl.createShader(type);
  81. gl.shaderSource(shader, source);
  82. gl.compileShader(shader);
  83. var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  84. if (!compiled) {
  85. var error = gl.getShaderInfoLog(shader);
  86. console.log('Failed to compile shader: ' + error);
  87. gl.deleteShader(shader);
  88. return null;
  89. }
  90. return shader;
  91. }
  92. function initVertexBuffer() {
  93. const widthRatio = 2 / canvas.width;
  94. const heightRatio = 2 / canvas.height;
  95. const vertices = new Float32Array([
  96. widthRatio, heightRatio, 1.0, 1.0,
  97. widthRatio, heightRatio, 1.0, 0.0,
  98. -widthRatio, heightRatio, 0.0, 1.0,
  99. -widthRatio, heightRatio, 0.0, 0.0,
  100. ]);
  101. vertexBuffer = gl.createBuffer();
  102. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  103. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  104. }
  105. function initProgressVertexBuffer() {
  106. const info = wx.getSystemInfoSync();
  107. const widthRatio = 0.405;
  108. const heightRatio = (info.pixelRatio >= 2 ? 6 : 3) / canvas.height;
  109. const heightOffset = -0.25;
  110. const vertices = new Float32Array([
  111. widthRatio, heightOffset - heightRatio, 1,
  112. widthRatio, heightOffset + heightRatio, 1,
  113. -widthRatio, heightOffset - heightRatio, 0,
  114. -widthRatio, heightOffset + heightRatio, 0,
  115. ]);
  116. vertexBufferProgress = gl.createBuffer();
  117. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferProgress);
  118. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  119. }
  120. function updateVertexBuffer() {
  121. let d_h = canvas.height;
  122. let d_w = canvas.width;
  123. let t_h = image.height;
  124. let t_w = image.width;
  125. let scale = 1;
  126. let ratio1 = d_h / t_h;
  127. let ratio2 = d_w / t_w;
  128. //根据高度适配ratio1
  129. let ratiomax = ratio1;
  130. let i_h = Math.round(t_h * ratiomax);
  131. let i_w = Math.round(t_w * ratiomax);
  132. let r_w = d_w / i_w;
  133. let r_h = d_h / i_h;
  134. r_w = r_w * scale;
  135. r_h = r_h * scale;
  136. const widthRatio = 1/r_w;
  137. const heightRatio = 1/r_h ;
  138. const vertices = new Float32Array([
  139. widthRatio, -heightRatio, 1.0, 1.0,
  140. widthRatio, heightRatio, 1.0, 0.0,
  141. -widthRatio, -heightRatio, 0.0, 1.0,
  142. -widthRatio, heightRatio, 0.0, 0.0,
  143. ]);
  144. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  145. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  146. /*const widthRatio = image.width / canvas.width;
  147. const heightRatio = image.height / canvas.height;
  148. const vertices = new Float32Array([
  149. widthRatio, -heightRatio, 1.0, 1.0,
  150. widthRatio, heightRatio, 1.0, 0.0,
  151. -widthRatio, -heightRatio, 0.0, 1.0,
  152. -widthRatio, heightRatio, 0.0, 0.0,
  153. ]);
  154. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  155. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);*/
  156. }
  157. function loadImage(imgPath) {
  158. return new Promise((resolve, reject) => {
  159. image = new Image();
  160. image.premultiplyAlpha = false;
  161. image.onload = function() {
  162. resolve(image);
  163. };
  164. image.onerror = function(err) {
  165. reject(err);
  166. };
  167. image.src = imgPath.replace('#', '%23');
  168. });
  169. }
  170. function initTexture() {
  171. texture = gl.createTexture();
  172. gl.activeTexture(gl.TEXTURE0);
  173. gl.bindTexture(gl.TEXTURE_2D, texture);
  174. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  175. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  176. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  177. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  178. 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]));
  179. }
  180. function updateTexture() {
  181. gl.activeTexture(gl.TEXTURE0);
  182. gl.bindTexture(gl.TEXTURE_2D, texture);
  183. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  184. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  185. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  186. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  187. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  188. }
  189. function draw() {
  190. gl.disable(gl.SCISSOR_TEST);
  191. gl.disable(gl.CULL_FACE);
  192. gl.disable(gl.DEPTH_TEST);
  193. //gl.clearColor(0.0, 0.0, 0.0, 0.0);
  194. gl.clearColor(249.0, 246.0, 229.0, 0.0);
  195. gl.clear(gl.COLOR_BUFFER_BIT);
  196. gl.useProgram(program);
  197. gl.activeTexture(gl.TEXTURE0);
  198. gl.bindTexture(gl.TEXTURE_2D, texture);
  199. var uSampler = gl.getUniformLocation(program, 'u_Sampler');
  200. gl.uniform1i(uSampler, 0);
  201. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  202. var vertexFormatLength = 4;
  203. var aPosition = gl.getAttribLocation(program, 'a_Position');
  204. gl.enableVertexAttribArray(aPosition);
  205. gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, vertexFormatLength * 4, 0);
  206. var aTexCoord = gl.getAttribLocation(program, 'a_TexCoord');
  207. gl.enableVertexAttribArray(aTexCoord);
  208. gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, vertexFormatLength * 4, vertexFormatLength * 2);
  209. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  210. gl.useProgram(programProgress);
  211. var uCurrentProgress = gl.getUniformLocation(programProgress, 'u_CurrentProgress');
  212. gl.uniform1f(uCurrentProgress, progress);
  213. var uProgressBarColor = gl.getUniformLocation(programProgress, 'u_ProgressBarColor');
  214. gl.uniform4fv(uProgressBarColor, progressBarColor);
  215. var uProgressBackground = gl.getUniformLocation(programProgress, 'u_ProgressBackground');
  216. gl.uniform4fv(uProgressBackground, progressBackground);
  217. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferProgress);
  218. aPosition = gl.getAttribLocation(programProgress, 'a_Position');
  219. gl.enableVertexAttribArray(aPosition);
  220. gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, vertexFormatLength * 3, 0);
  221. var aProgress = gl.getAttribLocation(programProgress, 'a_Progress');
  222. gl.enableVertexAttribArray(aProgress);
  223. gl.vertexAttribPointer(aProgress, 1, gl.FLOAT, false, vertexFormatLength * 3, vertexFormatLength * 2);
  224. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  225. }
  226. function tick() {
  227. rafHandle = requestAnimationFrame(() => {
  228. draw();
  229. tick();
  230. if (afterTick) {
  231. afterTick();
  232. afterTick = null;
  233. }
  234. });
  235. }
  236. function end() {
  237. return setProgress(1).then(() => {
  238. cancelAnimationFrame(rafHandle);
  239. gl.enable(gl.SCISSOR_TEST);
  240. gl.enable(gl.CULL_FACE);
  241. gl.enable(gl.DEPTH_TEST);
  242. // gl.useProgram(null);
  243. // gl.bindTexture(gl.TEXTURE_2D, null);
  244. // gl.bindBuffer(gl.ARRAY_BUFFER, null);
  245. // gl.deleteTexture(texture);
  246. // gl.deleteBuffer(vertexBuffer);
  247. // gl.deleteBuffer(vertexBufferProgress);
  248. // gl.deleteProgram(program);
  249. // gl.deleteProgram(programProgress);
  250. });
  251. }
  252. function setProgress(val) {
  253. progress = val;
  254. return new Promise((resolve, reject) => {
  255. afterTick = () => {
  256. resolve();
  257. };
  258. });
  259. }
  260. function firstCanvas() {
  261. const info = wx.getSystemInfoSync();
  262. if (canvas){
  263. var _w = canvas.width;
  264. var _h = canvas.height;
  265. if (info.screenWidth < info.screenHeight) {
  266. if (canvas.width > canvas.height) {
  267. _w = canvas.height;
  268. _h = canvas.width;
  269. }
  270. } else {
  271. if (canvas.width < canvas.height) {
  272. _w = canvas.height;
  273. _h = canvas.width;
  274. }
  275. }
  276. canvas.width = _w;
  277. canvas.height = _h;
  278. }
  279. if (canvas && info.devicePixelRatio >= 2) {canvas.width *= info.devicePixelRatio; canvas.height *= info.devicePixelRatio;}
  280. return canvas;
  281. }
  282. function start(alpha, antialias, useWebgl2) {
  283. options.alpha = alpha === 'true' ? true : false;
  284. options.antialias = antialias === 'false' ? false : true;
  285. if (useWebgl2 === 'true') {
  286. gl = window.canvas.getContext("webgl2", options);
  287. }
  288. // TODO: this is a hack method to detect whether WebGL2RenderingContext is supported
  289. if (gl) {
  290. window.WebGL2RenderingContext = true;
  291. } else {
  292. window.WebGL2RenderingContext = false;
  293. gl = window.canvas.getContext("webgl", options);
  294. }
  295. initVertexBuffer();
  296. initProgressVertexBuffer();
  297. initTexture();
  298. program = initShaders(VS_LOGO, FS_LOGO);
  299. programProgress = initShaders(VS_PROGRESSBAR, FS_PROGRESSBAR);
  300. tick();
  301. return loadImage('splash.png').then(() => {
  302. updateVertexBuffer();
  303. updateTexture();
  304. return setProgress(0);
  305. });
  306. }
  307. module.exports = { start, end, setProgress };