diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6347583 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.html linguist-language=javascript diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000..5834ef8 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,12 @@ +Title: 标号-题目-类型 问题简述 + +例子: + +``` +11 - Custom Video Player - readme: LocalStorage 補充 +11 - Custom Video Player - js: const 写法错误 +``` + +说明中最好提供问题所在的具体位置链接,链接获取方法: +1. Markdown 文档下,鼠标移动至你有问题的小标题,点击其左侧的链接图标,复制地址栏的地址即可。如:https://github.com/soyaine/JavaScript30/tree/master/11%20-%20Custom%20Video%20Player#图标切换 +2. 代码文档下,点击某一行左侧标号,复制地址栏地址即可,如 https://github.com/soyaine/JavaScript30/blob/master/11%20-%20Custom%20Video%20Player/index.html#L20 diff --git a/01 - JavaScript Drum Kit/README.md b/01 - JavaScript Drum Kit/README.md index 7fe38a8..1b02d30 100644 --- a/01 - JavaScript Drum Kit/README.md +++ b/01 - JavaScript Drum Kit/README.md @@ -1,6 +1,6 @@ -# 01 JavaScript Dump Kit 中文指南 +# 01 JavaScript Drum Kit 中文指南 -> 作者:©[缉熙Soyaine](https://github.com/soyaine) +> 作者:©[未枝丫](https://github.com/soyaine) > 简介:[JavaScript30](https://javascript30.com) 是 [Wes Bos](https://github.com/wesbos) 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 1 篇。完整指南在 [GitHub](https://github.com/soyaine/JavaScript30),喜欢请 Star 哦♪(^∇^*) ## 实现效果 @@ -92,7 +92,7 @@ audio.play(); ### 如何使页面按钮恢复原状? -利用一个叫 [`transitionened`](https://developer.mozilla.org/zh-CN/docs/Web/Events/transitionend) 的事件,它在 CSS transition 结束后会被触发。我们就可以利用这个事件,在每次打鼓的效果(尺寸变大、颜色变化)完成之后,去除相应样式。 +利用一个叫 [`transitionend`](https://developer.mozilla.org/zh-CN/docs/Web/Events/transitionend) 的事件,它在 CSS transition 结束后会被触发。我们就可以利用这个事件,在每次打鼓的效果(尺寸变大、颜色变化)完成之后,去除相应样式。 在这个页面中,发生 `transition` 的样式属性不止一个(`box-shadow`, `transform`, `border-color`),所以需要添加一个判断语句,使每发生一次按键事件时,只去除一次样式。 @@ -102,4 +102,4 @@ funciton remove(event) { this.classList.remove('playing'); // event.target.classList.remove('playing'); } -```` \ No newline at end of file +```` diff --git a/01 - JavaScript Drum Kit/index-draft.html b/01 - JavaScript Drum Kit/index-draft.html index 1e4bfab..903fcc3 100644 --- a/01 - JavaScript Drum Kit/index-draft.html +++ b/01 - JavaScript Drum Kit/index-draft.html @@ -69,7 +69,7 @@ } function removeTransition(e) { - if(e.propertyName != 'border-left-color') return; + if(e.propertyName !== 'border-left-color') return; this.classList.remove('playing'); } @@ -85,31 +85,30 @@ const keyCode = event.key; if ( keyCode === '76') { - alert("76"); + alert('76'); } else { - alert("false"); + alert('false'); } } - window.addEventListener("keydown", function(e){ + window.addEventListener('keydown', function(e){ const audio = document.querySelector(`audio[data-key="${ e.keyCode }"]`); const key = document.querySelector(`div[data-key="${ e.keyCode }"]`); -// console.log(video); -// console.log(key); + console.log(video); + console.log(key); if(!audio) return; audio.currentTime = 0; audio.play(); - key.classList.add("playing"); -// key.classList.remove("playing"); + key.classList.add('playing'); + // key.classList.remove("playing"); }, false); function removeTransition(e){ -// if(e.propertyName !== "border-left-color") return; + // if(e.propertyName !== "border-left-color") return; console.log(e.propertyName); -// e.target.classList.remove("playing"); + // e.target.classList.remove("playing"); } - const keys = document.querySelectorAll('.key'); keys.forEach( keyin => keyin.addEventListener('transitionend', removeTransition)); diff --git a/02 - JS + CSS Clock/README.md b/02 - JS + CSS Clock/README.md index fa56a74..0ca0415 100644 --- a/02 - JS + CSS Clock/README.md +++ b/02 - JS + CSS Clock/README.md @@ -1,8 +1,11 @@ # 02 纯 JS、CSS 时钟 中文指南 -> 作者:©[缉熙Soyaine](https://github.com/soyaine) +> 作者:©[未枝丫](https://github.com/soyaine) > 简介:[JavaScript30](https://javascript30.com) 是 [Wes Bos](https://github.com/wesbos) 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 2 篇。完整指南在 [GitHub](https://github.com/soyaine/JavaScript30),喜欢请 Star 哦♪(^∇^*) +> 创建时间:2016年12月21日 +最后更新:2017年01月06日 + ## 实现效果  @@ -18,7 +21,7 @@ 3. 每一秒改变一次指针状态 **涉及到的特性:** -- `transform-oragin` +- `transform-origin` - `transform: rotate()` - `transition` - `transition-timing-function: cubic-bezier(x, x, x, x)` @@ -30,10 +33,10 @@ ### CSS 部分 1. 调整指针的初始位置以及旋转的轴点 - [transform-oragin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin) + [transform-origin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin) ```css - transform-oragin: 100%; // 或者可以用 right + transform-origin: 100%; // 或者可以用 right ``` 2. 调整时钟指针跳动时的过渡效果 @@ -101,5 +104,58 @@ ``` 4. 将角度值赋值给 HTML 元素的 `style` 中的 `transform` 属性 + +## 延伸思考 + +> 2017年01月06日 更新完善,感谢 [@cody1991 提的 issue](https://github.com/soyaine/JavaScript30/issues/1) + +此处存在一个小瑕疵,当秒针旋转一圈之后回到初始位置,开始第二圈旋转,角度值的变化时 444° → 90° → 96° .... 这个过程中,指针会先逆时针从 444° 旋转至 90°,再继续我们期望的顺时针旋转,由于秒针变换时间只有 0.05s,所以呈现的效果就是秒针闪了一下,如果想要观察细节,可以将 `.second` 设为 `transition: all 1s`。要解决这个问题,目前找到了两种解决办法: + +#### 方法一 + +在这个特殊点将指针的 `transition` 属性去掉,由于距离短、时间短,将逆时针回旋的过程瞬间完成。 + +```js +if (secondDeg === 90) secHand.style.transition = 'all 0s'; +else secHand.style.transition = 'all 0.05s'; + +if (minDeg === 90) minHand.style.transition = 'all 0s'; +else minHand.style.transition = 'all 0.1s'; +``` + +#### 方法二 + +既然引发问题的是角度的大小变化,那就可以对这个值进行处理。此前的代码中,每秒都会重新 new 一个 Date 对象,用来计算角度值,但如果让这个角度值一直保持增长,也就不会出现逆时针回旋的问题了。 + +这是 @cody1991 提供的思路。只在页面第一次加载时 new 一次 Date 对象,此后每秒直接更新角度值。 + +```js +let secondDeg = 0, +minDeg = 0, +hourDeg = 0; + +function initDate() { + const date = new Date(); + const second = date.getSeconds(); + secondDeg = 90 + (second / 60) * 360; + const min = date.getMinutes(); + minDeg = 90 + (min / 60) * 360 + ((second / 60) / 60) * 360; + const hour = date.getHours(); + hourDeg = 90 + (hour / 12) * 360 + ((min / 60) / 12) * 360 + (((second / 60) / 60) / 12) * 360; +} + +function updateDate() { + secondDeg += (1 / 60) * 360; + minDeg += ((1 / 60) / 60) * 360; + hourDeg += (((1 / 60) / 60) / 12); -大功告成! \ No newline at end of file + secHand.style.transform = `rotate(${ secondDeg}deg)`; + minHand.style.transform = `rotate(${ minDeg }deg)`; + hourHand.style.transform = `rotate(${ hourDeg }deg)`; +} + +initDate(); +setInterval(updateDate, 1000); +``` + +问题解决。大功告成! \ No newline at end of file diff --git a/02 - JS + CSS Clock/index-SOYAINE.html b/02 - JS + CSS Clock/index-SOYAINE.html index d7539e4..af02706 100644 --- a/02 - JS + CSS Clock/index-SOYAINE.html +++ b/02 - JS + CSS Clock/index-SOYAINE.html @@ -53,7 +53,8 @@ position: relative; width: 100%; height: 100%; - transform: translateY(-3px); /* account for the height of the clock hands */ + /* transform: translateY(-3px); /* account for the height of the clock hands */ + /* canceled according to https://github.com/soyaine/JavaScript30/issues/55 */ } .hand { @@ -87,8 +88,6 @@ 0 0 0 2px rgba(0,0,0,0.1), 0 0 10px rgba(0,0,0,0.2); transform: translate(-50%, -50%); - /*transition: all .05s;*/ - } .hour-hand { @@ -104,7 +103,7 @@ width: 45%; height:5px; margin-top: -2.5px; - transition: all .1s; + transition: all .1s cubic-bezier(0.9, 0.54, 0.26, 1.68); } .second-hand { @@ -112,7 +111,7 @@ margin-top: -1px; border-bottom-left-radius: 100%; border-top-left-radius: 100%; - transition: all .05s; + transition: all .05s cubic-bezier(0.9, 0.54, 0.26, 1.68); background-color: red; } @@ -124,28 +123,76 @@ const secHand = document.querySelector('.second-hand'); const minHand = document.querySelector('.min-hand'); const hourHand = document.querySelector('.hour-hand'); - + function setDate() { const date = new Date(); - + const second = date.getSeconds(); - const secondDeg = (90 + (second / 60) * 360) % 360; + const secondDeg = (90 + (second / 60) * 360); const min = date.getMinutes(); - const minDeg = (90 + (min / 60) * 360) % 360; + const minDeg = (90 + (min / 60) * 360); const hour = date.getHours(); const hourDeg = (90 + (hour / 12) * 360 + (min / 12 / 60) * 360);// 加入分钟所占的时间,使时针可以缓慢地移动 + +// 解决指针跳顿问题【第一种方法】 +// 在发生跳顿的角度值处,将 CSS 的 `transition` 属性去掉 + if (secondDeg === 90) secHand.style.transition = 'all 0s'; + else secHand.style.transition = 'all 0.05s cubic-bezier(0.9, 0.54, 0.26, 1.68)'; + + if (minDeg === 90) minHand.style.transition = 'all 0s'; + else minHand.style.transition = 'all 0.1s cubic-bezier(0.9, 0.54, 0.26, 1.68)'; + +// 时针间距过大不做处理 +// if (hourDeg === 116.5) hourHand.style.transition = 'all 0s'; +// else hourHand.style.transition = 'all 3s'; + secHand.style.transform = `rotate(${ secondDeg }deg)`; minHand.style.transform = `rotate(${ minDeg }deg)`; hourHand.style.transform = `rotate(${ hourDeg }deg)`; -// console.log(`${hour}:${min}:${second} - ${hourDeg}:${minDeg}:${secondDeg}` ); + console.log(`${hour}:${min}:${second} - ${hourDeg}:${minDeg}:${secondDeg}` ); } // setDate(); setInterval(setDate, 1000); + +