迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
背景在日语学习初期阶段,我发现日语五十音的记忆并不是很容易的,片假名的记忆尤其令人费神。这时我想如果有一个应用可以充分利用碎片时间,在午休或地铁上随时可以练习五十音该多好。于是搜索 实现在线体验地址 https://dragonir.github.io/kanaApp/ 实现效果如下,该应用主要分为三个页面:
答题逻辑规则是从给出的 深色模式 随着
若结果为 下面例子中,当系统主题色为深色时 @media (prefers-color-scheme: dark) { .demo { background: #FFFFFF; } } @media (prefers-color-scheme: light) { .demo { background: #000000; } }
使用 if (window.matchMedia('(prefers-color-scheme)').media === 'not all') { // 浏览器不支持主题色设置 } if (window.matchMedia('(prefers-color-scheme: dark)').matches){ // 深色模式 } else { // 浅色模式 } 另外还可以动态监听系统深色模式的状态,根据系统深色模式的切换做出实时响应: window.matchMedia('(prefers-color-scheme: dark)').addListener(e => { if (e.matches) { // 开启深色模式 } else { // 关闭深色模式 } }); 或者单独检测深色或浅色模式: const listeners = { dark: (mediaQueryList) => { if (mediaQueryList.matches) { // 开启深色模式 } }, light: (mediaQueryList) => { if (mediaQueryList.matches) { // 开启浅色模式 } } }; window.matchMedia('(prefers-color-scheme: dark)').addListener(listeners.dark); window.matchMedia('(prefers-color-scheme: light)').addListener(listeners.light); 在50音小游戏中,就是使用
页面使用图片元素时,可以直接在 <picture> <source srcset="dark.jpg" media="(prefers-color-scheme: dark)"> <img src="light.jpg"> </picture>
注意: 离线缓存为了能够像原生应用一样可以在桌面生成快捷方式快速访问,随时随地离线使用,
特点:
配置页面参数在项目根目录添加文件 // manifest.webmainifest { "name": "かなゲーム", "short_name": "かなゲーム", "start_url": "index.html", "display": "standalone", "background_color": "#fff", "description": "かなゲーム", "icons": [ { "src": "assets/images/icon-64x64.jpg", "sizes": "64x64", "type": "image/jpg" }, { "src": "assets/images/icon-256x256.jpg", "sizes": "256x256", "type": "image/jpg" } ] } 参数说明:
需要说明的是,当一些系统的浏览器不支持
配置信息自动生成工具:https://tomitm.github.io/appmanifest/ 配置 在 <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-title" content="かなゲーム"> <link rel="stylesheet" type="text/css" href="./assets/css/main.css" rel="external nofollow" > <link rel="stylesheet" type="text/css" href="./assets/css/dark.css" rel="external nofollow" > <link rel="stylesheet" type="text/css" href="./assets/css/petals.css" rel="external nofollow" > <link rel="shortcut icon" href="./assets/images/icon-256x256.jpg" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > <link rel="apple-touch-icon" href="./assets/images/icon-256x256.jpg" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" /> <link rel="apple-touch-icon-precomposed" href="./assets/images/icon-256x256.jpg" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" > <link rel="Bookmark" href="./assets/images/icon-256x256.jpg" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" /> <link rel="manifest" href="./manifest.webmanifest" rel="external nofollow" > <title>かなゲーム</title>
注册使用 在 window.addEventListener('load', () => { registerSW(); }); async function registerSW() { if ('serviceWorker' in navigator) { try { await navigator.serviceWorker.register('./sw.js'); } catch (e) { console.log(`SW registration failed`); } } } 使用
在根目录添加 // 定义缓存的key值 const cacheName = 'kana-v1'; // 定义需要缓存的文件 const staticAssets = [ './', './index.html', './assets/css/main.css', './assets/js/main.js', './assets/images/bg.jpg' // ... ]; // 监听install事件,安装完成后,进行文件缓存 self.addEventListener('install', async e => { // 找到key对应的缓存并且获得可以操作的cache对象 const cache = await caches.open(cacheName); // 将需要缓存的文件加进来 await cache.addAll(staticAssets); return self.skipWaiting(); }); // 监听activate事件来更新缓存数据 self.addEventListener('activate', e => { // 保证第一次加载fetch触发 self.clients.claim(); }); // 监听fetch事件来使用缓存数据: self.addEventListener('fetch', async e => { const req = e.request; const url = new URL(req.url); if (url.origin === location.origin) { e.respondWith(cacheFirst(req)); } else { e.respondWith(networkAndCache(req)); } }); async function cacheFirst(req) { // 判断当前请求是否需要缓存 const cache = await caches.open(cacheName); const cached = await cache.match(req); // 有缓存就用缓存,没有就从新发请求获取 return cached || fetch(req); } async function networkAndCache(req) { const cache = await caches.open(cacheName); try { // 缓存报错还直接从新发请求获取 const fresh = await fetch(req); await cache.put(req, fresh.clone()); return fresh; } catch (e) { const cached = await cache.match(req); return cached; } } 在
**
注:使用 至此,当已安装的 更多 实现效果: PC端 🖥️:
移动端 📱: 樱花飘落动画 为增强视觉效果和趣味性,于是在页面增加了樱花
基本语法:
参数:
以下代码为本例中的具体实现, <div id="petals_container"> <div class="petal"></div> <!-- ... --> <div class="petal"></div> </div> var petalPlayers = []; function animatePetals() { var petals = document.querySelectorAll('.petal'); if (!petals[0].animate) { var petalsContainer = document.getElementById('petals_container'); return false; } for (var i = 0, len = petals.length; i < len; ++i) { var petal = petals[i]; petal.innerHTML = '<div class="rotate"><img src="petal.jpg" class="askew"></div>'; var scale = Math.random() * .6 + .2; var player = petal.animate([{ transform: 'translate3d(' + (i / len * 100) + 'vw,0,0) scale(' + scale + ')', opacity: scale }, { transform: 'translate3d(' + (i / len * 100 + 10) + 'vw,150vh,0) scale(' + scale + ')', opacity: 1 } ], { duration: Math.random() * 90000 + 8000, iterations: Infinity, delay: -(Math.random() * 5000) }); petalPlayers.push(player); } } animatePetals(); .petal .rotate { animation: driftyRotate 1s infinite both ease-in-out; perspective: 1000; } .petal .askew { transform: skewY(10deg); display: block; animation: drifty 1s infinite alternate both ease-in-out; perspective: 1000; } .petal:nth-of-type(7n) .askew { animation-delay: -.6s; animation-duration: 2.25s; } .petal:nth-of-type(7n + 1) .askew { animation-delay: -.879s; animation-duration: 3.5s; } /* ... */ .petal:nth-of-type(9n) .rotate { animation-duration: 2s; } .petal:nth-of-type(9n + 1) .rotate { animation-duration: 2.3s; } /* ... */ @keyframes drifty { 0% { transform: skewY(10deg) translate3d(-250%, 0, 0); display: block; } 100% { transform: skewY(-12deg) translate3d(250%, 0, 0); display: block; } } @keyframes driftyRotate { 0% { transform: rotateX(0); display: block; } 100% { transform: rotateX(359deg); display: block; } } 完整代码可查看文后链接
本例
/* 最小宽高比 */ @media (min-aspect-ratio: 8/5) { // ... } /* 最大宽高比 */ @media (max-aspect-ratio: 3/2) { // ... } /* 明确的宽高比, 放在最下部防止同时满足条件时的覆盖 */ @media (aspect-ratio: 1/1) { // ... } 在应用中的具体实现方式是添加一个 <div class="mod_orient_layer"></div> .mod_orient_layer { display: none; position: fixed; height: 100%; width: 100%; left: 0; top: 0; right: 0; bottom: 0; z-index: 999; background: #FFFFFF url('landscape.jpg') no-repeat center; background-size: auto 100%; } @media screen and (min-aspect-ratio: 13/8) { .mod_orient_layer { display: block; } } 实现效果: 兼容性下面是本文中涉及的几个属性的兼容性视图,在实际生产项目中需要注意兼容性适配。 Photoshop 技能logo设计
外部链接及参考资料 樱花散落动画完整版 https://codepen.io/dragonir/full/WNjEPwW Dark Mode Support in WebKit https://webkit.org/blog/8840/dark-mode-support-in-webkit PWA技术理论+实战全解析 https://www.cnblogs.com/yangyangxxb/p/9964959.html H5 PWA技术 https://zhuanlan.zhihu.com/p/144512343 aspect-ratio https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media/aspect-ratio Service Worker https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API Element.animate() https://developer.mozilla.org/zh-CN/docs/Web/API/Element/animate 作者:dragonir 博客地址:https://www.cnblogs.com/dragonir/p/15041977.html 到此这篇关于五十音小游戏中的前端知识的文章就介绍到这了,更多相关前端知识小游戏内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论