首页
闲言碎语
雁过留名
友链申请
Search
1
国外短信接码服务平台
9,705 阅读
2
Beyond Compare 4 序列号“这个授权密钥已被吊销”的解决办法
9,130 阅读
3
收藏几个Github镜像源
7,664 阅读
4
Handsome主题夜间模式插件 fo Typecho
7,502 阅读
5
美剧鸟v5.6.3(官方原版)
7,194 阅读
随笔吐槽
福利活动
技术教程
软件下载
源码分享
私密相册
登录
/
注册
Search
标签搜索
安卓软件
影音播放
影音视频
电视软件
电视盒子
Typecho
游戏加速
听书软件
影视播放
Handsome
音乐试听
影音视听
音乐播放
文件管理
输入法皮肤
解锁音乐
实用工具
学习阅读
GitHub
多开软件
低调G
累计撰写
291
篇文章
累计收到
701
条评论
首页
栏目
随笔吐槽
福利活动
技术教程
软件下载
源码分享
私密相册
页面
闲言碎语
雁过留名
友链申请
搜索到
291
篇与
低调G
的结果
2020-06-20
南瓜影视v1.3.7.2PJ会员版
软件名称:南瓜影视软件版本:v1.3.7.2_破解_会员_完美版软件大小:35M此版本由大神[蔡小木]完美破解,直接安装就是会员版,亲测,完美,流畅,你值得拥有。©下载资源版权归作者所有;本站所有资源均来源于网络,仅供学习使用,请支持正版!
2020年06月20日
1,283 阅读
0 评论
0 点赞
2020-06-19
橙色直播v3.2.3清爽版
软件名称:橙色直播软件版本:v3.2.3_清爽版软件语言:中文软件大小:8.53M此款神器由吾爱大神[狂暴亚丝娜]原创开发,绝对好用,欢迎各位下载体验。©下载资源版权归作者所有;本站所有资源均来源于网络,仅供学习使用,请支持正版!
2020年06月19日
2,063 阅读
0 评论
0 点赞
2020-06-18
镜像反代任何网站Workers-Proxy
介绍Workers-Proxy 是基于 Cloudflare Workers 的轻量级 Javascript 反向代理.用户无需购买主机并配置 Web 服务器 (例如 Nginx 或 Apache) 即可在 Cloudflare 的全球网络上部署反向代理.功能搭建网站镜像 通过 Cloudflare 的全球网络加速前端资源访问 增加安全性, 隐藏网站的真实 IP 地址 屏蔽特定地区或 IP 地址 将移动设备用户转发到不同网站配置教程安装和部署使用 Wrangler 部署1.安装 Wrangler. 2.创建一个新的项目.wrangler generate my-workers-proxy https://github.com/Berkeley-Reject/Workers-Proxy3.配置该项目的 wrangler.toml 文件来准备部署你的项目.wrangler config4.构建并部署于 Cloudflare Workers.wrangler buildwrangler publish手动部署1.转到 Cloudflare Workers, 注册或登录 Cloudflare 账号, 为 Workers 设置子域名, 创建新的 Worker. 2.自定义 'src/index.js', 将代码复制到在线编辑器中, 替换默认代码. 3.更改 Worker 名称, 保存代码并部署, 测试反向代理是否符合需求.绑定自定义域名1.检查域名是否接入 Cloudflare. 2.跳转到域名的控制面板, 选择 'Workers' 页面, 点击 'Add Route'. 3.在 Route 中输入 https://<自定义域名>/* 并且选择刚创建的 Worker. 4.为自定义域名添加 CNAME DNS 记录. 在 DNS 页面中, 在 'Name' 区域输入自定义域名的子域名 (或者 @), 在 'Target' 区域输入 Worker 的二级域名 (例如 test.workers.dev), 将代理状态选择为 '代理'.自定义 index.js在 'index.js' 文件顶部有一些常量.为了自定义 Workers-Proxy 反向代理, 请根据需求编辑这些常量.// 代理网站 const upstream = 'www.google.com' // 代理网站的目录 const upstream_path = '/' // 手机用户代理网站 const upstream_mobile = 'www.google.com' // 屏蔽国家和地区 const blocked_region = ['CN', 'KP', 'SY', 'PK', 'CU'] // 屏蔽 IP 地址 const blocked_ip_address = ['0.0.0.0', '127.0.0.1'] // 源站是否开启 HTTPS const https = true // 是否允许浏览器缓存 const disable_cache = false // 文本替换 const replace_dict = { '$upstream': '$custom_domain', '//google.com': '' }配置模板GoogleGoogle ScholarsGitHubWikipediaWikipedia (Chinese)The New York TimesPornhub部署多个域名如果被反代的网站使用其他域名的静态资源时, 可以部署多个 Workers-Proxy 并配置文本替换.www.google.com 使用位于 www.gstatic.com 的静态资源 部署 Workers-Proxy A, 用于代理 www.gstatic.com 部署 Workers-Proxy B, 用于代理 www.google.com 配置 Workers-Proxy B 的文本替换:const replace_dict = { '$upstream': '$custom_domain', 'www.gstatic.com': '<Workers-Proxy A 的域名>' }index.js代码// Website you intended to retrieve for users. const upstream = 'www.google.com' // Custom pathname for the upstream website. const upstream_path = '/' // Website you intended to retrieve for users using mobile devices. const upstream_mobile = 'www.google.com' // Countries and regions where you wish to suspend your service. const blocked_region = ['CN', 'KP', 'SY', 'PK', 'CU'] // IP addresses which you wish to block from using your service. const blocked_ip_address = ['0.0.0.0', '127.0.0.1'] // Whether to use HTTPS protocol for upstream address. const https = true // Whether to disable cache. const disable_cache = false // Replace texts. const replace_dict = { '$upstream': '$custom_domain', '//google.com': '' } addEventListener('fetch', event => { event.respondWith(fetchAndApply(event.request)); }) async function fetchAndApply(request) { const region = request.headers.get('cf-ipcountry').toUpperCase(); const ip_address = request.headers.get('cf-connecting-ip'); const user_agent = request.headers.get('user-agent'); let response = null; let url = new URL(request.url); let url_hostname = url.hostname; if (https == true) { url.protocol = 'https:'; } else { url.protocol = 'http:'; } if (await device_status(user_agent)) { var upstream_domain = upstream; } else { var upstream_domain = upstream_mobile; } url.host = upstream_domain; if (url.pathname == '/') { url.pathname = upstream_path; } else { url.pathname = upstream_path + url.pathname; } if (blocked_region.includes(region)) { response = new Response('Access denied: WorkersProxy is not available in your region yet.', { status: 403 }); } else if (blocked_ip_address.includes(ip_address)) { response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', { status: 403 }); } else { let method = request.method; let request_headers = request.headers; let new_request_headers = new Headers(request_headers); new_request_headers.set('Host', upstream_domain); new_request_headers.set('Referer', url.protocol + '//' + url_hostname); let original_response = await fetch(url.href, { method: method, headers: new_request_headers }) connection_upgrade = new_request_headers.get("Upgrade"); if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") { return original_response; } let original_response_clone = original_response.clone(); let original_text = null; let response_headers = original_response.headers; let new_response_headers = new Headers(response_headers); let status = original_response.status; if (disable_cache) { new_response_headers.set('Cache-Control', 'no-store'); } new_response_headers.set('access-control-allow-origin', '*'); new_response_headers.set('access-control-allow-credentials', true); new_response_headers.delete('content-security-policy'); new_response_headers.delete('content-security-policy-report-only'); new_response_headers.delete('clear-site-data'); if (new_response_headers.get("x-pjax-url")) { new_response_headers.set("x-pjax-url", response_headers.get("x-pjax-url").replace("//" + upstream_domain, "//" + url_hostname)); } const content_type = new_response_headers.get('content-type'); if (content_type != null && content_type.includes('text/html') && content_type.includes('UTF-8')) { original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname); } else { original_text = original_response_clone.body } response = new Response(original_text, { status, headers: new_response_headers }) } return response; } async function replace_response_text(response, upstream_domain, host_name) { let text = await response.text() var i, j; for (i in replace_dict) { j = replace_dict[i] if (i == '$upstream') { i = upstream_domain } else if (i == '$custom_domain') { i = host_name } if (j == '$upstream') { j = upstream_domain } else if (j == '$custom_domain') { j = host_name } let re = new RegExp(i, 'g') text = text.replace(re, j); } return text; } async function device_status(user_agent_info) { var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; var flag = true; for (var v = 0; v < agents.length; v++) { if (user_agent_info.indexOf(agents[v]) > 0) { flag = false; break; } } return flag; }
2020年06月18日
4,192 阅读
2 评论
0 点赞
2020-06-16
博客日志配图网站推荐
写博客的时候大家避免不了要用到日志配图,下面我为大家分享一些配图用得到的网站。Pexels优势:搜索功能强大,匹配度高,可以选择尺寸下载,图片质量高,原图分辨率高。劣势:图片种类没有Pixabay多。Pixabay优势:图片种类多,扁平风,摄影都有,可以选择尺寸下载。劣势:搜索功能鸡肋,图片质量一般,需要有一定筛选能力。Unsplash优势:图片质量高劣势:图片种类少,基本都是摄影图片,搜索出来的东西很多不沾边,无法选择尺寸下载需要自己压缩裁剪。可爱图片国内唯美小清新文艺图片壁纸的网站。
2020年06月16日
1,834 阅读
1 评论
0 点赞
2020-06-16
Typecho常用统计代码
一些常用统计<?php Typecho_Widget::widget('Widget_Stat')->to($stat); ?> 文章总数:<?php $stat->publishedPostsNum() ?> 篇 分类总数:<?php $stat->categoriesNum() ?> 个 评论总数:<?php $stat->publishedCommentsNum() ?> 条 页面总数:<?php $stat->publishedPagesNum() ?> 个 当前作者的文章总数:<?php $stat->myPublishedPostsNum() ?> 篇程序自带的统计函数详细参数 说明 代码 获取已发布的文章数目 publishedPostsNum 获取待审核的文章数目 waitingPostsNum 获取草稿文章数目 draftPostsNum 获取当前用户已发布的文章数目 myPublishedPostsNum 获取当前用户待审核文章数目 myWaitingPostsNum 获取当前用户草稿文章数目 myDraftPostsNum 获取当前用户已发布的文章数目 currentPublishedPostsNum 获取当前用户待审核文章数目 currentWaitingPostsNum 获取当前用户草稿文章数目 currentDraftPostsNum 获取已发布页面数目 publishedPagesNum 获取草稿页面数目 draftPagesNum 获取当前显示的评论数目 publishedCommentsNum 获取当前待审核的评论数目 waitingCommentsNum 获取当前垃圾评论数目 spamCommentsNum 获取当前用户显示的评论数目 myPublishedCommentsNum 获取当前用户显示的评论数目 myWaitingCommentsNum 获取当前用户显示的评论数目 mySpamCommentsNum 获取当前文章的评论数目 currentCommentsNum 获取当前文章显示的评论数目 currentPublishedCommentsNum 获取当前文章显示的评论数目 currentWaitingCommentsNum 获取当前文章显示的评论数目 currentSpamCommentsNum 获取分类数目 categoriesNum 该统计函数来自源码typecho/var/Widget/Stat.php <span><?php _me("页面") ?></span> <?php Typecho_Widget::widget('Widget_Stat')->to($stat); ?> <span class="badge bg-default pull-right"> <?php $stat->publishedPagesNum() ?><!--页面总数--> </span
2020年06月16日
1,471 阅读
0 评论
0 点赞
2020-06-15
Typecho新版又拍云插件UpyunFile
说明本插件[button color="black" icon="" url="https://github.com/ShadowySpirits/UpyunFile" type="round"]UpyunFile [/button]是又拍云文件上传插件,基于 codesee/UpyunFile 二次开发。相比于原插件:修复了启用本插件会影响其他替换内容插件生效的 Bug修复了某些情况下图片链接替换失败的 Bug新增:接入又拍云图片处理功能新增:为博客静态资源加入 Token 防盗链又拍云 SDK 仅支持 PHP >= 5.6 的环境使用方法在 Release 中下载此插件的最新版,上传至网站的 /usr/plugins/ 目录下。务必保持本插件文件夹名称为 UpyunFile,不能随意更改启用该插件,正确填写相关信息,保存即可注意事项启用又拍云图片处理需在又拍云控制台中创建缩略图版本并填入插件相应位置,文档:https://help.upyun.com/knowledge-base/image/#thumb;又拍云图片处理会忽略带有后缀 _nothumb 的图片(比如:example_nothumb.png)如你创建的缩略图版本开启了转码功能,则需将输出格式填入插件相应位置只有 JPG、JPEG、PNG、BMP 这 4 种格式的图片才会进行处理启用 Token 防盗链需在又拍云控制台中启用 Token 防盗链并将密钥填入插件相应位置自定义目录结构可以在 Typecho 根目录下的 config.inc.php 中添加代码 define('__TYPECHO_UPLOAD_DIR__', '/path/to/uploads'); 并设置目录结构为 Typecho结构。Token 防盗链功能只能修改 HTML 代码中的 CDN 链接,如果需要引入字体图片等资源请内联 CSS*更新记录:v0.9.0:升级 SDK,修复 Bug,加入新功能v1.0.0:控制台的文件管理中现在可以正常查看有 Token 防盗链保护的图片又拍云图片处理会忽略带有后缀 _nothumb 的图片(比如:example_nothumb.png)优化代码v1.0.2:修复某些情况下重复添加 Token 的 bugv1.0.3:优化代码增强兼容性v1.0.4:解决兼容性问题如果你有使用上的问题请在提问时写清楚你的 php 和 typecho 版本以及报错信息,否则一律不予回复[button color="success" icon="glyphicon glyphicon-link" url="https://blog.sspirits.top/archives/new-version-of-UpyunFile-plugin-use-tutorial" type=""]作者:SSpiritsの秘密基地[/button]
2020年06月15日
1,800 阅读
0 评论
0 点赞
2020-06-13
将Chrome离线小恐龙嵌入博客
前言最近我逛各位大佬的博客时,看到了将chrome的离线游戏嵌入博客,就觉得比较有意思,想抄过来,发现原博客的实现方法和源代码实在粗糙,于是我在github上找到了源码,将其进一步更方便嵌入博客,现在讲讲步骤。试玩正文仅需一个JS文件即可runner.js代码如下!function (A, i) { "object" == typeof exports && "object" == typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define([], i) : "object" == typeof exports ? exports.initRunner = i() : A.initRunner = i() }(this, function () { return function (A) { function i(s) { if (t[s]) return t[s].exports; var e = t[s] = {exports: {}, id: s, loaded: !1}; return A[s].call(e.exports, e, e.exports, i), e.loaded = !0, e.exports } var t = {}; return i.m = A, i.c = t, i.p = "", i(0) }([function (A, i, t) { document.body.insertAdjacentHTML("beforeend", t(3)), t(5); const s = t(6); A.exports = function (A, i) { var t = "string" == typeof A ? document.querySelector(A) : A; return t.classList.add("interstitial-wrapper"), new s(t, i) } }, function (A, i, t) { i = A.exports = t(2)(), i.push([A.id, ".interstitial-wrapper{box-sizing:border-box;margin:0 auto;max-width:600px}.runner-container{width:44px}.runner-canvas,.runner-container{height:150px;max-width:600px;overflow:hidden}.runner-canvas{opacity:1;position:relative;z-index:2}.inverted{transition:-webkit-filter 1.5s cubic-bezier(.65,.05,.36,1),background-color 1.5s cubic-bezier(.65,.05,.36,1);will-change:-webkit-filter,background-color;-webkit-filter:invert(100%);background-color:#000}.controller{background:hsla(0,0%,97%,.1);height:100vh;left:0;position:absolute;top:0;width:100vw;z-index:1}#offline-resources{display:none}", ""]) }, function (A, i) { A.exports = function () { var A = []; return A.toString = function () { for (var A = [], i = 0; i < this.length; i++) { var t = this[i]; t[2] ? A.push("@media " + t[2] + "{" + t[1] + "}") : A.push(t[1]) } return A.join("") }, A.i = function (i, t) { "string" == typeof i && (i = [[null, i, ""]]); for (var s = {}, e = 0; e < this.length; e++) { var n = this[e][0]; "number" == typeof n && (s[n] = !0) } for (e = 0; e < i.length; e++) { var o = i[e]; "number" == typeof o[0] && s[o[0]] || (t && !o[2] ? o[2] = t : t && (o[2] = "(" + o[2] + ") and (" + t + ")"), A.push(o)) } }, A } }, function (A, i) { A.exports = '<div id=offline-resources> <img id=offline-resources-1x src="data:image/png;base64,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"> <img id=offline-resources-2x src="data:image/png;base64,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"> <template id=audio-resources> <audio id=offline-sound-press src=data:audio/mpeg;base64,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></audio> <audio id=offline-sound-hit src=data:audio/mpeg;base64,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 i18n-processed=""></audio> <audio id=offline-sound-reached src="data:audio/mpeg;base64,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"></audio> </template> </div>'; }, function (A, i, t) { function s(A, i) { for (var t = 0; t < A.length; t++) { var s = A[t], e = I[s.id]; if (e) { e.refs++; for (var n = 0; n < e.parts.length; n++) e.parts[n](s.parts[n]); for (; n < s.parts.length; n++) e.parts.push(r(s.parts[n], i)) } else { for (var o = [], n = 0; n < s.parts.length; n++) o.push(r(s.parts[n], i)); I[s.id] = {id: s.id, refs: 1, parts: o} } } } function e(A) { for (var i = [], t = {}, s = 0; s < A.length; s++) { var e = A[s], n = e[0], o = e[1], h = e[2], a = e[3], r = {css: o, media: h, sourceMap: a}; t[n] ? t[n].parts.push(r) : i.push(t[n] = {id: n, parts: [r]}) } return i } function n(A, i) { var t = l(), s = m[m.length - 1]; if ("top" === A.insertAt) s ? s.nextSibling ? t.insertBefore(i, s.nextSibling) : t.appendChild(i) : t.insertBefore(i, t.firstChild), m.push(i); else { if ("bottom" !== A.insertAt) throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'."); t.appendChild(i) } } function o(A) { A.parentNode.removeChild(A); var i = m.indexOf(A); i >= 0 && m.splice(i, 1) } function h(A) { var i = document.createElement("style"); return i.type = "text/css", n(A, i), i } function a(A) { var i = document.createElement("link"); return i.rel = "stylesheet", n(A, i), i } function r(A, i) { var t, s, e; if (i.singleton) { var n = p++; t = C || (C = h(i)), s = c.bind(null, t, n, !1), e = c.bind(null, t, n, !0) } else A.sourceMap && "function" == typeof URL && "function" == typeof URL.createObjectURL && "function" == typeof URL.revokeObjectURL && "function" == typeof Blob && "function" == typeof btoa ? (t = a(i), s = d.bind(null, t), e = function () { o(t), t.href && URL.revokeObjectURL(t.href) }) : (t = h(i), s = g.bind(null, t), e = function () { o(t) }); return s(A), function (i) { if (i) { if (i.css === A.css && i.media === A.media && i.sourceMap === A.sourceMap) return; s(A = i) } else e() } } function c(A, i, t, s) { var e = t ? "" : s.css; if (A.styleSheet) A.styleSheet.cssText = f(i, e); else { var n = document.createTextNode(e), o = A.childNodes; o[i] && A.removeChild(o[i]), o.length ? A.insertBefore(n, o[i]) : A.appendChild(n) } } function g(A, i) { var t = i.css, s = i.media; if (s && A.setAttribute("media", s), A.styleSheet) A.styleSheet.cssText = t; else { for (; A.firstChild;) A.removeChild(A.firstChild); A.appendChild(document.createTextNode(t)) } } function d(A, i) { var t = i.css, s = i.sourceMap; s && (t += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(s)))) + " */"); var e = new Blob([t], {type: "text/css"}), n = A.href; A.href = URL.createObjectURL(e), n && URL.revokeObjectURL(n) } var I = {}, E = function (A) { var i; return function () { return "undefined" == typeof i && (i = A.apply(this, arguments)), i } }, u = E(function () { return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase()) }), l = E(function () { return document.head || document.getElementsByTagName("head")[0] }), C = null, p = 0, m = []; A.exports = function (A, i) { i = i || {}, "undefined" == typeof i.singleton && (i.singleton = u()), "undefined" == typeof i.insertAt && (i.insertAt = "bottom"); var t = e(A); return s(t, i), function (A) { for (var n = [], o = 0; o < t.length; o++) { var h = t[o], a = I[h.id]; a.refs--, n.push(a) } if (A) { var r = e(A); s(r, i) } for (var o = 0; o < n.length; o++) { var a = n[o]; if (0 === a.refs) { for (var c = 0; c < a.parts.length; c++) a.parts[c](); delete I[a.id] } } } }; var f = function () { var A = []; return function (i, t) { return A[i] = t, A.filter(Boolean).join("\n") } }() }, function (A, i, t) { var s = t(1); "string" == typeof s && (s = [[A.id, s, ""]]); t(4)(s, {}); s.locals && (A.exports = s.locals) }, function (A, i) { function t(A, i) { this.outerContainerEl = "string" == typeof A ? document.querySelector(A) : A, this.containerEl = null, this.config = i || t.config, this.dimensions = t.defaultDimensions, this.canvas = null, this.canvasCtx = null, this.tRex = null, this.distanceMeter = null, this.distanceRan = 0, this.highestScore = 0, this.time = 0, this.runningTime = 0, this.msPerFrame = 1e3 / V, this.currentSpeed = this.config.SPEED, this.obstacles = [], this.started = !1, this.activated = !1, this.crashed = !1, this.paused = !1, this.inverted = !1, this.invertTimer = 0, this.resizeTimerId_ = null, this.playCount = 0, this.audioBuffer = null, this.soundFx = {}, this.audioContext = null, this.images = {}, this.imagesLoaded = 0, this.loadImages() } function s(A, i) { return Math.floor(Math.random() * (i - A + 1)) + A } function e(A) { D && window.navigator.vibrate && window.navigator.vibrate(A) } function n(A, i, s, e) { var n = document.createElement("canvas"); return n.className = e ? t.classes.CANVAS + " " + e : t.classes.CANVAS, n.width = i, n.height = s, A.appendChild(n), n } function o(A) { for (var i = A.length / 4 * 3, t = atob(A), s = new ArrayBuffer(i), e = new Uint8Array(s), n = 0; i > n; n++) e[n] = t.charCodeAt(n); return e.buffer } function h() { return T ? (new Date).getTime() : performance.now() } function a(A, i, t, s) { this.canvas = A, this.canvasCtx = A.getContext("2d"), this.canvasDimensions = s, this.textImgPos = i, this.restartImgPos = t, this.draw() } function r(A, i, s) { var e = (t.defaultDimensions.WIDTH + A.xPos, new I(i.xPos + 1, i.yPos + 1, i.config.WIDTH - 2, i.config.HEIGHT - 2)), n = new I(A.xPos + 1, A.yPos + 1, A.typeConfig.width * A.size - 2, A.typeConfig.height - 2); if (s && g(s, e, n), d(e, n)) for (var o = A.collisionBoxes, h = i.ducking ? u.collisionBoxes.DUCKING : u.collisionBoxes.RUNNING, a = 0; a < h.length; a++) for (var r = 0; r < o.length; r++) { var E = c(h[a], e), l = c(o[r], n), C = d(E, l); if (s && g(s, E, l), C) return [E, l] } return !1 } function c(A, i) { return new I(A.x + i.x, A.y + i.y, A.width, A.height) } function g(A, i, t) { A.save(), A.strokeStyle = "#f00", A.strokeRect(i.x, i.y, i.width, i.height), A.strokeStyle = "#0f0", A.strokeRect(t.x, t.y, t.width, t.height), A.restore() } function d(A, i) { var t = !1, s = (A.x, A.y, i.x); i.y; return A.x < s + i.width && A.x + A.width > s && A.y < i.y + i.height && A.height + A.y > i.y && (t = !0), t } function I(A, i, t, s) { this.x = A, this.y = i, this.width = t, this.height = s } function E(A, i, t, e, n, o, h) { this.canvasCtx = A, this.spritePos = t, this.typeConfig = i, this.gapCoefficient = n, this.size = s(1, E.MAX_OBSTACLE_LENGTH), this.dimensions = e, this.remove = !1, this.xPos = e.WIDTH + (h || 0), this.yPos = 0, this.width = 0, this.collisionBoxes = [], this.gap = 0, this.speedOffset = 0, this.currentFrame = 0, this.timer = 0, this.init(o) } function u(A, i) { this.canvas = A, this.canvasCtx = A.getContext("2d"), this.spritePos = i, this.xPos = 0, this.yPos = 0, this.groundYPos = 0, this.currentFrame = 0, this.currentAnimFrames = [], this.blinkDelay = 0, this.animStartTime = 0, this.timer = 0, this.msPerFrame = 1e3 / V, this.config = u.config, this.status = u.status.WAITING, this.jumping = !1, this.ducking = !1, this.jumpVelocity = 0, this.reachedMinHeight = !1, this.speedDrop = !1, this.jumpCount = 0, this.jumpspotX = 0, this.init() } function l(A, i, s) { this.canvas = A, this.canvasCtx = A.getContext("2d"), this.image = t.imageSprite, this.spritePos = i, this.x = 0, this.y = 5, this.currentDistance = 0, this.maxScore = 0, this.highScore = 0, this.container = null, this.digits = [], this.acheivement = !1, this.defaultString = "", this.flashTimer = 0, this.flashIterations = 0, this.invertTrigger = !1, this.config = l.config, this.maxScoreUnits = this.config.MAX_DISTANCE_UNITS, this.init(s) } function C(A, i, t) { this.canvas = A, this.canvasCtx = this.canvas.getContext("2d"), this.spritePos = i, this.containerWidth = t, this.xPos = t, this.yPos = 0, this.remove = !1, this.cloudGap = s(C.config.MIN_CLOUD_GAP, C.config.MAX_CLOUD_GAP), this.init() } function p(A, i, t) { this.spritePos = i, this.canvas = A, this.canvasCtx = A.getContext("2d"), this.xPos = t - 50, this.yPos = 30, this.currentPhase = 0, this.opacity = 0, this.containerWidth = t, this.stars = [], this.drawStars = !1, this.placeStars() } function m(A, i) { this.spritePos = i, this.canvas = A, this.canvasCtx = A.getContext("2d"), this.sourceDimensions = {}, this.dimensions = m.dimensions, this.sourceXPos = [this.spritePos.x, this.spritePos.x + this.dimensions.WIDTH], this.xPos = [], this.yPos = 0, this.bumpThreshold = .5, this.setSourceDimensions(), this.draw() } function f(A, i, t, s) { this.canvas = A, this.canvasCtx = this.canvas.getContext("2d"), this.config = f.config, this.dimensions = t, this.gapCoefficient = s, this.obstacles = [], this.obstacleHistory = [], this.horizonOffsets = [0, 0], this.cloudFrequency = this.config.CLOUD_FREQUENCY, this.spritePos = i, this.nightMode = null, this.clouds = [], this.cloudSpeed = this.config.BG_CLOUD_SPEED, this.horizonLine = null, this.init() } A.exports = t; var S = 600, V = 60, Q = window.devicePixelRatio > 1, T = window.navigator.userAgent.indexOf("CriOS") > -1 || "UIWebViewForStaticFileContent" == window.navigator.userAgent, D = window.navigator.userAgent.indexOf("Mobi") > -1 || T; "ontouchstart" in window; t.config = { ACCELERATION: .001, BG_CLOUD_SPEED: .2, BOTTOM_PAD: 10, CLEAR_TIME: 3e3, CLOUD_FREQUENCY: .5, GAMEOVER_CLEAR_TIME: 750, GAP_COEFFICIENT: .6, GRAVITY: .6, INITIAL_JUMP_VELOCITY: 12, INVERT_FADE_DURATION: 12e3, INVERT_DISTANCE: 700, MAX_CLOUDS: 6, MAX_OBSTACLE_LENGTH: 3, MAX_OBSTACLE_DUPLICATION: 2, MAX_SPEED: 13, MIN_JUMP_HEIGHT: 35, MOBILE_SPEED_COEFFICIENT: 1.2, RESOURCE_TEMPLATE_ID: "audio-resources", SPEED: 6, SPEED_DROP_COEFFICIENT: 3 }, t.defaultDimensions = {WIDTH: S, HEIGHT: 150}, t.classes = { CANVAS: "runner-canvas", CONTAINER: "runner-container", CRASHED: "crashed", ICON: "icon-offline", INVERTED: "inverted", SNACKBAR: "snackbar", SNACKBAR_SHOW: "snackbar-show", TOUCH_CONTROLLER: "controller" }, t.spriteDefinition = { LDPI: { CACTUS_LARGE: {x: 332, y: 2}, CACTUS_SMALL: {x: 228, y: 2}, CLOUD: {x: 86, y: 2}, HORIZON: {x: 2, y: 54}, MOON: {x: 484, y: 2}, PTERODACTYL: {x: 134, y: 2}, RESTART: {x: 2, y: 2}, TEXT_SPRITE: {x: 655, y: 2}, TREX: {x: 848, y: 2}, STAR: {x: 645, y: 2} }, HDPI: { CACTUS_LARGE: {x: 652, y: 2}, CACTUS_SMALL: {x: 446, y: 2}, CLOUD: {x: 166, y: 2}, HORIZON: {x: 2, y: 104}, MOON: {x: 954, y: 2}, PTERODACTYL: {x: 260, y: 2}, RESTART: {x: 2, y: 2}, TEXT_SPRITE: {x: 1294, y: 2}, TREX: {x: 1678, y: 2}, STAR: {x: 1276, y: 2} } }, t.sounds = { BUTTON_PRESS: "offline-sound-press", HIT: "offline-sound-hit", SCORE: "offline-sound-reached" }, t.keycodes = { JUMP: {38: 1, 32: 1}, DUCK: {40: 1}, RESTART: {13: 1} }, t.events = { ANIM_END: "webkitAnimationEnd", CLICK: "click", KEYDOWN: "keydown", KEYUP: "keyup", MOUSEDOWN: "mousedown", MOUSEUP: "mouseup", RESIZE: "resize", TOUCHEND: "touchend", TOUCHSTART: "touchstart", VISIBILITY: "visibilitychange", BLUR: "blur", FOCUS: "focus", LOAD: "load" }, t.prototype = { updateConfigSetting: function (A, i) { if (A in this.config && void 0 != i) switch (this.config[A] = i, A) { case"GRAVITY": case"MIN_JUMP_HEIGHT": case"SPEED_DROP_COEFFICIENT": this.tRex.config[A] = i; break; case"INITIAL_JUMP_VELOCITY": this.tRex.setJumpVelocity(i); break; case"SPEED": this.setSpeed(i) } }, loadImages: function () { Q ? (t.imageSprite = document.getElementById("offline-resources-2x"), this.spriteDef = t.spriteDefinition.HDPI) : (t.imageSprite = document.getElementById("offline-resources-1x"), this.spriteDef = t.spriteDefinition.LDPI), this.init() }, loadSounds: function () { if (!T && window.AudioContext) { this.audioContext = new AudioContext; var A = document.getElementById(this.config.RESOURCE_TEMPLATE_ID).content; for (var i in t.sounds) { var s = A.getElementById(t.sounds[i]).src; s = s.substr(s.indexOf(",") + 1); var e = o(s); this.audioContext.decodeAudioData(e, function (A, i) { this.soundFx[A] = i }.bind(this, i)) } } }, setSpeed: function (A) { var i = A || this.currentSpeed; if (this.dimensions.WIDTH < S) { var t = i * this.dimensions.WIDTH / S * this.config.MOBILE_SPEED_COEFFICIENT; this.currentSpeed = t > i ? i : t } else A && (this.currentSpeed = A) }, init: function () { this.adjustDimensions(), this.setSpeed(), this.containerEl = document.createElement("div"), this.containerEl.className = t.classes.CONTAINER, this.canvas = n(this.containerEl, this.dimensions.WIDTH, this.dimensions.HEIGHT, t.classes.PLAYER), this.canvasCtx = this.canvas.getContext("2d"), this.canvasCtx.fillStyle = "#f7f7f7", this.canvasCtx.fill(), t.updateCanvasScaling(this.canvas), this.horizon = new f(this.canvas, this.spriteDef, this.dimensions, this.config.GAP_COEFFICIENT), this.distanceMeter = new l(this.canvas, this.spriteDef.TEXT_SPRITE, this.dimensions.WIDTH), this.tRex = new u(this.canvas, this.spriteDef.TREX), this.outerContainerEl.appendChild(this.containerEl), D && this.createTouchController(), this.startListening(), this.update(), window.addEventListener(t.events.RESIZE, this.debounceResize.bind(this)) }, createTouchController: function () { this.touchController = document.createElement("div"), this.touchController.className = t.classes.TOUCH_CONTROLLER }, debounceResize: function () { this.resizeTimerId_ || (this.resizeTimerId_ = setInterval(this.adjustDimensions.bind(this), 250)) }, adjustDimensions: function () { clearInterval(this.resizeTimerId_), this.resizeTimerId_ = null; var A = window.getComputedStyle(this.outerContainerEl), i = Number(A.paddingLeft.substr(0, A.paddingLeft.length - 2)); this.dimensions.WIDTH = this.outerContainerEl.offsetWidth - 2 * i, this.canvas && (this.canvas.width = this.dimensions.WIDTH, this.canvas.height = this.dimensions.HEIGHT, t.updateCanvasScaling(this.canvas), this.distanceMeter.calcXPos(this.dimensions.WIDTH), this.clearCanvas(), this.horizon.update(0, 0, !0), this.tRex.update(0), this.activated || this.crashed || this.paused ? (this.containerEl.style.width = this.dimensions.WIDTH + "px", this.containerEl.style.height = this.dimensions.HEIGHT + "px", this.distanceMeter.update(0, Math.ceil(this.distanceRan)), this.stop()) : this.tRex.draw(0, 0), this.crashed && this.gameOverPanel && (this.gameOverPanel.updateDimensions(this.dimensions.WIDTH), this.gameOverPanel.draw())) }, playIntro: function () { if (this.started || this.crashed) this.crashed && this.restart(); else { this.playingIntro = !0, this.tRex.playingIntro = !0; var A = "@-webkit-keyframes intro { from { width:" + u.config.WIDTH + "px }to { width: " + this.dimensions.WIDTH + "px }}"; document.styleSheets[0].insertRule(A, 0), this.containerEl.addEventListener(t.events.ANIM_END, this.startGame.bind(this)), this.containerEl.style.webkitAnimation = "intro .4s ease-out 1 both", this.containerEl.style.width = this.dimensions.WIDTH + "px", this.touchController && this.outerContainerEl.appendChild(this.touchController), this.activated = !0, this.started = !0 } }, startGame: function () { this.runningTime = 0, this.playingIntro = !1, this.tRex.playingIntro = !1, this.containerEl.style.webkitAnimation = "", this.playCount++, document.addEventListener(t.events.VISIBILITY, this.onVisibilityChange.bind(this)), window.addEventListener(t.events.BLUR, this.onVisibilityChange.bind(this)), window.addEventListener(t.events.FOCUS, this.onVisibilityChange.bind(this)) }, clearCanvas: function () { this.canvasCtx.clearRect(0, 0, this.dimensions.WIDTH, this.dimensions.HEIGHT) }, update: function () { this.drawPending = !1; var A = h(), i = A - (this.time || A); if (this.time = A, this.activated) { this.clearCanvas(), this.tRex.jumping && this.tRex.updateJump(i), this.runningTime += i; var t = this.runningTime > this.config.CLEAR_TIME; 1 != this.tRex.jumpCount || this.playingIntro || this.playIntro(), this.playingIntro ? this.horizon.update(0, this.currentSpeed, t) : (i = this.started ? i : 0, this.horizon.update(i, this.currentSpeed, t, this.inverted)); var s = t && r(this.horizon.obstacles[0], this.tRex); s ? this.gameOver() : (this.distanceRan += this.currentSpeed * i / this.msPerFrame, this.currentSpeed < this.config.MAX_SPEED && (this.currentSpeed += this.config.ACCELERATION)); var e = this.distanceMeter.update(i, Math.ceil(this.distanceRan)); if (e && this.playSound(this.soundFx.SCORE), this.invertTimer > this.config.INVERT_FADE_DURATION) this.invertTimer = 0, this.invertTrigger = !1, this.invert(); else if (this.invertTimer) this.invertTimer += i; else { var n = this.distanceMeter.getActualDistance(Math.ceil(this.distanceRan)); n > 0 && (this.invertTrigger = !(n % this.config.INVERT_DISTANCE), this.invertTrigger && 0 === this.invertTimer && (this.invertTimer += i, this.invert())) } } this.crashed || (this.tRex.update(i), this.raq()) }, handleEvent: function (A) { return function (i, t) { switch (i) { case t.KEYDOWN: case t.TOUCHSTART: case t.MOUSEDOWN: this.onKeyDown(A); break; case t.KEYUP: case t.TOUCHEND: case t.MOUSEUP: this.onKeyUp(A) } }.bind(this)(A.type, t.events) }, startListening: function () { document.addEventListener(t.events.KEYDOWN, this), document.addEventListener(t.events.KEYUP, this), D ? (this.touchController.addEventListener(t.events.TOUCHSTART, this), this.touchController.addEventListener(t.events.TOUCHEND, this), this.containerEl.addEventListener(t.events.TOUCHSTART, this)) : (document.addEventListener(t.events.MOUSEDOWN, this), document.addEventListener(t.events.MOUSEUP, this)) }, stopListening: function () { document.removeEventListener(t.events.KEYDOWN, this), document.removeEventListener(t.events.KEYUP, this), D ? (this.touchController.removeEventListener(t.events.TOUCHSTART, this), this.touchController.removeEventListener(t.events.TOUCHEND, this), this.containerEl.removeEventListener(t.events.TOUCHSTART, this)) : (document.removeEventListener(t.events.MOUSEDOWN, this), document.removeEventListener(t.events.MOUSEUP, this)) }, onKeyDown: function (A) { D && A.preventDefault(), this.crashed || !t.keycodes.JUMP[A.keyCode] && A.type != t.events.TOUCHSTART || (this.activated || (this.loadSounds(), this.activated = !0), this.tRex.jumping || this.tRex.ducking || (this.playSound(this.soundFx.BUTTON_PRESS), this.tRex.startJump(this.currentSpeed))), this.crashed && A.type == t.events.TOUCHSTART && A.currentTarget == this.containerEl && this.restart(), this.activated && !this.crashed && t.keycodes.DUCK[A.keyCode] && (A.preventDefault(), this.tRex.jumping ? this.tRex.setSpeedDrop() : this.tRex.jumping || this.tRex.ducking || this.tRex.setDuck(!0)) }, onKeyUp: function (A) { var i = String(A.keyCode), s = t.keycodes.JUMP[i] || A.type == t.events.TOUCHEND || A.type == t.events.MOUSEDOWN; if (this.isRunning() && s) this.tRex.endJump(); else if (t.keycodes.DUCK[i]) this.tRex.speedDrop = !1, this.tRex.setDuck(!1); else if (this.crashed) { var e = h() - this.time; (t.keycodes.RESTART[i] || this.isLeftClickOnCanvas(A) || e >= this.config.GAMEOVER_CLEAR_TIME && t.keycodes.JUMP[i]) && this.restart() } else this.paused && s && (this.tRex.reset(), this.play()) }, isLeftClickOnCanvas: function (A) { return null != A.button && A.button < 2 && A.type == t.events.MOUSEUP && A.target == this.canvas }, raq: function () { this.drawPending || (this.drawPending = !0, this.raqId = requestAnimationFrame(this.update.bind(this))) }, isRunning: function () { return !!this.raqId }, gameOver: function () { this.playSound(this.soundFx.HIT), e(200), this.stop(), this.crashed = !0, this.distanceMeter.acheivement = !1, this.tRex.update(100, u.status.CRASHED), this.gameOverPanel ? this.gameOverPanel.draw() : this.gameOverPanel = new a(this.canvas, this.spriteDef.TEXT_SPRITE, this.spriteDef.RESTART, this.dimensions), this.distanceRan > this.highestScore && (this.highestScore = Math.ceil(this.distanceRan), this.distanceMeter.setHighScore(this.highestScore)), this.time = h() }, stop: function () { this.activated = !1, this.paused = !0, cancelAnimationFrame(this.raqId), this.raqId = 0 }, play: function () { this.crashed || (this.activated = !0, this.paused = !1, this.tRex.update(0, u.status.RUNNING), this.time = h(), this.update()) }, restart: function () { this.raqId || (this.playCount++, this.runningTime = 0, this.activated = !0, this.crashed = !1, this.distanceRan = 0, this.setSpeed(this.config.SPEED), this.time = h(), this.containerEl.classList.remove(t.classes.CRASHED), this.clearCanvas(), this.distanceMeter.reset(this.highestScore), this.horizon.reset(), this.tRex.reset(), this.playSound(this.soundFx.BUTTON_PRESS), this.invert(!0), this.update()) }, onVisibilityChange: function (A) { document.hidden || document.webkitHidden || "blur" == A.type || "visible" != document.visibilityState ? this.stop() : this.crashed || (this.tRex.reset(), this.play()) }, playSound: function (A) { if (A) { var i = this.audioContext.createBufferSource(); i.buffer = A, i.connect(this.audioContext.destination), i.start(0) } }, invert: function (A) { A ? (document.body.classList.toggle(t.classes.INVERTED, !1), this.invertTimer = 0, this.inverted = !1) : this.inverted = document.body.classList.toggle(t.classes.INVERTED, this.invertTrigger) } }, t.updateCanvasScaling = function (A, i, t) { var s = A.getContext("2d"), e = Math.floor(window.devicePixelRatio) || 1, n = Math.floor(s.webkitBackingStorePixelRatio) || 1, o = e / n; if (e !== n) { var h = i || A.width, a = t || A.height; return A.width = h * o, A.height = a * o, A.style.width = h + "px", A.style.height = a + "px", s.scale(o, o), !0 } return 1 == e && (A.style.width = A.width + "px", A.style.height = A.height + "px"), !1 }, a.dimensions = { TEXT_X: 0, TEXT_Y: 13, TEXT_WIDTH: 191, TEXT_HEIGHT: 11, RESTART_WIDTH: 36, RESTART_HEIGHT: 32 }, a.prototype = { updateDimensions: function (A, i) { this.canvasDimensions.WIDTH = A, i && (this.canvasDimensions.HEIGHT = i) }, draw: function () { var A = a.dimensions, i = this.canvasDimensions.WIDTH / 2, s = A.TEXT_X, e = A.TEXT_Y, n = A.TEXT_WIDTH, o = A.TEXT_HEIGHT, h = Math.round(i - A.TEXT_WIDTH / 2), r = Math.round((this.canvasDimensions.HEIGHT - 25) / 3), c = A.TEXT_WIDTH, g = A.TEXT_HEIGHT, d = A.RESTART_WIDTH, I = A.RESTART_HEIGHT, E = i - A.RESTART_WIDTH / 2, u = this.canvasDimensions.HEIGHT / 2; Q && (e *= 2, s *= 2, n *= 2, o *= 2, d *= 2, I *= 2), s += this.textImgPos.x, e += this.textImgPos.y, this.canvasCtx.drawImage(t.imageSprite, s, e, n, o, h, r, c, g), this.canvasCtx.drawImage(t.imageSprite, this.restartImgPos.x, this.restartImgPos.y, d, I, E, u, A.RESTART_WIDTH, A.RESTART_HEIGHT) } }, E.MAX_GAP_COEFFICIENT = 1.5, E.MAX_OBSTACLE_LENGTH = 3, E.prototype = { init: function (A) { if (this.cloneCollisionBoxes(), this.size > 1 && this.typeConfig.multipleSpeed > A && (this.size = 1), this.width = this.typeConfig.width * this.size, Array.isArray(this.typeConfig.yPos)) { var i = D ? this.typeConfig.yPosMobile : this.typeConfig.yPos; this.yPos = i[s(0, i.length - 1)] } else this.yPos = this.typeConfig.yPos; this.draw(), this.size > 1 && (this.collisionBoxes[1].width = this.width - this.collisionBoxes[0].width - this.collisionBoxes[2].width, this.collisionBoxes[2].x = this.width - this.collisionBoxes[2].width), this.typeConfig.speedOffset && (this.speedOffset = Math.random() > .5 ? this.typeConfig.speedOffset : -this.typeConfig.speedOffset), this.gap = this.getGap(this.gapCoefficient, A) }, draw: function () { var A = this.typeConfig.width, i = this.typeConfig.height; Q && (A = 2 * A, i = 2 * i); var s = A * this.size * (.5 * (this.size - 1)) + this.spritePos.x; this.currentFrame > 0 && (s += A * this.currentFrame), this.canvasCtx.drawImage(t.imageSprite, s, this.spritePos.y, A * this.size, i, this.xPos, this.yPos, this.typeConfig.width * this.size, this.typeConfig.height) }, update: function (A, i) { this.remove || (this.typeConfig.speedOffset && (i += this.speedOffset), this.xPos -= Math.floor(i * V / 1e3 * A), this.typeConfig.numFrames && (this.timer += A, this.timer >= this.typeConfig.frameRate && (this.currentFrame = this.currentFrame == this.typeConfig.numFrames - 1 ? 0 : this.currentFrame + 1, this.timer = 0)), this.draw(), this.isVisible() || (this.remove = !0)) }, getGap: function (A, i) { var t = Math.round(this.width * i + this.typeConfig.minGap * A), e = Math.round(t * E.MAX_GAP_COEFFICIENT); return s(t, e) }, isVisible: function () { return this.xPos + this.width > 0 }, cloneCollisionBoxes: function () { for (var A = this.typeConfig.collisionBoxes, i = A.length - 1; i >= 0; i--) this.collisionBoxes[i] = new I(A[i].x, A[i].y, A[i].width, A[i].height) } }, E.types = [{ type: "CACTUS_SMALL", width: 17, height: 35, yPos: 105, multipleSpeed: 4, minGap: 120, minSpeed: 0, collisionBoxes: [new I(0, 7, 5, 27), new I(4, 0, 6, 34), new I(10, 4, 7, 14)] }, { type: "CACTUS_LARGE", width: 25, height: 50, yPos: 90, multipleSpeed: 7, minGap: 120, minSpeed: 0, collisionBoxes: [new I(0, 12, 7, 38), new I(8, 0, 7, 49), new I(13, 10, 10, 38)] }, { type: "PTERODACTYL", width: 46, height: 40, yPos: [100, 75, 50], yPosMobile: [100, 50], multipleSpeed: 999, minSpeed: 8.5, minGap: 150, collisionBoxes: [new I(15, 15, 16, 5), new I(18, 21, 24, 6), new I(2, 14, 4, 3), new I(6, 10, 4, 7), new I(10, 8, 6, 9)], numFrames: 2, frameRate: 1e3 / 6, speedOffset: .8 }], u.config = { DROP_VELOCITY: -5, GRAVITY: .6, HEIGHT: 47, HEIGHT_DUCK: 25, INIITAL_JUMP_VELOCITY: -10, INTRO_DURATION: 1500, MAX_JUMP_HEIGHT: 30, MIN_JUMP_HEIGHT: 30, SPEED_DROP_COEFFICIENT: 3, SPRITE_WIDTH: 262, START_X_POS: 50, WIDTH: 44, WIDTH_DUCK: 59 }, u.collisionBoxes = { DUCKING: [new I(1, 18, 55, 25)], RUNNING: [new I(22, 0, 17, 16), new I(1, 18, 30, 9), new I(10, 35, 14, 8), new I(1, 24, 29, 5), new I(5, 30, 21, 4), new I(9, 34, 15, 4)] }, u.status = { CRASHED: "CRASHED", DUCKING: "DUCKING", JUMPING: "JUMPING", RUNNING: "RUNNING", WAITING: "WAITING" }, u.BLINK_TIMING = 7e3, u.animFrames = { WAITING: {frames: [44, 0], msPerFrame: 1e3 / 3}, RUNNING: {frames: [88, 132], msPerFrame: 1e3 / 12}, CRASHED: {frames: [220], msPerFrame: 1e3 / 60}, JUMPING: {frames: [0], msPerFrame: 1e3 / 60}, DUCKING: {frames: [262, 321], msPerFrame: 125} }, u.prototype = { init: function () { this.blinkDelay = this.setBlinkDelay(), this.groundYPos = t.defaultDimensions.HEIGHT - this.config.HEIGHT - t.config.BOTTOM_PAD, this.yPos = this.groundYPos, this.minJumpHeight = this.groundYPos - this.config.MIN_JUMP_HEIGHT, this.draw(0, 0), this.update(0, u.status.WAITING) }, setJumpVelocity: function (A) { this.config.INIITAL_JUMP_VELOCITY = -A, this.config.DROP_VELOCITY = -A / 2 }, update: function (A, i) { this.timer += A, i && (this.status = i, this.currentFrame = 0, this.msPerFrame = u.animFrames[i].msPerFrame, this.currentAnimFrames = u.animFrames[i].frames, i == u.status.WAITING && (this.animStartTime = h(), this.setBlinkDelay())), this.playingIntro && this.xPos < this.config.START_X_POS && (this.xPos += Math.round(this.config.START_X_POS / this.config.INTRO_DURATION * A)), this.status == u.status.WAITING ? this.blink(h()) : this.draw(this.currentAnimFrames[this.currentFrame], 0), this.timer >= this.msPerFrame && (this.currentFrame = this.currentFrame == this.currentAnimFrames.length - 1 ? 0 : this.currentFrame + 1, this.timer = 0), this.speedDrop && this.yPos == this.groundYPos && (this.speedDrop = !1, this.setDuck(!0)) }, draw: function (A, i) { var s = A, e = i, n = this.ducking && this.status != u.status.CRASHED ? this.config.WIDTH_DUCK : this.config.WIDTH, o = this.config.HEIGHT; Q && (s *= 2, e *= 2, n *= 2, o *= 2), s += this.spritePos.x, e += this.spritePos.y, this.ducking && this.status != u.status.CRASHED ? this.canvasCtx.drawImage(t.imageSprite, s, e, n, o, this.xPos, this.yPos, this.config.WIDTH_DUCK, this.config.HEIGHT) : (this.ducking && this.status == u.status.CRASHED && this.xPos++, this.canvasCtx.drawImage(t.imageSprite, s, e, n, o, this.xPos, this.yPos, this.config.WIDTH, this.config.HEIGHT)) }, setBlinkDelay: function () { this.blinkDelay = Math.ceil(Math.random() * u.BLINK_TIMING) }, blink: function (A) { var i = A - this.animStartTime; i >= this.blinkDelay && (this.draw(this.currentAnimFrames[this.currentFrame], 0), 1 == this.currentFrame && (this.setBlinkDelay(), this.animStartTime = A)) }, startJump: function (A) { this.jumping || (this.update(0, u.status.JUMPING), this.jumpVelocity = this.config.INIITAL_JUMP_VELOCITY - A / 10, this.jumping = !0, this.reachedMinHeight = !1, this.speedDrop = !1) }, endJump: function () { this.reachedMinHeight && this.jumpVelocity < this.config.DROP_VELOCITY && (this.jumpVelocity = this.config.DROP_VELOCITY) }, updateJump: function (A, i) { var t = u.animFrames[this.status].msPerFrame, s = A / t; this.speedDrop ? this.yPos += Math.round(this.jumpVelocity * this.config.SPEED_DROP_COEFFICIENT * s) : this.yPos += Math.round(this.jumpVelocity * s), this.jumpVelocity += this.config.GRAVITY * s, (this.yPos < this.minJumpHeight || this.speedDrop) && (this.reachedMinHeight = !0), (this.yPos < this.config.MAX_JUMP_HEIGHT || this.speedDrop) && this.endJump(), this.yPos > this.groundYPos && (this.reset(), this.jumpCount++), this.update(A) }, setSpeedDrop: function () { this.speedDrop = !0, this.jumpVelocity = 1 }, setDuck: function (A) { A && this.status != u.status.DUCKING ? (this.update(0, u.status.DUCKING), this.ducking = !0) : this.status == u.status.DUCKING && (this.update(0, u.status.RUNNING), this.ducking = !1) }, reset: function () { this.yPos = this.groundYPos, this.jumpVelocity = 0, this.jumping = !1, this.ducking = !1, this.update(0, u.status.RUNNING), this.midair = !1, this.speedDrop = !1, this.jumpCount = 0 } }, l.dimensions = { WIDTH: 10, HEIGHT: 13, DEST_WIDTH: 11 }, l.yPos = [0, 13, 27, 40, 53, 67, 80, 93, 107, 120], l.config = { MAX_DISTANCE_UNITS: 5, ACHIEVEMENT_DISTANCE: 100, COEFFICIENT: .025, FLASH_DURATION: 250, FLASH_ITERATIONS: 3 }, l.prototype = { init: function (A) { var i = ""; this.calcXPos(A), this.maxScore = this.maxScoreUnits; for (var t = 0; t < this.maxScoreUnits; t++) this.draw(t, 0), this.defaultString += "0", i += "9"; this.maxScore = parseInt(i) }, calcXPos: function (A) { this.x = A - l.dimensions.DEST_WIDTH * (this.maxScoreUnits + 1) }, draw: function (A, i, t) { var s = l.dimensions.WIDTH, e = l.dimensions.HEIGHT, n = l.dimensions.WIDTH * i, o = 0, h = A * l.dimensions.DEST_WIDTH, a = this.y, r = l.dimensions.WIDTH, c = l.dimensions.HEIGHT; if (Q && (s *= 2, e *= 2, n *= 2), n += this.spritePos.x, o += this.spritePos.y, this.canvasCtx.save(), t) { var g = this.x - 2 * this.maxScoreUnits * l.dimensions.WIDTH; this.canvasCtx.translate(g, this.y) } else this.canvasCtx.translate(this.x, this.y); this.canvasCtx.drawImage(this.image, n, o, s, e, h, a, r, c), this.canvasCtx.restore() }, getActualDistance: function (A) { return A ? Math.round(A * this.config.COEFFICIENT) : 0 }, update: function (A, i) { var t = !0, s = !1; if (this.acheivement) this.flashIterations <= this.config.FLASH_ITERATIONS ? (this.flashTimer += A, this.flashTimer < this.config.FLASH_DURATION ? t = !1 : this.flashTimer > 2 * this.config.FLASH_DURATION && (this.flashTimer = 0, this.flashIterations++)) : (this.acheivement = !1, this.flashIterations = 0, this.flashTimer = 0); else if (i = this.getActualDistance(i), i > this.maxScore && this.maxScoreUnits == this.config.MAX_DISTANCE_UNITS ? (this.maxScoreUnits++, this.maxScore = parseInt(this.maxScore + "9")) : this.distance = 0, i > 0) { i % this.config.ACHIEVEMENT_DISTANCE == 0 && (this.acheivement = !0, this.flashTimer = 0, s = !0); var e = (this.defaultString + i).substr(-this.maxScoreUnits); this.digits = e.split("") } else this.digits = this.defaultString.split(""); if (t) for (var n = this.digits.length - 1; n >= 0; n--) this.draw(n, parseInt(this.digits[n])); return this.drawHighScore(), s }, drawHighScore: function () { this.canvasCtx.save(), this.canvasCtx.globalAlpha = .8; for (var A = this.highScore.length - 1; A >= 0; A--) this.draw(A, parseInt(this.highScore[A], 10), !0); this.canvasCtx.restore() }, setHighScore: function (A) { A = this.getActualDistance(A); var i = (this.defaultString + A).substr(-this.maxScoreUnits); this.highScore = ["10", "11", ""].concat(i.split("")) }, reset: function () { this.update(0), this.acheivement = !1 } }, C.config = { HEIGHT: 14, MAX_CLOUD_GAP: 400, MAX_SKY_LEVEL: 30, MIN_CLOUD_GAP: 100, MIN_SKY_LEVEL: 71, WIDTH: 46 }, C.prototype = { init: function () { this.yPos = s(C.config.MAX_SKY_LEVEL, C.config.MIN_SKY_LEVEL), this.draw() }, draw: function () { this.canvasCtx.save(); var A = C.config.WIDTH, i = C.config.HEIGHT; Q && (A = 2 * A, i = 2 * i), this.canvasCtx.drawImage(t.imageSprite, this.spritePos.x, this.spritePos.y, A, i, this.xPos, this.yPos, C.config.WIDTH, C.config.HEIGHT), this.canvasCtx.restore() }, update: function (A) { this.remove || (this.xPos -= Math.ceil(A), this.draw(), this.isVisible() || (this.remove = !0)) }, isVisible: function () { return this.xPos + C.config.WIDTH > 0 } }, p.config = { FADE_SPEED: .035, HEIGHT: 40, MOON_SPEED: .25, NUM_STARS: 2, STAR_SIZE: 9, STAR_SPEED: .3, STAR_MAX_Y: 70, WIDTH: 20 }, p.phases = [140, 120, 100, 60, 40, 20, 0], p.prototype = { update: function (A, i) { if (A && 0 == this.opacity && (this.currentPhase++, this.currentPhase >= p.phases.length && (this.currentPhase = 0)), A && (this.opacity < 1 || 0 == this.opacity) ? this.opacity += p.config.FADE_SPEED : this.opacity > 0 && (this.opacity -= p.config.FADE_SPEED), this.opacity > 0) { if (this.xPos = this.updateXPos(this.xPos, p.config.MOON_SPEED), this.drawStars) for (var t = 0; t < p.config.NUM_STARS; t++) this.stars[t].x = this.updateXPos(this.stars[t].x, p.config.STAR_SPEED); this.draw() } else this.opacity = 0, this.placeStars(); this.drawStars = !0 }, updateXPos: function (A, i) { return A < -p.config.WIDTH ? A = this.containerWidth : A -= i, A }, draw: function () { var A = 3 == this.currentPhase ? 2 * p.config.WIDTH : p.config.WIDTH, i = p.config.HEIGHT, s = this.spritePos.x + p.phases[this.currentPhase], e = A, n = p.config.STAR_SIZE, o = t.spriteDefinition.LDPI.STAR.x; if (Q && (A *= 2, i *= 2, s = this.spritePos.x + 2 * p.phases[this.currentPhase], n *= 2, o = t.spriteDefinition.HDPI.STAR.x), this.canvasCtx.save(), this.canvasCtx.globalAlpha = this.opacity, this.drawStars) for (var h = 0; h < p.config.NUM_STARS; h++) this.canvasCtx.drawImage(t.imageSprite, o, this.stars[h].sourceY, n, n, Math.round(this.stars[h].x), this.stars[h].y, p.config.STAR_SIZE, p.config.STAR_SIZE); this.canvasCtx.drawImage(t.imageSprite, s, this.spritePos.y, A, i, Math.round(this.xPos), this.yPos, e, p.config.HEIGHT), this.canvasCtx.globalAlpha = 1, this.canvasCtx.restore() }, placeStars: function () { for (var A = Math.round(this.containerWidth / p.config.NUM_STARS), i = 0; i < p.config.NUM_STARS; i++) this.stars[i] = {}, this.stars[i].x = s(A * i, A * (i + 1)), this.stars[i].y = s(0, p.config.STAR_MAX_Y), Q ? this.stars[i].sourceY = t.spriteDefinition.HDPI.STAR.y + 2 * p.config.STAR_SIZE * i : this.stars[i].sourceY = t.spriteDefinition.LDPI.STAR.y + p.config.STAR_SIZE * i }, reset: function () { this.currentPhase = 0, this.opacity = 0, this.update(!1) } }, m.dimensions = {WIDTH: 600, HEIGHT: 12, YPOS: 127}, m.prototype = { setSourceDimensions: function () { for (var A in m.dimensions) Q ? "YPOS" != A && (this.sourceDimensions[A] = 2 * m.dimensions[A]) : this.sourceDimensions[A] = m.dimensions[A], this.dimensions[A] = m.dimensions[A]; this.xPos = [0, m.dimensions.WIDTH], this.yPos = m.dimensions.YPOS }, getRandomType: function () { return Math.random() > this.bumpThreshold ? this.dimensions.WIDTH : 0 }, draw: function () { this.canvasCtx.drawImage(t.imageSprite, this.sourceXPos[0], this.spritePos.y, this.sourceDimensions.WIDTH, this.sourceDimensions.HEIGHT, this.xPos[0], this.yPos, this.dimensions.WIDTH, this.dimensions.HEIGHT), this.canvasCtx.drawImage(t.imageSprite, this.sourceXPos[1], this.spritePos.y, this.sourceDimensions.WIDTH, this.sourceDimensions.HEIGHT, this.xPos[1], this.yPos, this.dimensions.WIDTH, this.dimensions.HEIGHT) }, updateXPos: function (A, i) { var t = A, s = 0 == A ? 1 : 0; this.xPos[t] -= i, this.xPos[s] = this.xPos[t] + this.dimensions.WIDTH, this.xPos[t] <= -this.dimensions.WIDTH && (this.xPos[t] += 2 * this.dimensions.WIDTH, this.xPos[s] = this.xPos[t] - this.dimensions.WIDTH, this.sourceXPos[t] = this.getRandomType() + this.spritePos.x) }, update: function (A, i) { var t = Math.floor(.06 * i * A); this.xPos[0] <= 0 ? this.updateXPos(0, t) : this.updateXPos(1, t), this.draw() }, reset: function () { this.xPos[0] = 0, this.xPos[1] = m.dimensions.WIDTH } }, f.config = { BG_CLOUD_SPEED: .2, BUMPY_THRESHOLD: .3, CLOUD_FREQUENCY: .5, HORIZON_HEIGHT: 16, MAX_CLOUDS: 6 }, f.prototype = { init: function () { this.addCloud(), this.horizonLine = new m(this.canvas, this.spritePos.HORIZON), this.nightMode = new p(this.canvas, this.spritePos.MOON, this.dimensions.WIDTH) }, update: function (A, i, t, s) { this.runningTime += A, this.horizonLine.update(A, i), this.nightMode.update(s), this.updateClouds(A, i), t && this.updateObstacles(A, i) }, updateClouds: function (A, i) { var t = this.cloudSpeed / 1e3 * A * i, s = this.clouds.length; if (s) { for (var e = s - 1; e >= 0; e--) this.clouds[e].update(t); var n = this.clouds[s - 1]; s < this.config.MAX_CLOUDS && this.dimensions.WIDTH - n.xPos > n.cloudGap && this.cloudFrequency > Math.random() && this.addCloud(), this.clouds = this.clouds.filter(function (A) { return !A.remove }) } else this.addCloud() }, updateObstacles: function (A, i) { for (var t = this.obstacles.slice(0), s = 0; s < this.obstacles.length; s++) { var e = this.obstacles[s]; e.update(A, i), e.remove && t.shift() } if (this.obstacles = t, this.obstacles.length > 0) { var n = this.obstacles[this.obstacles.length - 1]; n && !n.followingObstacleCreated && n.isVisible() && n.xPos + n.width + n.gap < this.dimensions.WIDTH && (this.addNewObstacle(i), n.followingObstacleCreated = !0) } else this.addNewObstacle(i) }, removeFirstObstacle: function () { this.obstacles.shift() }, addNewObstacle: function (A) { var i = s(0, E.types.length - 1), e = E.types[i]; if (this.duplicateObstacleCheck(e.type) || A < e.minSpeed) this.addNewObstacle(A); else { var n = this.spritePos[e.type]; this.obstacles.push(new E(this.canvasCtx, e, n, this.dimensions, this.gapCoefficient, A, e.width)), this.obstacleHistory.unshift(e.type), this.obstacleHistory.length > 1 && this.obstacleHistory.splice(t.config.MAX_OBSTACLE_DUPLICATION) } }, duplicateObstacleCheck: function (A) { for (var i = 0, s = 0; s < this.obstacleHistory.length; s++) i = this.obstacleHistory[s] == A ? i + 1 : 0; return i >= t.config.MAX_OBSTACLE_DUPLICATION }, reset: function () { this.obstacles = [], this.horizonLine.reset(), this.nightMode.reset() }, resize: function (A, i) { this.canvas.width = A, this.canvas.height = i }, addCloud: function () { this.clouds.push(new C(this.canvas, this.spritePos.CLOUD, this.dimensions.WIDTH)) } } }]) });一般网页使用方法很简单,如果在一般的网页中使用直接添加<div id="container"></div> <script src="runner.js"></script> <script> initRunner('#container'); </script>其中runner.js可以为任意地址,你可以把runner放在本地,也可以把runner放在OSS(阿里云对象储存)等储存。Typecho博客我们还可以将这段代码嵌入到博客里去,当然因为在这里图个方便,我直接使用iframe方法来引入,比较方便,我在这贴下我的方法<iframe align="center" width="100%" height="200px" src="https://tx.ddg.ink/dinogame/index.html" frameborder="no" border="0" scrolling="no" marginwidth="0" marginheight="0" ></iframe>很简单啊,就一句话就可以了,当然你也可以选择常规的方式去嵌入。我的方法是引入我OSS(阿里云对象储存)存放的html文件,所以要保证你的OSS(阿里云对象储存)和你的网站活的一样久。index.html的网页源码如下<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>Runner</title> </head> <body> <div id="test"></div> <script src="https://tx.ddg.ink/dinogame/runner.js"></script> <script> initRunner( '#test' ); </script> </body> </html>你可以自己存放在本地服务器去引用,js同理注意在typecho中的markdown语法!!!你的代码!!!这样是嵌入代码,记得是英文感叹号。不要直接复制我的代码使用,因为设置了Referer白名单防止盗链,直接使用是无效的。本方法支持手机,电脑,等设备玩耍。本文转自:XSY的FUN天地
2020年06月13日
1,229 阅读
0 评论
0 点赞
2020-06-12
给久坐族的10分钟运动指南
日积月累中,久坐的我们,身体也在悄悄发生变化。简单的小运动,专为久坐人群定制的运动计划,30秒简单拉伸,久坐不伤身,现在就学会。动起来吧( ,,´・ω・)ノ"(´っω・`。)
2020年06月12日
1,550 阅读
0 评论
1 点赞
2020-06-11
Font Awesome 图标字体使用教程
Font Awesome Font Awesome 是为 Twitter Bootstrap 设计的图标字体,通过Web Font的方式来显示一些图标,好处是图标可以被任意缩放、改变颜色,你需要做的只是像修改文字样式那样修改图标样式,现在非常多的网站还有博客都是使用的这套图标。 基本使用1.在站点的在head处引入官方的font-awesome.min.css<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> 2.其他博客或者网站就在你的header头部引入就可以了 3.Handsome主题直接在:设置外观-开发者设置-自定义输出header头部的HTML代码 4.引入完成,就去这个图标库里去找你想要的图标 图标库 然后复制下来这串代码,然后就可以把这个 i 标签放在任何位置。 5.举个栗子 比如我要在我博客右侧的统计信息评论前面加上这个图标,就找到这个部分的源码,然后找合适的位置粘贴进去就行,当然也可以直接在现有的class里去添加,在现有的class添加就只用 “fa fa-grav” 就可以了,如果要替换现有的图标直接在现有的class修改 进阶使用下面是一些参数使用方法,如放大,翻转,动态等,使用的时候直接在基础用法的后面加参数,详情请看代码部分 1.图标放大,为了增加图标大小相对于它们的容器,使用fa-lg(33%递增) fa-2x, fa-3x,fa-4x或fa-5x类。 fa-lg fa-2x fa-3x fa-4x fa-5x<i class="fa fa-camera-retro fa-lg"></i> fa-lg <i class="fa fa-camera-retro fa-2x"></i> fa-2x <i class="fa fa-camera-retro fa-3x"></i> fa-3x <i class="fa fa-camera-retro fa-4x"></i> fa-4x <i class="fa fa-camera-retro fa-5x"></i> fa-5x 2.旋转并翻转,若要对图标进行任意旋转和旋转,可以使用fa-rotate和fa-flip-类 normal fa-rotate-90 fa-rotate-180 fa-rotate-270 fa-flip-horizontal fa-flip-vertical<i class="fa fa-shield"></i> normal<br> <i class="fa fa-shield fa-rotate-90"></i> fa-rotate-90<br> <i class="fa fa-shield fa-rotate-180"></i> fa-rotate-180<br> <i class="fa fa-shield fa-rotate-270"></i> fa-rotate-270<br> <i class="fa fa-shield fa-flip-horizontal"></i> fa-flip-horizontal<br> <i class="fa fa-shield fa-flip-vertical"></i> fa-flip-vertical 3.组合图标,如果想要将多个图标组合起来,使用fa-stack类,作为父容器,fa-stack-1x作为正常比例的图标,fa-stack-2x作为大一些的图标。还可以使用fa-inverse类来切换图标颜色,在父容器中通过添加更大的图标类来控制整体大小。fa-twitter on fa-square-o fa-flag on fa-circle fa-terminal on fa-square fa-ban on fa-camera<span class="fa-stack fa-lg"> <i class="fa fa-square-o fa-stack-2x"></i> <i class="fa fa-twitter fa-stack-1x"></i> </span>fa-twitter on fa-square-o<br> <span class="fa-stack fa-lg"> <i class="fa fa-circle fa-stack-2x"></i> <i class="fa fa-flag fa-stack-1x fa-inverse"></i> </span>fa-flag on fa-circle<br> <span class="fa-stack fa-lg"> <i class="fa fa-square fa-stack-2x"></i> <i class="fa fa-terminal fa-stack-1x fa-inverse"></i> </span>fa-terminal on fa-square<br> <span class="fa-stack fa-lg"> <i class="fa fa-camera fa-stack-1x"></i> <i class="fa fa-ban fa-stack-2x text-danger"></i> </span>fa-ban on fa-camera 4.动态图标,先引入一个css动画,引入方式和上面一样。使用这个CSS动画来实现动态图标,使用fa-spin使任意图标种植旋转,可以还使用fa-pulse使其进行方位旋转<link rel="stylesheet" href="https://itggg.bj.bcebos.com/cdn/font-awesome-animation.min.css"> 旋转类Loading...Loading...Loading...Loading...Loading...<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i> <span class="sr-only">Loading...</span> <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i> <span class="sr-only">Loading...</span> <i class="fa fa-refresh fa-spin fa-3x fa-fw"></i> <span class="sr-only">Loading...</span> <i class="fa fa-cog fa-spin fa-3x fa-fw"></i> <span class="sr-only">Loading...</span> <i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i> <span class="sr-only">Loading...</span> 其他13种动画效果,序号请参照下方代码1. | 2. | 3. | 4. | 5. | 6. | 7.8. | 9. | 10.11. | 12. | 13.<i class="fa fa-wrench faa-wrench animated fa-3x"></i> <i class="fa fa-bell faa-ring animated fa-3x"></i> <i class="fa fa-envelope faa-horizontal animated fa-3x"></i> <i class="fa fa-thumbs-up faa-vertical animated fa-3x"></i> <i class="fa fa-exclamation-triangle faa-flash animated fa-3x"></i> <i class="fa fa-thumbs-up faa-bounce animated fa-3x"></i> <i class="fa fa-plane faa-float animated fa-3x"></i> <i class="fa fa-heart faa-pulse animated fa-3x"></i> <i class="fa fa-trophy faa-tada animated fa-3x"></i> <i class="fa fa-space-shuttle faa-passing animated fa-3x"></i> <i class="fa fa-space-shuttle faa-passing-reverse animated fa-3x"></i> <i class="fa fa-circle faa-burst animated fa-3x"></i> <i class="fa fa-star faa-falling animated fa-3x"></i> 鼠标点击动态,修改默认的动态参数 animated参数说明:animated 循环动态 animated-hover 鼠标移动到图标上动态 效果演示:移动鼠标到图标上 | <i class="fas fa-bell faa-ring animated-hover"></i> <i class="fas fa-spinner faa-spin animated-hover"></i> 怎么样?你学会了吗? 本文转自:Flat tire Blog
2020年06月11日
1,224 阅读
0 评论
0 点赞
1
...
22
23
24
...
33