大家好,我叫 Toby Pitman,Chris 让我写一篇关于我前段时间在论坛上发布的一项实验的文章。这一切都是从我浏览 WebKit 博客 开始的,我 看到一篇关于 新的 CSS3 动画的文章,其中最吸引我眼球的是“旋转”动画。我开始思考,在网页上你能旋转什么东西(这可是十倍于动画 GIF 的效果!)。然后我灵机一动 - 时钟的指针会旋转! bingo!
CSS3 transform: rotate
transform: rotate;
是 CSS 3 的一项新功能,它可以让你... 好吧,旋转东西。Transform 还可以让你缩放、倾斜和平移(移动)网页上的对象。所有这些都可以通过 Transition 属性进行动画化(包括缓动和持续时间)。
听起来很熟悉?这确实应该很熟悉,因为我们现在正在使用 jQuery 等框架来为网页上的元素添加动画。与 jQuery 一样,你可以使用 Transition 为几乎任何值得动画化的 CSS 属性添加动画。想想 :hover 效果,你应该就能得到一些想法。它远没有 jQuery 或 Mootools 等框架强大,但仍然可以实现一些很酷的效果。我敢肯定 John Resig 不会为此失眠的!
而且,它永远不会在 IE6 中起作用... 好的,我们开始吧!
图形
首先,我们需要一些图形来制作我们的时钟界面。我们有一个表盘和三根指针。所有活动部件都在 Photoshop 中以 600px 高度和 30px 宽度进行了切片,并且垂直居中,因为默认情况下,rotate 属性会从元素的中心“旋转”。如果你想设置旋转点,可以使用“transform-origin”。
我在这里使用了一个通用的时钟样式,但如果你喜欢,也可以选择使用米老鼠时钟。所有活动部件都是 PNG 图片,这使得这种效果成为可能。
HTML 标记
时钟的标记是一个简单的无序列表。每个列表项都包含一个活动部件,并赋予一个相关的 id。这里就是它。
<ul id="clock">
<li id="sec"></li>
<li id="hour"></li>
<li id="min"></li>
</ul>
注意: 论坛帖子 中的标记略显笨拙,因为它在指针上具有真实的投影。我已经为这个演示精简了一些代码,而论坛上的代码保持原样。
CSS
#clock {
position: relative;
width: 600px;
height: 600px;
margin: 20px auto 0 auto;
background: url(clockface.jpg);
list-style: none;
}
#sec, #min, #hour {
position: absolute;
width: 30px;
height: 600px;
top: 0px;
left: 285px;
}
#sec {
background: url(sechand.png);
z-index: 3;
}
#min {
background: url(minhand.png);
z-index: 2;
}
#hour {
background: url(hourhand.png);
z-index: 1;
}
CSS 也非常简单。由于活动部件具有相同的尺寸和起始位置,我们可以将它们一起声明,避免重复自己,使 CSS 更简洁。<ul>
被赋予了相对定位,允许我们在其中绝对定位时钟指针。
注意: 旋转不会影响布局,旋转后的对象会像一个绝对定位的元素一样,脱离正常文档流。
那么 CSS3 相关的内容在哪里呢?嗯,我们将使用一些简单的 jQuery 来应用它。
jQuery JavaScript
- 获取时钟的计时信息。
- 计算并注入每个元素的 CSS 样式(旋转角度)。
- 定期更新 CSS 样式信息。
需要注意的是,jQuery 在使用这些新的 CSS3 属性方面没有任何问题。此外,由于样式是动态分配的,而不是从样式表中分配的,因此此时钟仍然符合 CSS2.1 的验证标准!
获取时间
你们中有些人(我之前就是!),可能会将日期和时间信息与 PHP 等同起来,当我开始做这个项目时,PHP 是我的第一个想法,但后来我发现 JavaScript 也有自己的内置功能来获取日期和时间数据。请注意,在 JavaScript 中,时间是本地机器时间,而不是服务器时间。
我们将使用 Date() 语法来获取此信息,并将其分配给一个变量。我们可以通过将 GetSeconds()
、GetMinutes()
或 GetHours()
附加到 Date()
语法来获取每根指针的特定数据,例如以下示例。
var seconds = new Date().getSeconds();
上面的代码将返回一个介于 0 到 59 之间的数字,并将其存储在变量“seconds”中。
获取角度
接下来,我们要计算每根指针的角度。对于秒针和分针,它们每旋转一周有 60 个刻度,我们只需将 360 除以 60,得到 6。这意味着,对于每秒或每分钟,我们都需要将指针旋转 6 度。我们将把这个公式存储在另一个变量中。对于秒针,它将如下所示。
var sdegree = seconds * 6;
时针的场景有所不同。因为它每旋转一周有 12 个刻度,所以每个小时的角度是 30 度。即 360/12=30。现在,如果时钟的时针以小时为单位移动,那就简单了,但事实并非如此。它是根据分钟值以更小的幅度移动的。比如 4:30 时,时针将位于 3 和 4 之间的中间位置。那么我们该如何实现呢?以下是代码。
var hdegree = hours * 30 + (mins / 2);
基本上,我们将加上当前分钟数除以 2 的结果,这将得到一个介于 0.5 到 29.5 之间的数字(“rotate”可以处理所有浮点数),这将使指针位于任意给定的 30 度(小时)刻度之间。
示例
2.40 将是 | 2 * 30 | = | 60 度 | |
+ | 40 / 2 | = | 20 度 | |
——— | — | ———- | ||
hdegree | = | 80 度 |
我以为时钟在超过 12 时会爆炸,因为它会超过 360,但它运行正常。
所以现在我们已经弄清楚了数学运算,让我们注入新的 CSS。
设置样式
以下是用样式表表示的 CSS3 旋转。
#sec {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
以下是 jQuery 注入的代码(注意:从 jQuery 1.8 开始,在使用 .css() 函数时会自动应用正确的供应商前缀。旧版本的 jQuery 需要手动应用前缀)。
$("#sec").css({
"transform": "rotate(45deg)"
});
我们在这里遇到的问题是将变量“sdegree”(它保存我们的角度)放到这个语法中,以替换 (45deg)。起初,我只是尝试将变量放在括号之间,但它无法识别。为了使它起作用,我们需要在另一个名为“srotate”的变量中构建一个“字符串”,并完全替换第二个参数。以下是我们实现它的方法。
var srotate = "rotate(" + sdegree + "deg)";
现在 jQuery 将被写入为以下代码。
$("#sec").css({ "transform": srotate });
将所有内容组合在一起(及时!)
整个 jQuery 代码如下所示。
$(function() {
setInterval( function() {
var seconds = new Date().getSeconds();
var sdegree = seconds * 6;
var srotate = "rotate(" + sdegree + "deg)";
$("#sec").css({ "transform": srotate });
}, 1000 );
setInterval( function() {
var hours = new Date().getHours();
var mins = new Date().getMinutes();
var hdegree = hours * 30 + (mins / 2);
var hrotate = "rotate(" + hdegree + "deg)";
$("#hour").css({ "transform": hrotate});
}, 1000 );
setInterval( function() {
var mins = new Date().getMinutes();
var mdegree = mins * 6;
var mrotate = "rotate(" + mdegree + "deg)";
$("#min").css({ "transform" : mrotate });
}, 1000 );
});
请注意,我们使用了 JavaScript setInterval,因此该函数每秒钟运行一次。获取时间数据的变量必须位于函数内部,这样它们才能更新。否则,它们只会加载页面时获取一次数据,这将导致一个非常糟糕的时钟。
我们的时钟现在应该可以工作了(在 Safari 和其他现代浏览器中)。
其他方案
Flash 是最明显的选项,但如果你没有 ActionScript 技术,我建议你放弃它。这甚至可以通过 PHP 使用 GD 图像库来旋转指针来实现,但这对我来说太难了。
顺便说一下,Soh Tanaka 在几天后偶然发布了这个:CSS 时钟。他的时钟使用 JavaScript 添加类和精灵图像来表示指针。
**更新 2012 年 11 月:**Daniel Bakan 有一篇非常类似的文章,“如何为 iOS 设备编写全屏 Web 应用程序”,其中他也制作了一个老式时钟。如果你对此非常感兴趣,那也值得一看。
结论
所以这就是它了,朋友们,新的 CSS3 属性 transform:rotate 的一个真正的(也许是唯一的)实际应用。我个人迫不及待地想要看到上下颠倒和左右颠倒的网站(是的,你甚至可以旋转 HTML 标签!虽然 看看这对 Safari 的影响)以及我最喜欢的旋转/缩放漫画报纸博客帖子。
所以,继续吧,尝试一些新的 CSS3 功能!
很酷的技巧!
FYI,它在 Windows 版 Safari 中也能运行!=D
太棒了,我喜欢这个,一些 jQuery 和 CSS 的绝妙运用,真的很有帮助。
它在 Midori 上也能运行。基本上,它在所有基于 Webkit 的浏览器和即将推出的 Firefox 上都能运行。:)
http://code.google.com/p/jquery-rotate/
但是使用这个 jQuery 插件,可以使用这个脚本在更多浏览器上运行吗?
有可能吗?
很好,但很糟糕,因为它在 IE6 中无法运行。
但有很多东西在 IE 中无法运行。这只是其中之一。
感谢您的教程。
@moksha- 你读过这篇文章吗?这只能在 Safari 和 Chrome 中运行。它实际上并不打算在此时实用,只是一个有趣且创新的尝试。
很棒的文章,这很有趣。希望有更多 CSS3 的乐趣!
此致,
Drew
:) 它在 Firefox 中无法运行,我现在正在看 Safari。
这是一个真正的前沿技巧 :)
顺便说一下,它似乎也能在 Google 的 Chrome 浏览器中运行。
这真的很酷!我特别喜欢旋转 HTML 标签的屏幕截图。酷!
感谢您提供的精彩教程。
做得好,Chris。每个人都可以通过这个例子简单地学习关于 CSS 和 jQuery 的一切。
这是一个很酷的技巧。天哪,现在有这么多浏览器,这真是让人害怕。
这很酷。谢谢。
很好的例子,很有趣。
只是想问一个问题!
为什么普通的 CSS 表达式不起作用?我的意思是,如果我们想动画化……“这个”,“属性”似乎有点奇怪。
无论如何,谢谢!
很棒的工作,但在 IE 11 中它不起作用。我使用以下更改,然后它在 IE 11 中运行良好。
$("#sec").css({ "-moz-transform": srotate, "-webkit-transform": srotate, "transform": srotate });
$("#min").css({ "-moz-transform": mrotate, "-webkit-transform": mrotate, "transform": mrotate });
$("#hour").css({ "-moz-transform": hrotate, "-webkit-transform": hrotate, "transform": hrotate });