Index.cshtml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. @using CommonTool
  2. @using YZXYH.Repository.Models
  3. @{
  4. List<MessageWallInfo> msgs = ViewBag.Msgs?? new List<MessageWallInfo>();
  5. var dataStr = JsonHelper.Instance.Serialize(msgs);
  6. string isRead = ViewBag.Read ?? "1";
  7. }
  8. <!DOCTYPE html>
  9. <html>
  10. <head>
  11. <meta charset="utf-8">
  12. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  13. <meta name="renderer" content="webkit">
  14. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  15. <meta http-equiv="Cache-Control" content="no-siteapp" />
  16. <title>盐城中学校友会——愿望墙</title>
  17. <meta name="keywords" content="盐城中学,盐中校友会,校友会,盐中">
  18. <meta name="description" content="">
  19. <link href="~/Content/css/bootstrap.min.css" rel="stylesheet" />
  20. <link href="~/Content/css/font-awesome.min.css" rel="stylesheet" />
  21. <link href="~/Content/css/animate.min.css" rel="stylesheet" />
  22. <script src="~/Content/js/jquery.min.js"></script>
  23. <script src="~/Content/js/bootstrap.min.js"></script>
  24. <style>
  25. body {
  26. background: linear-gradient(180deg, #3bb3c3, #3bb3c3);
  27. width: 100vw;
  28. height: 100vh;
  29. overflow: hidden;
  30. color: #000;
  31. font-family: '微软雅黑', sans-serif;
  32. font-size: 16px;
  33. position: relative;
  34. top: 0;
  35. left: 0;
  36. bottom: 0;
  37. right: 0;
  38. }
  39. #msg-box {
  40. width: 100%;
  41. height: 100%;
  42. position: absolute;
  43. top: 0;
  44. left:0;
  45. bottom: 0;
  46. right: 0;
  47. overflow: hidden;
  48. }
  49. .item {
  50. width: 15%;
  51. min-width: 200px;
  52. max-width: 400px;
  53. min-height: 200px;
  54. max-height: 95vh;
  55. overflow: hidden;
  56. border-radius: 10px;
  57. line-height: 30px;
  58. padding: 10px;
  59. box-shadow: 5px 5px 7px #212121;
  60. box-shadow: 5px 5px 7px rgba(33,33,33,.7);
  61. }
  62. .item .title {
  63. height: 50px;
  64. padding: 5px 10px;
  65. }
  66. .item .avatar {
  67. width: 35px;
  68. height: 35px;
  69. border-radius: 50%;
  70. display: block;
  71. float: left;
  72. background-size: 100%;
  73. }
  74. .item .name {
  75. margin-left: 15px;
  76. display: block;
  77. float: left;
  78. line-height: 35px;
  79. font-size: 120%;
  80. font-weight: bold;
  81. }
  82. .item .content {
  83. padding:20px;
  84. padding-top: 0;
  85. text-indent: 2em;
  86. line-height: 25px;
  87. font-family: "Reenie Beanie",arial,sans-serif;
  88. }
  89. .item .image {
  90. width: 100%;
  91. height: auto;
  92. margin: 0 auto;
  93. }
  94. /*.item-0 {
  95. border-top-left-radius: 5px 100px;
  96. border-top-right-radius: 5px 100px;
  97. border-bottom-left-radius: 30px 500px;
  98. border-bottom-right-radius: 500px 20px;
  99. }
  100. .item-1 {
  101. border-bottom-left-radius: 20px 400px;
  102. border-bottom-right-radius: 500px 30px;
  103. }
  104. .item-2 {
  105. border-bottom-left-radius: 40px 400px;
  106. border-bottom-right-radius: 500px 30px;
  107. }
  108. .item-3 {
  109. border-bottom-left-radius: 50px 200px;
  110. border-bottom-right-radius: 500px 30px;
  111. }
  112. .item-4 {
  113. border-bottom-right-radius: 20px 400px;
  114. border-bottom-left-radius: 500px 30px;
  115. }*/
  116. </style>
  117. </head>
  118. <body class="">
  119. <canvas id="canvas"></canvas>
  120. <div id="msg-box" ></div>
  121. <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
  122. <script src="~/signalr/hubs"></script>
  123. <script id="msg-push">
  124. var interval = 0, msgData = @(Html.Raw(dataStr)), tPush,$container = $('#msg-box');
  125. $(function() {
  126. // 启动全屏!
  127. draw();
  128. PushMsg();
  129. var chat = $.connection.xyhHub;
  130. chat.client.getMsg = function(msg) {
  131. if (msg) {
  132. try {
  133. var data = JSON.parse(msg);
  134. if (data) {
  135. //console.log("未推送消息数量:", msgData.length, "新消息:", data);
  136. msgData.push(data);
  137. } else {
  138. console.log("错误消息:",msg);
  139. }
  140. } catch (e) {
  141. console.log("错误消息:",msg);
  142. console.log(e);
  143. }
  144. } else {
  145. console.log("错误消息:",msg);
  146. }
  147. }
  148. });
  149. function PushMsg() {
  150. function push() {
  151. if ($container.children().length>50) {
  152. $container.children().first().fadeOut().remove();
  153. }
  154. if (msgData && msgData.length > 0) {
  155. var msg = msgData.shift();
  156. FormatterMsg(msg);
  157. if (msgData.length > 30) {
  158. clearInterval(tPush);
  159. interval = 400;
  160. PushMsg();
  161. } else if (msgData.length > 20) {
  162. clearInterval(tPush);
  163. interval = 800;
  164. PushMsg();
  165. } else if (msgData.length > 5) {
  166. clearInterval(tPush);
  167. interval = 1200;
  168. PushMsg();
  169. } else if (msgData.length <= 0) {
  170. clearInterval(tPush);
  171. interval = 100;
  172. PushMsg();
  173. } else if (interval !== 2000) {
  174. clearInterval(tPush);
  175. interval = 2000;
  176. PushMsg();
  177. }
  178. console.log("未显示消息数量:", msgData.length);
  179. } else {
  180. clearInterval(tPush);
  181. interval = 100;
  182. PushMsg();
  183. }
  184. }
  185. tPush = setInterval(push, interval);
  186. }
  187. var colors = ['#ffc', '#cfc', '#ccf'];
  188. function FormatterMsg(data) {
  189. if (data) {
  190. var str = '';
  191. var img = data.ImagePath ? '<img class="image" src="' + data.ImagePath + '" alt="" />' : '';
  192. var date = FormatDateTime(parseInt(data.MsgDateTime.replace("/Date(", "").replace(")/", ""), 10));
  193. str += '<div class="item item-' + parseInt(Math.random() * 5, 10) + '" data-id="' + data.Id + '" data-type="' + data.MsgType + '" data-date="' + date + '">';
  194. str += '<div class=title>';
  195. str += '<span class="avatar" style="background-image:url(\'' + data.Avatar + '\')"></span>';
  196. //str += '<span class="name">' + date + ' | ' + data.NickName + '</span>';
  197. str += '<span class="name">' + data.NickName + '</span>';
  198. str += '</div>';
  199. str += '<div class="content">' + data.MsgContent + '</div>';
  200. str += img;
  201. str += '</div>';
  202. var color = colors[parseInt(Math.random() * 3, 10)];
  203. var deg = parseInt(Math.random() * 10, 10) > 5
  204. ? parseInt(Math.random() * 10, 10) + 1
  205. : -(parseInt(Math.random() * 10, 10) + 1);
  206. var item= $(str).css({
  207. 'background': color,
  208. 'transform': 'rotate(' + deg + 'deg)'
  209. }).hide().appendTo($container);
  210. if (img) {
  211. $(item).find('.image').load(function() {
  212. item.css({ 'width': '20%'});
  213. item.drag();
  214. });
  215. } else {
  216. item.drag();
  217. }
  218. if ('@(isRead)'==="1") {
  219. $.ajax({
  220. url: '@Url.Action("Read","MessageWall")',
  221. type: 'post',
  222. data: { Id: data.Id },
  223. success: function(res) {
  224. if (!res || !res.Success) {
  225. console.log("消息阅读失败:", data.Id);
  226. }
  227. }
  228. });
  229. }
  230. }
  231. }
  232. function FormatDateTime(inputTime) {
  233. var date = new Date(inputTime);
  234. var y = date.getFullYear();
  235. var m = date.getMonth() + 1;
  236. m = m < 10 ? ('0' + m) : m;
  237. var d = date.getDate();
  238. d = d < 10 ? ('0' + d) : d;
  239. var h = date.getHours();
  240. h = h < 10 ? ('0' + h) : h;
  241. var minute = date.getMinutes();
  242. var second = date.getSeconds();
  243. minute = minute < 10 ? ('0' + minute) : minute;
  244. second = second < 10 ? ('0' + second) : second;
  245. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  246. };
  247. $.connection.hub.start().done(function () {
  248. console.log("XYH:Signalr已连接服务器!");
  249. });
  250. </script>
  251. <script>
  252. // 定义拖拽函数
  253. $.fn.drag = function () {
  254. var $this = $(this);
  255. var parent = $this.parent();
  256. var pw = parent.width();
  257. var ph = parent.height();
  258. var thisWidth = $this.width() + parseInt($this.css('padding-left'), 10) + parseInt($this.css('padding-right'), 10);
  259. var thisHeight = $this.height() + parseInt($this.css('padding-top'), 10) + parseInt($this.css('padding-bottom'), 10);
  260. var x, y, positionX, positionY;
  261. var isDown = false;
  262. var borderWidth = 30;
  263. var randY = parseInt(Math.random() * (ph - thisHeight - borderWidth*2), 10);
  264. randY = randY > borderWidth ? randY : borderWidth;
  265. var randX = parseInt(Math.random() * (pw - thisWidth - borderWidth*2), 10);
  266. randX = randX > borderWidth ? randX : borderWidth;
  267. //parent.css({
  268. // "position": "relative",
  269. // "overflow": "hidden"
  270. //});
  271. $this.css({
  272. "cursor": "move",
  273. "position": "absolute"
  274. }).css({
  275. top: randY,
  276. left: randX
  277. }).fadeIn(800).mousedown(function (e) {
  278. parent.children().css({
  279. "zIndex": "0"
  280. });
  281. $this.css({
  282. "zIndex": "1"
  283. });
  284. isDown = true;
  285. x = e.pageX;
  286. y = e.pageY;
  287. positionX = $this.position().left;
  288. positionY = $this.position().top;
  289. return false;
  290. });
  291. $(document).mouseup(function () {
  292. isDown = false;
  293. }).mousemove(function (e) {
  294. var xPage = e.pageX;
  295. var moveX = positionX + xPage - x;
  296. var yPage = e.pageY;
  297. var moveY = positionY + yPage - y;
  298. if (isDown === true) {
  299. $this.css({
  300. "left": moveX,
  301. "top": moveY
  302. });
  303. } else {
  304. return;
  305. }
  306. if (moveX < 0) {
  307. $this.css({
  308. "left": "0"
  309. });
  310. }
  311. if (moveX > (pw - thisWidth)) {
  312. $this.css({
  313. "left": pw - thisWidth
  314. });
  315. }
  316. if (moveY < 0) {
  317. $this.css({
  318. "top": "0"
  319. });
  320. }
  321. if (moveY > (ph - thisHeight)) {
  322. $this.css({
  323. "top": ph - thisHeight
  324. });
  325. }
  326. });
  327. };
  328. </script>
  329. <script>
  330. ////Based on https://www.youtube.com/watch?v=3CycKKJiwis
  331. var canvas = document.getElementById("canvas");
  332. var mobile = navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i);
  333. canvas.width = window.innerWidth;
  334. canvas.height = window.innerHeight; // Initialize the GL context
  335. var gl = canvas.getContext('webgl');
  336. if (!gl) {
  337. console.error("Unable to initialize WebGL.");
  338. }
  339. var layers_ = 10;
  340. if (mobile) {
  341. layers_ = 6;
  342. } //Time step
  343. var dt = 0.015; //Time
  344. var time = 0.0; //************** Shader sources **************
  345. var vertexSource = "\n\nattribute vec2 position;\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n}\n";
  346. var fragmentSource = "\nprecision highp float;\n\nuniform float width;\nuniform float height;\nvec2 resolution = vec2(width, height);\n\nuniform float time;\nfloat random(vec2 par){\n return fract(sin(dot(par.xy,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvec2 random2(vec2 par){\n\tfloat rand = random(par);\n\treturn vec2(rand, random(par+rand));\n}\n\n//https://www.shadertoy.com/view/3s3GDn\nfloat getGlow(float dist, float radius, float intensity){\n return pow(radius/dist, intensity);\n}\n\nvoid main(){\n\t\n\tfloat t = 1.0 + time * 0.05;\n const float layers = float(" + layers_ + ");\n float scale = 32.0;\n float depth;\n float phase;\n float rotationAngle = time * -0.1;\n float size;\n float glow;\n //Iteration step size for outermost loop\n const float del = 1.0/layers;\n \n vec2 uv;\n //Value of floor(uv)\n vec2 fl;\n vec2 local_uv;\n vec2 index;\n vec2 pos;\n //Seed for random values\n vec2 seed;\n vec2 centre; \n //The indices of 3x3 cells surrounding the fragment\n vec2 cell;\n //To move the focus of the camera in a circle\n vec2 rot = vec2(cos(t), sin(t));\n \n //To rotate layers\n mat2 rotation = mat2(cos(rotationAngle), -sin(rotationAngle), \n sin(rotationAngle), cos(rotationAngle));\n \tvec3 col = vec3(0);\n vec3 tone;\n \n //For all layers\n for(float i = 0.0; i <= 1.0; i+=del){\n \t//Find depth from layer index and move it in time\n depth = fract(i + t);\n \n //Move centre in a circle depending on the depth of the layer\n centre = rot * 0.2 * depth + 0.5;\n \n //Get uv from the fragment coordinates, rotation and depth\n \tuv = centre-gl_FragCoord.xy/resolution.x;\n uv *= rotation;\n \tuv *= mix(scale, 0.0, depth);\n fl = floor(uv);\n //The local cell coordinates. uv-fl == frac(uv)\n local_uv = uv - fl - 0.5;\n\n \n //For a 3x3 group of cells around the fragment, find the \n\t\t//distance from the points of each to the current fragment \n\t\t//and draw an accumulative glow accordingly\n for(float j = -1.0; j <= 1.0; j++){\n \tfor(float k = -1.0; k <= 1.0; k++){\n \t\tcell = vec2(j,k);\n \n index = fl + cell;\n \n //Cell seed\n \tseed = 128.0 * i + index;\n \n //Get a random position in relation to the considered cell\n pos = cell + 0.9 * (random2(seed) - 0.5);\n \n //Get a random phase\n phase = 128.0 * random(seed);\n //Get colour from cell information\n tone = vec3(random(seed), random(seed + 1.0), random(seed + 2.0));\n \n //Get distance to the generated point, fade distant points\n //and make glow radius pulse in time\n size = (0.1 + 0.5 + 0.5 * sin(phase * t)) * depth;\n glow = size * getGlow(length(local_uv-pos), 0.09, 2.0);\n //Add white core and glow\n col += 5.0 * vec3(0.02 * glow) + tone * glow;\n \t}\n \t}\n\t}\n \n //Tone mapping\n col = 1.0 - exp(-col);\n \n //Output to screen\n\tgl_FragColor = vec4(col,1.0);\n}\n"; //************** Utility functions **************
  347. window.addEventListener('resize', onWindowResize, false);
  348. function onWindowResize() {
  349. canvas.width = window.innerWidth;
  350. canvas.height = window.innerHeight;
  351. gl.viewport(0, 0, canvas.width, canvas.height);
  352. gl.uniform1f(widthHandle, window.innerWidth);
  353. gl.uniform1f(heightHandle, window.innerHeight);
  354. } //Compile shader and combine with source
  355. function compileShader(shaderSource, shaderType) {
  356. var shader = gl.createShader(shaderType);
  357. gl.shaderSource(shader, shaderSource);
  358. gl.compileShader(shader);
  359. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  360. throw "Shader compile failed with: " + gl.getShaderInfoLog(shader);
  361. }
  362. return shader;
  363. } //From https://codepen.io/jlfwong/pen/GqmroZ
  364. //Utility to complain loudly if we fail to find the attribute/uniform
  365. function getAttribLocation(program, name) {
  366. var attributeLocation = gl.getAttribLocation(program, name);
  367. if (attributeLocation === -1) {
  368. throw 'Cannot find attribute ' + name + '.';
  369. }
  370. return attributeLocation;
  371. }
  372. function getUniformLocation(program, name) {
  373. var attributeLocation = gl.getUniformLocation(program, name);
  374. if (attributeLocation === -1) {
  375. throw 'Cannot find uniform ' + name + '.';
  376. }
  377. return attributeLocation;
  378. } //************** Create shaders **************
  379. //Create vertex and fragment shaders
  380. var vertexShader = compileShader(vertexSource, gl.VERTEX_SHADER);
  381. var fragmentShader = compileShader(fragmentSource, gl.FRAGMENT_SHADER); //Create shader programs
  382. var program = gl.createProgram();
  383. gl.attachShader(program, vertexShader);
  384. gl.attachShader(program, fragmentShader);
  385. gl.linkProgram(program);
  386. gl.useProgram(program); //Set up rectangle covering entire canvas
  387. var vertexData = new Float32Array([-1.0, 1.0, // top left
  388. -1.0, -1.0, // bottom left
  389. 1.0, 1.0, // top right
  390. 1.0, -1.0 // bottom right
  391. ]); //Create vertex buffer
  392. var vertexDataBuffer = gl.createBuffer();
  393. gl.bindBuffer(gl.ARRAY_BUFFER, vertexDataBuffer);
  394. gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW); // Layout of our data in the vertex buffer
  395. var positionHandle = getAttribLocation(program, 'position');
  396. gl.enableVertexAttribArray(positionHandle);
  397. gl.vertexAttribPointer(positionHandle, 2, // position is a vec2 (2 values per component)
  398. gl.FLOAT, // each component is a float
  399. false, // don't normalize values
  400. 2 * 4, // two 4 byte float components per vertex (32 bit float is 4 bytes)
  401. 0 // how many bytes inside the buffer to start from
  402. ); //Set uniform handle
  403. var timeHandle = getUniformLocation(program, 'time');
  404. var widthHandle = getUniformLocation(program, 'width');
  405. var heightHandle = getUniformLocation(program, 'height');
  406. gl.uniform1f(widthHandle, window.innerWidth);
  407. gl.uniform1f(heightHandle, window.innerHeight);
  408. function draw() {
  409. //Update time
  410. time += dt; //Send uniforms to program
  411. gl.uniform1f(timeHandle, time); //Draw a triangle strip connecting vertices 0-4
  412. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  413. requestAnimationFrame(draw);
  414. }
  415. </script>
  416. </body>
  417. </html>