{"id":18,"date":"2019-12-30T02:17:00","date_gmt":"2019-12-29T18:17:00","guid":{"rendered":"https:\/\/sth99.top\/?p=18"},"modified":"2023-03-17T01:08:14","modified_gmt":"2023-03-16T17:08:14","slug":"%e5%be%88%e4%b9%85%e4%b9%8b%e5%89%8d%e5%81%9a%e7%9a%843d%e8%b4%ba%e5%8d%a1","status":"publish","type":"post","link":"https:\/\/sth99.top\/index.php\/2019\/12\/30\/%e5%be%88%e4%b9%85%e4%b9%8b%e5%89%8d%e5%81%9a%e7%9a%843d%e8%b4%ba%e5%8d%a1\/","title":{"rendered":"\u5f88\u4e45\u4e4b\u524d\u505a\u76843D\u8d3a\u5361"},"content":{"rendered":"\n<style>\n  #renderCanvas {\n    width: 100%;\n    height: 100%;\n    touch-action: none;\n  }\n\n  #fps-counter {\n    margin: 0;\n    padding: 0;\n    color: gray;\n  }\n\n  #clock {\n    margin: 0;\n    padding: 0;\n    font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;\n    color: gray;\n  }\n\n  .button-holder {\n    text-align: right;\n    padding: 4px;\n  }\n\n  .button {\n    cursor: pointer;\n    display: inline-block;\n    padding: 4px 6px;\n    background-color: #1e1e1e;\n    color: gray;\n    border-radius: 3px;\n  }\n<\/style>\n\n\n\n\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-92db2b2a wp-block-group-is-layout-flex\">\n<p class=\"wp-block-paragraph\">\u5e27\u7387\uff1a<\/p>\n\n\n\n<span id=\"fps-counter\"><\/span>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-92db2b2a wp-block-group-is-layout-flex\">\n<p class=\"wp-block-paragraph\">\u65f6\u949f\uff0c\u539f\u6765\u80fd\u53e0\u52a0\u5728canvas\u4e0a\u8fb9\u7684\uff0c\u73b0\u5728\u4e0d\u77e5\u9053\u4e3a\u4ec0\u4e48\u8986\u76d6\u4e0d\u4e0a\u53bb\u4e86\u3002<\/p>\n\n\n\n<span id=\"clock\"><\/span>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-layout-constrained wp-block-group-is-layout-constrained\">\n<canvas id=\"renderCanvas\" style=\"width: 100%; min-height: 600px;\">\n<\/canvas>\n<div class=\"button-holder\">\n  <div id=\"refresh\" class=\"button\">\u5237\u65b0<\/div>\n  <div id=\"temp\" class=\"button\">\u5f00\u5173\u706f<\/div>\n<\/div>\n<script src=\"https:\/\/cdn.bootcss.com\/jquery\/3.3.1\/jquery.min.js\"><\/script>\n<!--<script src=\"https:\/\/cdn.bootcss.com\/babylonjs\/4.0.3\/babylon.js\"><\/script>-->\n<script src=\"https:\/\/cdn.bootcdn.net\/ajax\/libs\/babylonjs\/5.49.0\/babylon.js\"><\/script>\n<script>\n  var canvas;\n  var engine;\n  var scene;\n\n  var getTimeString = function () {\n    var _d22c = function (num) {\n      return num < 10 ? '0' + num : '' + num;\n    };\n    var date = new Date();\n    var display = _d22c(date.getHours()) + ':';\n    display += _d22c(date.getMinutes()) + (date.getSeconds() % 2 ? ' ' : ':');\n    display += _d22c(date.getSeconds());\n    return display;\n  };\n\n  var main = function () {\n    canvas = document.getElementById('renderCanvas');\n    var fps_counter = document.getElementById('fps-counter');\n    var clock = document.getElementById('clock');\n    engine = new BABYLON.Engine(canvas, true);\n    scene = createScene();\n\n    engine.runRenderLoop(function () {\n      scene.render();\n      fps_counter.innerText = engine.getFps();\n      clock.innerText = getTimeString();\n    });\n\n    window.addEventListener('resize', function () {\n      engine.resize();\n    });\n  };\n\n  var _cycle = function (second) {\n    var time = new Date().getTime() \/ 1000;\n    return time % second;\n  };\n\n  var createCamera = function () {\n    var camera = new BABYLON.ArcRotateCamera('camera', -Math.PI \/ 6, Math.PI \/ 3, 1300,\n      BABYLON.Vector3.Zero(), scene);\n    camera.minZ = 0;\n    camera.maxZ = 10000;\n    camera.wheelPrecision = 0.2;\n    camera.panningSensibility = 30;\n    camera.keysUp.push(87);\n    camera.keysDown.push(83);\n    camera.keysLeft.push(65);\n    camera.keysRight.push(68);\n    camera.lowerBetaLimit = Math.PI \/ 12;\n    camera.upperBetaLimit = Math.PI \/ 12 * 5;\n    camera.lowerAlphaLimit = -Math.PI \/ 12 * 5;\n    camera.upperAlphaLimit = Math.PI \/ 12 * 5;\n    return camera;\n  };\n  var createMaterials = function () {\n    var _createMaterial = function (name, tex_path) {\n      var mat = new BABYLON.StandardMaterial(name, scene);\n      var tex = new BABYLON.Texture(tex_path, scene);\n      mat.diffuseTexture = tex;\n      mat.diffuseTexture.hasAlpha = true;\n      mat.specularColor = BABYLON.Color3.Black();\n      mat.hasAlpha = true;\n      \/\/ mat.emissiveColor = BABYLON.Color3.White();\n      \/\/ mat.disableLighting = true;\n      return mat;\n    };\n\n    var pageL = _createMaterial('page l', 'https:\/\/bk-wpblog-1257439254.cos.ap-hongkong.myqcloud.com\/blog\/3d_card\/page_01.png');\n    var pageR = _createMaterial('page r', 'https:\/\/bk-wpblog-1257439254.cos.ap-hongkong.myqcloud.com\/blog\/3d_card\/page_02.png');\n    var sofa = _createMaterial('sofa', 'https:\/\/bk-wpblog-1257439254.cos.ap-hongkong.myqcloud.com\/blog\/3d_card\/sofa.png');\n    var cards = ['card1', 'card2', 'card3'].map(function (name) {\n      return _createMaterial(name, 'https:\/\/bk-wpblog-1257439254.cos.ap-hongkong.myqcloud.com\/blog\/3d_card\/' + name + '.png');\n    });\n\n    \/\/ pageL.zOffset = -5;\n    \/\/ cover.zOffset = -10;\n\n    return {\n      pageL: pageL,\n      pageR: pageR,\n      sofa: sofa,\n      cards: cards,\n    };\n  };\n  var createMeshes = function (mats) {\n    var pageW = 425;\n    var pageH = 595;\n\n    var pageL = BABYLON.MeshBuilder.CreatePlane('page l', {\n      width: pageW,\n      height: pageH,\n      sideOrientation: BABYLON.Mesh.DOUBLESIDE,\n      backUVs: new BABYLON.Vector4(0.5, 0, 0, 1),\n      frontUVs: new BABYLON.Vector4(0.5, 0, 1, 1)\n    }, scene);\n    pageL.rotate(BABYLON.Vector3.Right(), Math.PI \/ 2);\n    pageL.position.x -= pageW \/ 2;\n    pageL.bakeCurrentTransformIntoVertices();\n    pageL.material = mats.pageL;\n    pageL.rotationQuaternion = null;\n\n    var pageR = BABYLON.MeshBuilder.CreatePlane('page r', {\n      width: pageW,\n      height: pageH,\n      sideOrientation: BABYLON.Mesh.DOUBLESIDE,\n      backUVs: new BABYLON.Vector4(1, 0, 0.5, 1),\n      frontUVs: new BABYLON.Vector4(0, 0, 0.5, 1)\n    }, scene);\n    pageR.rotate(BABYLON.Vector3.Right(), Math.PI \/ 2);\n    pageR.position.x += pageW \/ 2;\n    pageR.bakeCurrentTransformIntoVertices();\n    pageR.material = mats.pageR;\n    pageR.rotationQuaternion = null;\n\n    var sofaW = 291;\n    var sofaX = 59;\n    var sofa = BABYLON.MeshBuilder.CreatePlane('page r', {\n      width: sofaW,\n      height: pageH,\n      sideOrientation: BABYLON.Mesh.DOUBLESIDE,\n    }, scene);\n    sofa.rotate(BABYLON.Vector3.Right(), Math.PI \/ 2);\n    sofa.position.x -= sofaW \/ 2;\n    sofa.bakeCurrentTransformIntoVertices();\n    sofa.position.x = sofaX;\n    sofa.material = mats.sofa;\n    sofa.rotationQuaternion = null;\n\n    var cardSizes = [{\n      w: 1800,\n      h: 1800\n    }, {\n      w: 1400,\n      h: 1400\n    }, {\n      w: 1200,\n      h: 1800\n    }];\n    var scale = 0.2;\n    var cards = mats.cards.map(function (cardMat, index) {\n      cardMat.opacityTexture = cardMat.diffuseTexture;\n      var size = cardSizes[index];\n      var w = size.w * scale,\n        h = size.h * scale;\n      var card = BABYLON.MeshBuilder.CreatePlane('card ' + index, {\n        width: w,\n        height: h,\n        sideOrientation: BABYLON.Mesh.DOUBLESIDE,\n      }, scene);\n      card.rotate(BABYLON.Vector3.Up(), Math.PI \/ 2);\n      card.position.y += h \/ 2;\n      card.bakeCurrentTransformIntoVertices();\n      card.position.x = sofaX * 1.5;\n      card.rotationQuaternion = null;\n      card.material = cardMat;\n      card.visibility = 0;\n      return card;\n    });\n\n    return {\n      pageL: pageL,\n      pageR: pageR,\n      sofa: sofa,\n      cards: cards,\n    };\n  };\n\n  var createShadows = function (light, meshes) {\n    var sg = new BABYLON.ShadowGenerator(1024, light);\n    sg.setTransparencyShadow(true);\n    sg.addShadowCaster(meshes.sofa);\n    sg.setDarkness(0.5);\n    sg.useBlurExponentialShadowMap = true;\n\n    meshes.pageL.receiveShadows = true;\n    meshes.pageR.receiveShadows = true;\n\n    return sg;\n  };\n\n  var switchLight;\n  var createScene = function () {\n    var scene = new BABYLON.Scene(engine);\n    scene.clearColor = new BABYLON.Color3(0, 0, 0);\n\n    var camera = createCamera();\n    camera.attachControl(canvas, false);\n\n    var light = new BABYLON.DirectionalLight('light', new BABYLON.Vector3(-1, -1, -0.5), scene);\n    light.position = new BABYLON.Vector3(1000, 1000, 1000);\n    light.intensity = 1;\n    var pointLight = new BABYLON.PointLight('point light', BABYLON.Vector3.Zero(), scene);\n    pointLight.diffuse = new BABYLON.Color3(1, 0.5, 0);\n    pointLight.intensity = 0;\n    pointLight.range = 500;\n\n    var box = BABYLON.MeshBuilder.CreateBox('', {\n      size: 50\n    }, scene);\n    box.position.copyFrom(light.position);\n\n    var materials = createMaterials();\n    var meshes = createMeshes(materials);\n    var shadowGenerator = createShadows(light, meshes);\n\n    var updateCardAngle = function (angle) {\n      meshes.pageL.rotation.z = angle;\n      meshes.sofa.rotation.z = angle;\n      meshes.cards.forEach(function (m) {\n        m.rotation.z = angle + Math.PI \/ 2;\n      });\n      pointLight.position = new BABYLON.Vector3(200 - 175 * Math.cos(-angle), 175 * Math.sin(-angle), 225);\n      \/\/ box.position.copyFrom(pointLight.position);\n    };\n    var animateCards = function (cards) {\n      var _limitMinMax = function (min, max, value) {\n        return value < min ? min : value;\n      };\n      var bc = 12;\n      var bt = _cycle(bc);\n      var c = bc \/ cards.length;\n      var t = bt % c;\n      var i = parseInt(bt \/ c);\n\n      cards.forEach(function (c) {\n        c.visibility = 0;\n      });\n      var v = 1 - _limitMinMax(0, 1, Math.abs(t - c \/ 2) - (c \/ 2 - 1));\n      cards[i].visibility = v;\n      cards[i].position.y = 50 - 50 * Math.cos((v - 1) * Math.PI \/ 2);\n    };\n\n    scene.onBeforeRenderObservable.add(function (ev, evState) {\n      var angle = -Math.PI \/ 3 + 0.1 * Math.cos(_cycle(2) * Math.PI);\n      updateCardAngle(angle);\n      animateCards(meshes.cards);\n    });\n\n    switchLight = function () {\n      if (light.intensity == 0.2) {\n        \/\/\u65e5\n        light.intensity = 1;\n        pointLight.intensity = 0;\n        shadowGenerator.setDarkness(0.5);\n      } else {\n        \/\/\u591c\n        light.intensity = 0.2;\n        pointLight.intensity = 1;\n        shadowGenerator.setDarkness(0.8);\n      }\n    };\n\n    return scene;\n  };\n\n  window.addEventListener('DOMContentLoaded', function () {\n    main();\n    $('#refresh').click(function (e) {\n      e.preventDefault();\n      window.location.reload();\n    });\n    $('#temp').click(function (e) {\n      e.preventDefault();\n      switchLight();\n    });\n    canvas.oncontextmenu = function (e) {\n      e.preventDefault();\n    };\n  });\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u5e27\u7387\uff1a \u65f6\u949f\uff0c\u539f\u6765\u80fd\u53e0\u52a0\u5728canvas\u4e0a\u8fb9\u7684\uff0c\u73b0\u5728\u4e0d\u77e5\u9053\u4e3a\u4ec0\u4e48\u8986\u76d6\u4e0d\u4e0a\u53bb\u4e86\u3002 \u5237\u65b0 \u5f00\u5173\u706f<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","jetpack_post_was_ever_published":false,"footnotes":""},"categories":[1],"tags":[4],"class_list":["post-18","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-webgl"],"blocksy_meta":"","jetpack_featured_media_url":"","uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"STH99","author_link":"https:\/\/sth99.top\/index.php\/author\/sth99_admin\/"},"uagb_comment_info":1,"uagb_excerpt":"\u5e27\u7387\uff1a \u65f6\u949f\uff0c\u539f\u6765\u80fd\u53e0\u52a0\u5728canvas\u4e0a\u8fb9\u7684\uff0c\u73b0\u5728\u4e0d\u77e5\u9053\u4e3a\u4ec0\u4e48\u8986\u76d6\u4e0d\u4e0a\u53bb\u4e86\u3002 \u5237\u65b0 \u5f00\u5173\u706f","_links":{"self":[{"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/posts\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":3,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"predecessor-version":[{"id":905,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/posts\/18\/revisions\/905"}],"wp:attachment":[{"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sth99.top\/index.php\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}