{"id":84,"date":"2026-06-29T14:16:28","date_gmt":"2026-06-29T06:16:28","guid":{"rendered":"https:\/\/liubai.wuxiangsoft.com\/?page_id=84"},"modified":"2026-06-29T14:31:22","modified_gmt":"2026-06-29T06:31:22","slug":"solartourch","status":"publish","type":"page","link":"https:\/\/liubai.wuxiangsoft.com\/?page_id=84","title":{"rendered":"\u592a\u9633\u80fd\u7535\u7b52"},"content":{"rendered":"\n<link href=\"https:\/\/fonts.googleapis.com\/icon?family=Material+Icons\" rel=\"stylesheet\">\n\n<div class=\"solar-torch-widget\">\n  <button type=\"button\" class=\"solar-torch-btn solar-off\" onclick=\"solarTorchToggle(this)\">\n    <i class=\"mdui-icon material-icons\">power_settings_new<\/i>\n  <\/button>\n<\/div>\n\n<style>\n.solar-torch-widget,\n.solar-torch-widget * {\n  box-sizing: border-box;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Microsoft YaHei\", Arial !important;\n}\n\n.solar-torch-widget {\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  padding: 34px 16px;\n  -webkit-text-size-adjust: 100%;\n  text-size-adjust: 100%;\n}\n\n.solar-torch-btn {\n  width: 96px;\n  height: 96px;\n  border: none;\n  border-radius: 50%;\n  color: #fff;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  -webkit-appearance: none;\n  appearance: none;\n  transition: transform 0.15s ease, background 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;\n}\n\n.solar-torch-btn i {\n  font-family: \"Material Icons\" !important;\n  font-size: 46px;\n  font-weight: normal;\n  font-style: normal;\n  line-height: 1;\n  letter-spacing: normal;\n  text-transform: none;\n  display: inline-block;\n  white-space: nowrap;\n  direction: ltr;\n  -webkit-font-feature-settings: \"liga\";\n  -webkit-font-smoothing: antialiased;\n}\n\n.solar-torch-btn.solar-off {\n  background: #2ecc71;\n  box-shadow: 0 12px 26px rgba(46, 204, 113, 0.3);\n}\n\n.solar-torch-btn.solar-on {\n  background: #e53935;\n  box-shadow: 0 12px 26px rgba(229, 57, 53, 0.26);\n}\n\n.solar-torch-btn.solar-night {\n  background: #9e9e9e;\n  color: #eeeeee;\n  cursor: pointer;\n  opacity: 0.75;\n  box-shadow: none;\n}\n\n.solar-torch-btn:active {\n  transform: scale(0.95);\n}\n<\/style>\n\n<script>\n(function () {\n  window.solarTorchData = window.solarTorchData || new WeakMap();\n\n  function rad(d) {\n    return d * Math.PI \/ 180;\n  }\n\n  function deg(r) {\n    return r * 180 \/ Math.PI;\n  }\n\n  function getDayOfYear(date) {\n    var start = new Date(date.getFullYear(), 0, 0);\n    return Math.floor((date - start) \/ 86400000);\n  }\n\n  function normalizeDegree(value) {\n    value = value % 360;\n    return value < 0 ? value + 360 : value;\n  }\n\n  function normalizeHour(value) {\n    value = value % 24;\n    return value < 0 ? value + 24 : value;\n  }\n\n  function getSunTime(date, latitude, longitude, sunrise) {\n    var zenith = 90.833;\n    var N = getDayOfYear(date);\n    var lngHour = longitude \/ 15;\n\n    var t = sunrise\n      ? N + ((6 - lngHour) \/ 24)\n      : N + ((18 - lngHour) \/ 24);\n\n    var M = (0.9856 * t) - 3.289;\n\n    var L = M +\n      (1.916 * Math.sin(rad(M))) +\n      (0.020 * Math.sin(rad(2 * M))) +\n      282.634;\n\n    L = normalizeDegree(L);\n\n    var RA = deg(Math.atan(0.91764 * Math.tan(rad(L))));\n    RA = normalizeDegree(RA);\n\n    var Lquadrant = Math.floor(L \/ 90) * 90;\n    var RAquadrant = Math.floor(RA \/ 90) * 90;\n    RA = RA + (Lquadrant - RAquadrant);\n    RA = RA \/ 15;\n\n    var sinDec = 0.39782 * Math.sin(rad(L));\n    var cosDec = Math.cos(Math.asin(sinDec));\n\n    var cosH =\n      (Math.cos(rad(zenith)) - (sinDec * Math.sin(rad(latitude)))) \/\n      (cosDec * Math.cos(rad(latitude)));\n\n    if (cosH > 1 || cosH < -1) {\n      return null;\n    }\n\n    var H = sunrise\n      ? 360 - deg(Math.acos(cosH))\n      : deg(Math.acos(cosH));\n\n    H = H \/ 15;\n\n    var T = H + RA - (0.06571 * t) - 6.622;\n    var UT = normalizeHour(T - lngHour);\n\n    var timezoneOffset = -date.getTimezoneOffset() \/ 60;\n    var localHour = normalizeHour(UT + timezoneOffset);\n\n    var hour = Math.floor(localHour);\n    var minute = Math.floor((localHour - hour) * 60);\n    var second = Math.floor((((localHour - hour) * 60) - minute) * 60);\n\n    return new Date(\n      date.getFullYear(),\n      date.getMonth(),\n      date.getDate(),\n      hour,\n      minute,\n      second\n    );\n  }\n\n  function getSunTimes(latitude, longitude) {\n    var now = new Date();\n    return {\n      sunrise: getSunTime(now, latitude, longitude, true),\n      sunset: getSunTime(now, latitude, longitude, false)\n    };\n  }\n\n  function isDaytime(latitude, longitude) {\n    var now = new Date();\n    var times = getSunTimes(latitude, longitude);\n\n    if (!times.sunrise || !times.sunset) {\n      return true;\n    }\n\n    return now >= times.sunrise && now < times.sunset;\n  }\n\n  function setButtonState(btn, state) {\n    btn.classList.remove(\"solar-on\", \"solar-off\", \"solar-night\");\n\n    if (state === \"on\") {\n      btn.classList.add(\"solar-on\");\n    } else if (state === \"night\") {\n      btn.classList.add(\"solar-night\");\n    } else {\n      btn.classList.add(\"solar-off\");\n    }\n  }\n\n  function initTorch(root) {\n    if (window.solarTorchData.has(root)) return;\n\n    var data = {\n      latitude: 39.9042,\n      longitude: 116.4074,\n      isOn: false,\n      stream: null,\n      track: null\n    };\n\n    window.solarTorchData.set(root, data);\n\n    if (navigator.geolocation) {\n      navigator.geolocation.getCurrentPosition(\n        function (pos) {\n          data.latitude = pos.coords.latitude;\n          data.longitude = pos.coords.longitude;\n          window.solarTorchData.set(root, data);\n          refreshTorchState(root);\n        },\n        function () {\n          refreshTorchState(root);\n        },\n        {\n          enableHighAccuracy: false,\n          timeout: 5000,\n          maximumAge: 21600000\n        }\n      );\n    }\n\n    refreshTorchState(root);\n\n    setInterval(function () {\n      refreshTorchState(root);\n    }, 60000);\n  }\n\n  function refreshTorchState(root) {\n    var btn = root.querySelector(\".solar-torch-btn\");\n    var data = window.solarTorchData.get(root);\n    if (!btn || !data) return;\n\n    if (!isDaytime(data.latitude, data.longitude)) {\n      stopTorch(root);\n      setButtonState(btn, \"night\");\n      return;\n    }\n\n    if (data.isOn) {\n      setButtonState(btn, \"on\");\n    } else {\n      setButtonState(btn, \"off\");\n    }\n  }\n\n  function stopTorch(root) {\n    var data = window.solarTorchData.get(root);\n    if (!data) return;\n\n    if (data.track) {\n      try {\n        data.track.applyConstraints({ advanced: [{ torch: false }] });\n      } catch (e) {}\n\n      try {\n        data.track.stop();\n      } catch (e) {}\n    }\n\n    if (data.stream) {\n      try {\n        data.stream.getTracks().forEach(function (track) {\n          track.stop();\n        });\n      } catch (e) {}\n    }\n\n    data.isOn = false;\n    data.stream = null;\n    data.track = null;\n\n    window.solarTorchData.set(root, data);\n  }\n\n  window.solarTorchToggle = async function (button) {\n    var root = button.closest(\".solar-torch-widget\");\n    if (!root) return;\n\n    initTorch(root);\n\n    var data = window.solarTorchData.get(root);\n    if (!data) return;\n\n    if (!isDaytime(data.latitude, data.longitude)) {\n      setButtonState(button, \"night\");\n      alert(\"\u8bf7\u5728\u65e5\u95f4\u4f7f\u7528\u6b64\u7535\u7b52\u3002\");\n      return;\n    }\n\n    if (data.isOn) {\n      stopTorch(root);\n      setButtonState(button, \"off\");\n      return;\n    }\n\n    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {\n      alert(\"\u5f53\u524d\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u8c03\u7528\u624b\u673a\u95ea\u5149\u706f\u3002\");\n      return;\n    }\n\n    try {\n      var stream = await navigator.mediaDevices.getUserMedia({\n        video: {\n          facingMode: { ideal: \"environment\" }\n        },\n        audio: false\n      });\n\n      var track = stream.getVideoTracks()[0];\n\n      if (!track) {\n        alert(\"\u6ca1\u6709\u627e\u5230\u53ef\u7528\u7684\u540e\u7f6e\u6444\u50cf\u5934\u3002\");\n        return;\n      }\n\n      var capabilities = track.getCapabilities ? track.getCapabilities() : {};\n\n      if (!capabilities.torch) {\n        stream.getTracks().forEach(function (t) {\n          t.stop();\n        });\n\n        alert(\"\u5f53\u524d\u8bbe\u5907\u6216\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u7f51\u9875\u8c03\u7528\u95ea\u5149\u706f\u3002\");\n        return;\n      }\n\n      await track.applyConstraints({\n        advanced: [{ torch: true }]\n      });\n\n      data.isOn = true;\n      data.stream = stream;\n      data.track = track;\n\n      window.solarTorchData.set(root, data);\n\n      setButtonState(button, \"on\");\n    } catch (e) {\n      setButtonState(button, \"off\");\n      alert(\"\u65e0\u6cd5\u5f00\u542f\u95ea\u5149\u706f\uff0c\u8bf7\u68c0\u67e5\u6444\u50cf\u5934\u6743\u9650\u3001\u6d4f\u89c8\u5668\u652f\u6301\u6216 HTTPS \u9875\u9762\u3002\");\n    }\n  };\n\n  document.querySelectorAll(\".solar-torch-widget\").forEach(function (root) {\n    initTorch(root);\n  });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>power_settings_new<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-84","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/pages\/84","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=84"}],"version-history":[{"count":6,"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/pages\/84\/revisions"}],"predecessor-version":[{"id":91,"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=\/wp\/v2\/pages\/84\/revisions\/91"}],"wp:attachment":[{"href":"https:\/\/liubai.wuxiangsoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=84"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}