{"id":363,"date":"2014-12-31T21:00:52","date_gmt":"2014-12-31T13:00:52","guid":{"rendered":"http:\/\/www.hightopo.com\/blog\/?p=363"},"modified":"2014-12-31T21:06:45","modified_gmt":"2014-12-31T13:06:45","slug":"%e7%ba%afshading-language%e7%bb%98%e5%88%b6html5%e6%97%b6%e9%92%9f","status":"publish","type":"post","link":"https:\/\/www.hightopo.com\/blog\/363.html","title":{"rendered":"\u7eafShading Language\u7ed8\u5236HTML5\u65f6\u949f"},"content":{"rendered":"<p>\u4eca\u5929\u662f2014\u5e74\u7684\u6700\u540e\u4e00\u5929\uff0c\u8fd9\u4e2a\u65f6\u523b\u603b\u4f1a\u8ba9\u4eba\u60f3\u8d77\u65f6\u949f\uff0c\u518d\u8fc7\u51e0\u4e2a\u5c0f\u65f6\u5730\u7403\u4eba\u90fd\u8981\u518d\u8001\u4e86\u4e00\u5c81\uff0c\u4e8e\u662f\u641e\u4e2aHTML5\u7248\u7684\u65f6\u949f\u5c31\u662f\u6211\u4eec\u4eca\u5929\u8981\u5b8c\u6210\u7684\u4efb\u52a1\uff0c\u5b9e\u73b0HTML5\u7684\u65f6\u949f\u7ed8\u5236\u4e00\u822c\u4f1a\u91c7\u7528\u4e09\u79cd\u65b9\u5f0f\uff0c\u7b2c\u4e00\u79cd\u91c7\u7528CSS\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4f8b\u5982\u00a0<a href=\"http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/\">http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/\u00a0<\/a>\uff1b\u7b2c\u4e8c\u79cd\u91c7\u7528SVG\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4f8b\u5982\u00a0<a href=\"http:\/\/html5demos.com\/svg-clock\">http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/<\/a>\uff1b\u7b2c\u4e09\u79cd\u91c7\u7528Cavnas\u76842D\u7ed8\u5236\u65b9\u5f0f\uff0c\u5982<a href=\"http:\/\/www.hightopo.com\/\">HT for Web<\/a>\u4e2d\u300a<a href=\"http:\/\/www.hightopo.com\/\">\u77e2\u91cf\u624b\u518c<\/a>\u300b\u4e2d\u81ea\u5b9a\u4e49\u7ed8\u5236\u7684clock\u4f8b\u5b50\uff0cHT\u7684\u4f8b\u5b50\u7684\u5b9e\u73b0\u6548\u679c\u5982\u4e0b\uff0c\u5176\u5b9e\u73b0\u4ee3\u7801\u9644\u5728\u672c\u6587\u7684\u6700\u540e\u90e8\u5206\u3002<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-364\" alt=\"Screen Shot 2014-12-31 at 8.19.17 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png\" width=\"280\" height=\"271\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png 280w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM-200x193.png 200w\" sizes=\"(max-width: 280px) 100vw, 280px\" \/><\/a><\/p>\n<p>\u4ee5\u4e0a\u4e09\u79cd\u65b9\u5f0f\u90fd\u662f\u8f83\u5bb9\u6613\u7406\u89e3\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4eca\u5929\u6211\u4eec\u5c06\u91c7\u7528\u7684\u5219\u662f\u8f83\u4e3a\u5c11\u89c1\u7684WebGL\u7eafShading Language\u5b9e\u73b0\u65b9\u5f0f\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6781\u5176\u9ad8\u6548\uff0c\u6bd5\u7adf\u6211\u4eec\u91c7\u7528\u7684\u662f\u53ef\u5229\u7528GPU\u786c\u4ef6\u52a0\u901f\u7684WebGL\u6280\u672f\uff0cCPU\u4ee3\u7801\u89d2\u5ea6\u770b\u4ec5\u6709\u4e24\u4e2a\u4e09\u89d2\u5f62\u7684\u7ed8\u5236\uff0c\u771f\u6b63\u8868\u76d8\u7684\u7ed8\u5236\u903b\u8f91\u5b8c\u5168\u5728GPU\u5bf9\u4e24\u4e2a\u4e09\u89d2\u5f62\u8fdb\u884cFragment Shading\u65f6\u5b9e\u73b0\u3002<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-365\" alt=\"Screen Shot 2014-12-31 at 8.08.48 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png\" width=\"1048\" height=\"638\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png 1048w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-300x182.png 300w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-1024x623.png 1024w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-200x121.png 200w\" sizes=\"(max-width: 1048px) 100vw, 1048px\" \/><\/a><\/p>\n<p>\u53ef\u901a\u8fc7\u8fd9\u91cc\u00a0<a href=\"http:\/\/js.do\/hightopo\/glsl-clock\">http:\/\/js.do\/hightopo\/glsl-clock<\/a> \u73a9\u73a9\u6700\u540e\u7684\u5b9e\u73b0\u6548\u679c\u4ee5\u53ca\u5b9e\u73b0\u4ee3\u7801\uff0c\u91c7\u7528GLSL\u7684\u5b9e\u73b0\u6700\u91cd\u8981\u7684\u5c31\u662f\u51b3\u5b9a\u5f53\u524d\u5750\u6807\u4f4d\u7f6e\u7684gl_FragColor\u7684\u989c\u8272\uff0c\u6211\u4eec\u5c06\u59cb\u7ec8\u5206\u4e3a\u8868\u76d8\u3001\u5916\u5708\u3001\u523b\u5ea6\u3001\u65f6\u9488\u3001\u5206\u9488\u548c\u79d2\u9488\u51e0\u4e2a\u90e8\u5206\uff0c\u4ee3\u7801\u540e\u90e8\u5206\u7684\u7559\u4e2a\u8fde\u7eedBlend\u4ee3\u7801\u76f8\u5f53\u4e8e\u9010\u5c42\u7ed8\u5236\u7684\u903b\u8f91\uff0c\u4ee5\u4e0b\u51e0\u4e2a\u51fd\u6570\u6280\u672f\u70b9\u8bf4\u660e\uff1a<\/p>\n<ul>\n<li>Rect\u51fd\u6570\u4e2d\u7684clamp(uv, -size\/2.0, size\/2.0))\u662f\u6211\u4eec\u51b3\u5b9a\u70b9\u662f\u5426\u5728\u77e9\u5f62\u533a\u57df\u7684\u6280\u5de7<\/li>\n<li>\u51fd\u6570Rotate(vec2 uv,float angle)\u5c06\u5750\u6807\u70b9\u65cb\u8f6c\u5230\u6c34\u5e73\u6216\u5782\u76f4\u4f4d\u7f6e\u65b9\u4fbf\u6211\u4eec\u786e\u5b9aRect\u548cLine\u53c2\u6570\u8fdb\u884c\u5bf9\u6bd4<\/li>\n<li>Blend\u51fd\u6570mix(shapeColor, backColor, smoothstep(0.0, 0.005, shape))\u662f\u5e38\u7528\u7684\u6df7\u5408mix\u548csmoothstep\u8fbe\u5230\u66f4\u597d\u5904\u7406\u8fb9\u7f18\u5e73\u6ed1\u6548\u679cGLSL\u5e38\u7528\u6280\u5de7<\/li>\n<\/ul>\n<p>\u4e3a\u4e86\u8bf4\u660emix\u548csmoothstep\u7684\u878d\u5408\u6548\u679c\uff0c\u6211\u641e\u4e86\u4e2a\u00a0<a href=\"http:\/\/js.do\/hightopo\/glsl-smooth-clrcle\">http:\/\/js.do\/hightopo\/glsl-smooth-clrcle<\/a>\u00a0\u7684\u4f8b\u5b50\uff0c\u4f60\u53ef\u4ee5\u5c1d\u8bd5\u53bb\u6389#define SMOOTH\u540e\u8fb9\u7f18\u952f\u9f7f\u8f83\u660e\u663e\u7684\u95ee\u9898\uff0c\u4e5f\u53ef\u4ee5\u8c03\u8282smoothstep(0.49, 0.5, d)\u76840.49\u4e3a0.3\u7b49\u8f83\u5c0f\u7684\u53c2\u6570\u4f53\u9a8c\u6e10\u8fdb\u7684\u6548\u679c\uff0c\u4ee5\u4e0b\u4e3a\u51e0\u79cd\u6548\u679c\u7684\u7efc\u5408\u5bf9\u6bd4<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-366\" alt=\"Screen Shot 2014-12-31 at 7.09.28 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png\" width=\"1368\" height=\"392\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png 1368w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-300x85.png 300w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-1024x293.png 1024w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-200x57.png 200w\" sizes=\"(max-width: 1368px) 100vw, 1368px\" \/><\/a><\/p>\n<p>GLSL\u7684Fragment Shader\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre class=\"brush:javascript\">#ifdef GL_ES\r\nprecision mediump float;\r\n#endif\r\n\r\nuniform float time;\r\nuniform vec2 resolution;\r\n\r\nfloat pi = 3.1415926; \r\nfloat tau = pi * 2.0;\r\n\r\nvec2 Rotate(vec2 uv,float angle);\r\n\r\nfloat Circle(vec2 uv,float r);\r\nfloat Rect(vec2 uv,vec2 size,float r);\r\nfloat Line(vec2 uv,vec2 start,vec2 end,float r);\r\nfloat Merge(float a,float b);\r\nfloat Outline(float a,float r);\r\n\r\nvec3 Blend(vec3 backColor, vec3 shapeColor, float shape);\r\n\r\nfloat SecStep(float x); \r\n\r\nvoid main( void ) \r\n{\r\n\t\tvec2 res = resolution \/ resolution.y;\r\n\t\tvec2 uv = ( gl_FragCoord.xy \/ resolution.y );\r\n\t\tuv -= res \/ 2.0;                                       \r\n\r\n\t\tfloat secAng = (SecStep(time) \/ 60.0) * tau;\r\n\t\tfloat minAng = (time \/ 3600.0) * tau;\r\n\t\tfloat hourAng = (time \/ 43200.0) * tau;\r\n\r\n\t\tfloat clockFace = Circle(uv, 0.45);\r\n\t\tfloat clockTrim = Outline(clockFace, 0.01);\r\n\r\n\t\tvec2 secDomain = Rotate(uv, secAng); \r\n\t\tfloat clockSec = Line(secDomain, vec2(0.0, -0.15), vec2(0.0, 0.35), 0.001);\r\n\t\tclockSec = Merge(clockSec, Circle(uv, 0.01));\r\n\t\tclockSec = Merge(clockSec, Rect(secDomain - vec2(0.0, -0.08), vec2(0.012, 0.07), 0.0));\r\n\r\n\t\tfloat clockMin = Line(Rotate(uv, minAng), vec2(0.0,-0.08), vec2(0.0, 0.35), 0.005);\r\n\t\tfloat clockHour = Line(Rotate(uv, hourAng), vec2(0.0,-0.05), vec2(0.0,0.3), 0.007);\r\n\t\tclockHour = Merge(clockHour, Circle(uv, 0.02));\r\n\r\n\t\tfloat tickMarks = 1.0;\r\n\t\tvec2 tickDomain = uv;\r\n\t\tfor(int i = 0;i &lt; 60;i++)\r\n\t\t{\r\n\t\t\ttickDomain = Rotate(tickDomain, tau \/ 60.0);\r\n\t\t\tvec2 size = (mod(float(i + 1), 5.0) == 0.0) ? vec2(0.08, 0.01) : vec2(0.04, 0.002); \r\n\t\t\ttickMarks = Merge(tickMarks, Rect(tickDomain - vec2(0.38, 0.0), size, 0.0));\r\n\t\t}\r\n\r\n\t\tvec3 faceColor = mix(vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), uv.x+0.5); \r\n\t\tvec3 trimColor = mix(vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0), uv.y + 0.5); \r\n\t\tvec3 secColor = vec3(1.0, 0.0, 0.0); \r\n\t\tvec3 handColor = vec3(0.0, 0.0, 0.0);\r\n\r\n\t\tvec3 color = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0), uv.y+0.5);\r\n\t\tcolor = Blend(color, faceColor, clockFace);\r\n\t\tcolor = Blend(color, trimColor, clockTrim);\r\n\t\tcolor = Blend(color, trimColor, tickMarks);                    \r\n\t\tcolor = Blend(color, handColor, clockHour);\r\n\t\tcolor = Blend(color, handColor, clockMin);\r\n\t\tcolor = Blend(color, secColor, clockSec);\t\r\n\r\n\t\tgl_FragColor = vec4(color, 1.0);\r\n}\r\nfloat SecStep(float x)\r\n{\r\n\tfloat interp = smoothstep(0.80, 1.0, mod(x, 1.0));\r\n\treturn floor(x) + interp + (sin(interp * pi)) ;\r\n}            \r\nfloat Line(vec2 uv,vec2 start,vec2 end,float r)\r\n{\r\n\treturn Rect(uv-(end+start)\/2.0, vec2(r, end.y - start.y), r);\r\n}\r\nfloat Rect(vec2 uv,vec2 size,float r)\r\n{\r\n\treturn length(uv - clamp(uv, -size\/2.0, size\/2.0)) - r;\t\r\n}            \r\nvec2 Rotate(vec2 uv,float angle)\r\n{\r\n\treturn mat2(cos(angle), sin(angle),-sin(angle), cos(angle)) * uv;\r\n}\r\nfloat Circle(vec2 uv,float r)\r\n{\r\n\treturn length(uv) - r;\t\r\n}\r\nfloat Merge(float a,float b)\r\n{\r\n\treturn min(a, b);\t\r\n}\r\nfloat Outline(float a,float r)\r\n{\r\n\treturn abs(a) - r;\t\r\n}\r\nvec3 Blend(vec3 backColor, vec3 shapeColor, float shape)\r\n{       \r\n\treturn mix(shapeColor, backColor, smoothstep(0.0, 0.005, shape));\r\n}<\/pre>\n<p><a href=\"http:\/\/www.hightopo.com\/\">HT for Web<\/a>\u4e2d\u300a<a href=\"http:\/\/www.hightopo.com\/\">\u77e2\u91cf\u624b\u518c<\/a>\u300b\u4e2d\u81ea\u5b9a\u4e49\u7ed8\u5236\u7684clock\u4f8b\u5b50\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre class=\"brush:javascript\">\r\nfunction init() {\r\n\tdataModel = new ht.DataModel();\r\n\tgraphView = new ht.graph.GraphView(dataModel);\r\n\tview = graphView.getView();\r\n\r\n\tview.className = 'main';\r\n\tdocument.body.appendChild(view);\r\n\twindow.addEventListener('resize', function(e) {\r\n\t\tgraphView.invalidate();\r\n\t}, false);\r\n\r\n\tht.Default.setCompType('clock-face', function(g, rect, comp, data, view) {\r\n\t\tvar cx = rect.x + rect.width \/ 2;\r\n\t\tvar cy = rect.y + rect.height \/ 2;\r\n\t\tvar theta = 0;\r\n\t\tvar r = Math.min(rect.width, rect.height)\/2 * 0.92;\r\n\t\t\r\n\t\tg.strokeStyle = \"#137\";\r\n\t\tfor (var i = 0; i < 60; i++) {                        \r\n\t\t\tg.beginPath();\r\n\t\t\tg.arc(\r\n\t\t\t\tcx + Math.cos(theta) * r, \r\n\t\t\t\tcy + Math.sin(theta) * r, \r\n\t\t\t\ti % 5 === 0 ? 4 : 1, \r\n\t\t\t\t0, Math.PI * 2, true);\r\n\t\t\tg.closePath();\r\n\t\t\tg.lineWidth = i % 5 === 0 ? 2 : 1;\r\n\t\t\tg.stroke();\r\n\t\t\ttheta = theta + (6 * Math.PI \/ 180);\r\n\t\t}\r\n\t});\r\n\r\n\tht.Default.setImage('clock', {\r\n\t\twidth: 500,\r\n\t\theight: 500,\r\n\t\tcomps: [\r\n\t\t\t{\r\n\t\t\t\ttype: 'circle',\r\n\t\t\t\trelative: true,\r\n\t\t\t\trect: [0, 0, 1, 1],\r\n\t\t\t\tbackground: 'yellow',\r\n\t\t\t\tgradient: 'linear.northeast'\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: 'clock-face',\r\n\t\t\t\trelative: true,\r\n\t\t\t\trect: [0, 0, 1, 1]\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: function(g, rect, comp, data, view) {\r\n\t\t\t\t\t\/\/ get current time\r\n\t\t\t\t\tvar date = data.a('date');\r\n\t\t\t\t\tif(!date){\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar hours = date.getHours();\r\n\t\t\t\t\tvar minutes = date.getMinutes();\r\n\t\t\t\t\tvar seconds = date.getSeconds();\r\n\t\t\t\t\thours = hours > 12 ? hours - 12 : hours;\r\n\t\t\t\t\tvar hour = hours + minutes \/ 60;\r\n\t\t\t\t\tvar minute = minutes + seconds \/ 60;\r\n\t\t\t\t\tvar clockRadius = 250;\r\n\r\n\t\t\t\t\t\/\/ save current context\r\n\t\t\t\t\tg.save();\r\n\r\n\t\t\t\t\tg.translate(clockRadius, clockRadius);\r\n\t\t\t\t\tg.beginPath();\r\n\r\n\t\t\t\t\t\/\/ draw numbers\r\n\t\t\t\t\tg.font = '36px Arial';\r\n\t\t\t\t\tg.fillStyle = '#000';\r\n\t\t\t\t\tg.textAlign = 'center';\r\n\t\t\t\t\tg.textBaseline = 'middle';\r\n\t\t\t\t\tfor (var n = 1; n <= 12; n++) {\r\n\t\t\t\t\t\tvar theta = (n - 3) * (Math.PI * 2) \/ 12;\r\n\t\t\t\t\t\tvar x = clockRadius * 0.75 * Math.cos(theta);\r\n\t\t\t\t\t\tvar y = clockRadius * 0.75 * Math.sin(theta);\r\n\t\t\t\t\t\tg.fillText(n, x, y);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\/\/ draw hour\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (hour - 3) * 2 * Math.PI \/ 12;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -5);\r\n\t\t\t\t\tg.lineTo(-15, 5);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.5, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.5, -1);\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\t\/\/ draw minute\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (minute - 15) * 2 * Math.PI \/ 60;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -4);\r\n\t\t\t\t\tg.lineTo(-15, 4);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.8, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.8, -1);\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\t\/\/ draw second\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (seconds - 15) * 2 * Math.PI \/ 60;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -3);\r\n\t\t\t\t\tg.lineTo(-15, 3);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.9, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.9, -1);\r\n\t\t\t\t\tg.fillStyle = '#0f0';\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\tg.restore();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t]\r\n\t});\r\n\r\n\tvar node = new ht.Node();\r\n\tnode.setPosition(150, 150);\r\n\tnode.setSize(250, 250);\r\n\tnode.setImage('clock');\r\n\tnode.a('date', new Date());\r\n\tnode.s('image.stretch', 'centerUniform');\r\n\tdataModel.add(node);\r\n\r\n\tgraphView.setEditable(true);\r\n\t\r\n\tsetInterval(function(){\r\n\t\tnode.a('date', new Date());\r\n\t}, 1000);\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4eca\u5929\u662f2014\u5e74\u7684\u6700\u540e\u4e00\u5929\uff0c\u8fd9\u4e2a\u65f6\u523b\u603b\u4f1a\u8ba9\u4eba\u60f3\u8d77\u65f6\u949f\uff0c\u518d\u8fc7\u51e0\u4e2a\u5c0f\u65f6\u5730\u7403\u4eba\u90fd\u8981\u518d\u8001\u4e86\u4e00\u5c81\uff0c\u4e8e\u662f\u641e\u4e2aHTML5\u7248\u7684\u65f6\u949f\u5c31\u662f\u6211\u4eec\u4eca\u5929\u8981\u5b8c\u6210\u7684\u4efb\u52a1\uff0c\u5b9e\u73b0HTML5\u7684\u65f6\u949f\u7ed8\u5236\u4e00\u822c\u4f1a\u91c7\u7528\u4e09\u79cd\u65b9\u5f0f\uff0c\u7b2c\u4e00\u79cd\u91c7\u7528CSS\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4f8b\u5982\u00a0<a href=\"http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/\">http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/\u00a0<\/a>\uff1b\u7b2c\u4e8c\u79cd\u91c7\u7528SVG\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4f8b\u5982\u00a0<a href=\"http:\/\/html5demos.com\/svg-clock\">http:\/\/www.css-tricks.com\/examples\/CSS3Clock\/<\/a>\uff1b\u7b2c\u4e09\u79cd\u91c7\u7528Cavnas\u76842D\u7ed8\u5236\u65b9\u5f0f\uff0c\u5982<a href=\"http:\/\/www.hightopo.com\/\">HT for Web<\/a>\u4e2d\u300a<a href=\"http:\/\/www.hightopo.com\/\">\u77e2\u91cf\u624b\u518c<\/a>\u300b\u4e2d\u81ea\u5b9a\u4e49\u7ed8\u5236\u7684clock\u4f8b\u5b50\uff0cHT\u7684\u4f8b\u5b50\u7684\u5b9e\u73b0\u6548\u679c\u5982\u4e0b\uff0c\u5176\u5b9e\u73b0\u4ee3\u7801\u9644\u5728\u672c\u6587\u7684\u6700\u540e\u90e8\u5206\u3002<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-364\" alt=\"Screen Shot 2014-12-31 at 8.19.17 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png\" width=\"280\" height=\"271\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM.png 280w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.19.17-PM-200x193.png 200w\" sizes=\"(max-width: 280px) 100vw, 280px\" \/><\/a><\/p>\n<p>\u4ee5\u4e0a\u4e09\u79cd\u65b9\u5f0f\u90fd\u662f\u8f83\u5bb9\u6613\u7406\u89e3\u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4eca\u5929\u6211\u4eec\u5c06\u91c7\u7528\u7684\u5219\u662f\u8f83\u4e3a\u5c11\u89c1\u7684WebGL\u7eafShading Language\u5b9e\u73b0\u65b9\u5f0f\uff0c\u8fd9\u79cd\u65b9\u5f0f\u6781\u5176\u9ad8\u6548\uff0c\u6bd5\u7adf\u6211\u4eec\u91c7\u7528\u7684\u662f\u53ef\u5229\u7528GPU\u786c\u4ef6\u52a0\u901f\u7684WebGL\u6280\u672f\uff0cCPU\u4ee3\u7801\u89d2\u5ea6\u770b\u4ec5\u6709\u4e24\u4e2a\u4e09\u89d2\u5f62\u7684\u7ed8\u5236\uff0c\u771f\u6b63\u8868\u76d8\u7684\u7ed8\u5236\u903b\u8f91\u5b8c\u5168\u5728GPU\u5bf9\u4e24\u4e2a\u4e09\u89d2\u5f62\u8fdb\u884cFragment Shading\u65f6\u5b9e\u73b0\u3002<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-365\" alt=\"Screen Shot 2014-12-31 at 8.08.48 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png\" width=\"1048\" height=\"638\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM.png 1048w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-300x182.png 300w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-1024x623.png 1024w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-8.08.48-PM-200x121.png 200w\" sizes=\"(max-width: 1048px) 100vw, 1048px\" \/><\/a><\/p>\n<p>\u53ef\u901a\u8fc7\u8fd9\u91cc\u00a0<a href=\"http:\/\/js.do\/hightopo\/glsl-clock\">http:\/\/js.do\/hightopo\/glsl-clock<\/a> \u73a9\u73a9\u6700\u540e\u7684\u5b9e\u73b0\u6548\u679c\u4ee5\u53ca\u5b9e\u73b0\u4ee3\u7801\uff0c\u91c7\u7528GLSL\u7684\u5b9e\u73b0\u6700\u91cd\u8981\u7684\u5c31\u662f\u51b3\u5b9a\u5f53\u524d\u5750\u6807\u4f4d\u7f6e\u7684gl_FragColor\u7684\u989c\u8272\uff0c\u6211\u4eec\u5c06\u59cb\u7ec8\u5206\u4e3a\u8868\u76d8\u3001\u5916\u5708\u3001\u523b\u5ea6\u3001\u65f6\u9488\u3001\u5206\u9488\u548c\u79d2\u9488\u51e0\u4e2a\u90e8\u5206\uff0c\u4ee3\u7801\u540e\u90e8\u5206\u7684\u7559\u4e2a\u8fde\u7eedBlend\u4ee3\u7801\u76f8\u5f53\u4e8e\u9010\u5c42\u7ed8\u5236\u7684\u903b\u8f91\uff0c\u4ee5\u4e0b\u51e0\u4e2a\u51fd\u6570\u6280\u672f\u70b9\u8bf4\u660e\uff1a<\/p>\n<ul>\n<li>Rect\u51fd\u6570\u4e2d\u7684clamp(uv, -size\/2.0, size\/2.0))\u662f\u6211\u4eec\u51b3\u5b9a\u70b9\u662f\u5426\u5728\u77e9\u5f62\u533a\u57df\u7684\u6280\u5de7<\/li>\n<li>\u51fd\u6570Rotate(vec2 uv,float angle)\u5c06\u5750\u6807\u70b9\u65cb\u8f6c\u5230\u6c34\u5e73\u6216\u5782\u76f4\u4f4d\u7f6e\u65b9\u4fbf\u6211\u4eec\u786e\u5b9aRect\u548cLine\u53c2\u6570\u8fdb\u884c\u5bf9\u6bd4<\/li>\n<li>Blend\u51fd\u6570mix(shapeColor, backColor, smoothstep(0.0, 0.005, shape))\u662f\u5e38\u7528\u7684\u6df7\u5408mix\u548csmoothstep\u8fbe\u5230\u66f4\u597d\u5904\u7406\u8fb9\u7f18\u5e73\u6ed1\u6548\u679cGLSL\u5e38\u7528\u6280\u5de7<\/li>\n<\/ul>\n<p>\u4e3a\u4e86\u8bf4\u660emix\u548csmoothstep\u7684\u878d\u5408\u6548\u679c\uff0c\u6211\u641e\u4e86\u4e2a\u00a0<a href=\"http:\/\/js.do\/hightopo\/glsl-smooth-clrcle\">http:\/\/js.do\/hightopo\/glsl-smooth-clrcle<\/a>\u00a0\u7684\u4f8b\u5b50\uff0c\u4f60\u53ef\u4ee5\u5c1d\u8bd5\u53bb\u6389#define SMOOTH\u540e\u8fb9\u7f18\u952f\u9f7f\u8f83\u660e\u663e\u7684\u95ee\u9898\uff0c\u4e5f\u53ef\u4ee5\u8c03\u8282smoothstep(0.49, 0.5, d)\u76840.49\u4e3a0.3\u7b49\u8f83\u5c0f\u7684\u53c2\u6570\u4f53\u9a8c\u6e10\u8fdb\u7684\u6548\u679c\uff0c\u4ee5\u4e0b\u4e3a\u51e0\u79cd\u6548\u679c\u7684\u7efc\u5408\u5bf9\u6bd4<\/p>\n<p><a href=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-366\" alt=\"Screen Shot 2014-12-31 at 7.09.28 PM\" src=\"http:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png\" width=\"1368\" height=\"392\" srcset=\"https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM.png 1368w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-300x85.png 300w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-1024x293.png 1024w, https:\/\/www.hightopo.com\/blog\/wp-content\/uploads\/2014\/12\/Screen-Shot-2014-12-31-at-7.09.28-PM-200x57.png 200w\" sizes=\"(max-width: 1368px) 100vw, 1368px\" \/><\/a><\/p>\n<p>GLSL\u7684Fragment Shader\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre class=\"brush:javascript\">#ifdef GL_ES\r\nprecision mediump float;\r\n#endif\r\n\r\nuniform float time;\r\nuniform vec2 resolution;\r\n\r\nfloat pi = 3.1415926; \r\nfloat tau = pi * 2.0;\r\n\r\nvec2 Rotate(vec2 uv,float angle);\r\n\r\nfloat Circle(vec2 uv,float r);\r\nfloat Rect(vec2 uv,vec2 size,float r);\r\nfloat Line(vec2 uv,vec2 start,vec2 end,float r);\r\nfloat Merge(float a,float b);\r\nfloat Outline(float a,float r);\r\n\r\nvec3 Blend(vec3 backColor, vec3 shapeColor, float shape);\r\n\r\nfloat SecStep(float x); \r\n\r\nvoid main( void ) \r\n{\r\n\t\tvec2 res = resolution \/ resolution.y;\r\n\t\tvec2 uv = ( gl_FragCoord.xy \/ resolution.y );\r\n\t\tuv -= res \/ 2.0;                                       \r\n\r\n\t\tfloat secAng = (SecStep(time) \/ 60.0) * tau;\r\n\t\tfloat minAng = (time \/ 3600.0) * tau;\r\n\t\tfloat hourAng = (time \/ 43200.0) * tau;\r\n\r\n\t\tfloat clockFace = Circle(uv, 0.45);\r\n\t\tfloat clockTrim = Outline(clockFace, 0.01);\r\n\r\n\t\tvec2 secDomain = Rotate(uv, secAng); \r\n\t\tfloat clockSec = Line(secDomain, vec2(0.0, -0.15), vec2(0.0, 0.35), 0.001);\r\n\t\tclockSec = Merge(clockSec, Circle(uv, 0.01));\r\n\t\tclockSec = Merge(clockSec, Rect(secDomain - vec2(0.0, -0.08), vec2(0.012, 0.07), 0.0));\r\n\r\n\t\tfloat clockMin = Line(Rotate(uv, minAng), vec2(0.0,-0.08), vec2(0.0, 0.35), 0.005);\r\n\t\tfloat clockHour = Line(Rotate(uv, hourAng), vec2(0.0,-0.05), vec2(0.0,0.3), 0.007);\r\n\t\tclockHour = Merge(clockHour, Circle(uv, 0.02));\r\n\r\n\t\tfloat tickMarks = 1.0;\r\n\t\tvec2 tickDomain = uv;\r\n\t\tfor(int i = 0;i &lt; 60;i++)\r\n\t\t{\r\n\t\t\ttickDomain = Rotate(tickDomain, tau \/ 60.0);\r\n\t\t\tvec2 size = (mod(float(i + 1), 5.0) == 0.0) ? vec2(0.08, 0.01) : vec2(0.04, 0.002); \r\n\t\t\ttickMarks = Merge(tickMarks, Rect(tickDomain - vec2(0.38, 0.0), size, 0.0));\r\n\t\t}\r\n\r\n\t\tvec3 faceColor = mix(vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), uv.x+0.5); \r\n\t\tvec3 trimColor = mix(vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0), uv.y + 0.5); \r\n\t\tvec3 secColor = vec3(1.0, 0.0, 0.0); \r\n\t\tvec3 handColor = vec3(0.0, 0.0, 0.0);\r\n\r\n\t\tvec3 color = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0), uv.y+0.5);\r\n\t\tcolor = Blend(color, faceColor, clockFace);\r\n\t\tcolor = Blend(color, trimColor, clockTrim);\r\n\t\tcolor = Blend(color, trimColor, tickMarks);                    \r\n\t\tcolor = Blend(color, handColor, clockHour);\r\n\t\tcolor = Blend(color, handColor, clockMin);\r\n\t\tcolor = Blend(color, secColor, clockSec);\t\r\n\r\n\t\tgl_FragColor = vec4(color, 1.0);\r\n}\r\nfloat SecStep(float x)\r\n{\r\n\tfloat interp = smoothstep(0.80, 1.0, mod(x, 1.0));\r\n\treturn floor(x) + interp + (sin(interp * pi)) ;\r\n}            \r\nfloat Line(vec2 uv,vec2 start,vec2 end,float r)\r\n{\r\n\treturn Rect(uv-(end+start)\/2.0, vec2(r, end.y - start.y), r);\r\n}\r\nfloat Rect(vec2 uv,vec2 size,float r)\r\n{\r\n\treturn length(uv - clamp(uv, -size\/2.0, size\/2.0)) - r;\t\r\n}            \r\nvec2 Rotate(vec2 uv,float angle)\r\n{\r\n\treturn mat2(cos(angle), sin(angle),-sin(angle), cos(angle)) * uv;\r\n}\r\nfloat Circle(vec2 uv,float r)\r\n{\r\n\treturn length(uv) - r;\t\r\n}\r\nfloat Merge(float a,float b)\r\n{\r\n\treturn min(a, b);\t\r\n}\r\nfloat Outline(float a,float r)\r\n{\r\n\treturn abs(a) - r;\t\r\n}\r\nvec3 Blend(vec3 backColor, vec3 shapeColor, float shape)\r\n{       \r\n\treturn mix(shapeColor, backColor, smoothstep(0.0, 0.005, shape));\r\n}<\/pre>\n<p><a href=\"http:\/\/www.hightopo.com\/\">HT for Web<\/a>\u4e2d\u300a<a href=\"http:\/\/www.hightopo.com\/\">\u77e2\u91cf\u624b\u518c<\/a>\u300b\u4e2d\u81ea\u5b9a\u4e49\u7ed8\u5236\u7684clock\u4f8b\u5b50\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre class=\"brush:javascript\">\r\nfunction init() {\r\n\tdataModel = new ht.DataModel();\r\n\tgraphView = new ht.graph.GraphView(dataModel);\r\n\tview = graphView.getView();\r\n\r\n\tview.className = 'main';\r\n\tdocument.body.appendChild(view);\r\n\twindow.addEventListener('resize', function(e) {\r\n\t\tgraphView.invalidate();\r\n\t}, false);\r\n\r\n\tht.Default.setCompType('clock-face', function(g, rect, comp, data, view) {\r\n\t\tvar cx = rect.x + rect.width \/ 2;\r\n\t\tvar cy = rect.y + rect.height \/ 2;\r\n\t\tvar theta = 0;\r\n\t\tvar r = Math.min(rect.width, rect.height)\/2 * 0.92;\r\n\t\t\r\n\t\tg.strokeStyle = \"#137\";\r\n\t\tfor (var i = 0; i < 60; i++) {                        \r\n\t\t\tg.beginPath();\r\n\t\t\tg.arc(\r\n\t\t\t\tcx + Math.cos(theta) * r, \r\n\t\t\t\tcy + Math.sin(theta) * r, \r\n\t\t\t\ti % 5 === 0 ? 4 : 1, \r\n\t\t\t\t0, Math.PI * 2, true);\r\n\t\t\tg.closePath();\r\n\t\t\tg.lineWidth = i % 5 === 0 ? 2 : 1;\r\n\t\t\tg.stroke();\r\n\t\t\ttheta = theta + (6 * Math.PI \/ 180);\r\n\t\t}\r\n\t});\r\n\r\n\tht.Default.setImage('clock', {\r\n\t\twidth: 500,\r\n\t\theight: 500,\r\n\t\tcomps: [\r\n\t\t\t{\r\n\t\t\t\ttype: 'circle',\r\n\t\t\t\trelative: true,\r\n\t\t\t\trect: [0, 0, 1, 1],\r\n\t\t\t\tbackground: 'yellow',\r\n\t\t\t\tgradient: 'linear.northeast'\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: 'clock-face',\r\n\t\t\t\trelative: true,\r\n\t\t\t\trect: [0, 0, 1, 1]\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\ttype: function(g, rect, comp, data, view) {\r\n\t\t\t\t\t\/\/ get current time\r\n\t\t\t\t\tvar date = data.a('date');\r\n\t\t\t\t\tif(!date){\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar hours = date.getHours();\r\n\t\t\t\t\tvar minutes = date.getMinutes();\r\n\t\t\t\t\tvar seconds = date.getSeconds();\r\n\t\t\t\t\thours = hours > 12 ? hours - 12 : hours;\r\n\t\t\t\t\tvar hour = hours + minutes \/ 60;\r\n\t\t\t\t\tvar minute = minutes + seconds \/ 60;\r\n\t\t\t\t\tvar clockRadius = 250;\r\n\r\n\t\t\t\t\t\/\/ save current context\r\n\t\t\t\t\tg.save();\r\n\r\n\t\t\t\t\tg.translate(clockRadius, clockRadius);\r\n\t\t\t\t\tg.beginPath();\r\n\r\n\t\t\t\t\t\/\/ draw numbers\r\n\t\t\t\t\tg.font = '36px Arial';\r\n\t\t\t\t\tg.fillStyle = '#000';\r\n\t\t\t\t\tg.textAlign = 'center';\r\n\t\t\t\t\tg.textBaseline = 'middle';\r\n\t\t\t\t\tfor (var n = 1; n <= 12; n++) {\r\n\t\t\t\t\t\tvar theta = (n - 3) * (Math.PI * 2) \/ 12;\r\n\t\t\t\t\t\tvar x = clockRadius * 0.75 * Math.cos(theta);\r\n\t\t\t\t\t\tvar y = clockRadius * 0.75 * Math.sin(theta);\r\n\t\t\t\t\t\tg.fillText(n, x, y);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\/\/ draw hour\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (hour - 3) * 2 * Math.PI \/ 12;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -5);\r\n\t\t\t\t\tg.lineTo(-15, 5);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.5, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.5, -1);\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\t\/\/ draw minute\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (minute - 15) * 2 * Math.PI \/ 60;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -4);\r\n\t\t\t\t\tg.lineTo(-15, 4);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.8, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.8, -1);\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\t\/\/ draw second\r\n\t\t\t\t\tg.save();\r\n\t\t\t\t\tvar theta = (seconds - 15) * 2 * Math.PI \/ 60;\r\n\t\t\t\t\tg.rotate(theta);\r\n\t\t\t\t\tg.beginPath();\r\n\t\t\t\t\tg.moveTo(-15, -3);\r\n\t\t\t\t\tg.lineTo(-15, 3);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.9, 1);\r\n\t\t\t\t\tg.lineTo(clockRadius * 0.9, -1);\r\n\t\t\t\t\tg.fillStyle = '#0f0';\r\n\t\t\t\t\tg.fill();\r\n\t\t\t\t\tg.restore();\r\n\r\n\t\t\t\t\tg.restore();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t]\r\n\t});\r\n\r\n\tvar node = new ht.Node();\r\n\tnode.setPosition(150, 150);\r\n\tnode.setSize(250, 250);\r\n\tnode.setImage('clock');\r\n\tnode.a('date', new Date());\r\n\tnode.s('image.stretch', 'centerUniform');\r\n\tdataModel.add(node);\r\n\r\n\tgraphView.setEditable(true);\r\n\t\r\n\tsetInterval(function(){\r\n\t\tnode.a('date', new Date());\r\n\t}, 1000);\r\n}\r\n<\/pre>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/posts\/363"}],"collection":[{"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/comments?post=363"}],"version-history":[{"count":5,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/posts\/363\/revisions"}],"predecessor-version":[{"id":372,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/posts\/363\/revisions\/372"}],"wp:attachment":[{"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/media?parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/categories?post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hightopo.com\/blog\/wp-json\/wp\/v2\/tags?post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}