原文链接:http://www.zuojj.com/archives/1292.html,转自Benjamin-专注前端开发和用户体验

相关概念:绘制频率、屏幕刷新频率、硬件加速、60fps

绘制频率:
页面上每一帧变化都是系统绘制出来的(GPU或者CPU)【参考浏览器渲染原理】。但这种绘制又和PC游戏的绘制不同,它的最高绘制频率受限于显示器的刷新频率(而非显卡),所以大多数情况下最高的绘制频率只能是每秒60帧(frame per second,以下用fps简称),对应于显示器的60Hz。60fps是一个最理想的状态,在日常对页面性能的测试中,60fps也是一个重要的指标,the closer the better。

刷新频率:
图像在屏幕上更新的速度,也即屏幕上的图像每秒钟出现的次数,它的单位是赫兹(Hz)。刷新频率越高,屏幕上图像闪烁感就越小,稳定性也就越高,换言之对视力的保护也越好。一般人的眼睛、不容易察觉75Hz以上刷新频率带来的闪烁感,因此最好能将您显示卡刷新频率调到75Hz以上。要注意的是,并不是所有的显示卡都能够在最大分辨率下达到70Hz以上的刷新频率(这个性能取决于显示卡上RAMDAC的速度),而且显示器也可能因为带宽不够而不能达到要求。影响刷新率最主要的还是显示器的带宽。

显示器带宽是显示器视频放大器通频带宽度的简称,指电子枪每秒钟在屏幕上扫过的最大总像素数,以MHz(兆赫兹)为单位。 带宽的值越大,显示器性能越好。

硬件加速:
硬件有三个处理器,CPU、GPU和APU(不是加速处理器是声音处理器)。他们通过PCI/AGP/PCIE总线交换数据。今天,GPU已经不再局限于3D图形处理了,GPU通用计算技术发展已经引起业界不少的关注,事实也证明在浮点运算、并行计算等部分计算方面,GPU可以提供数十倍乃至于上百倍于CPU的性能。

60Hz和60fps是什么关系
没有任何关系。fps代表GPU渲染画面的频率,Hz代表显示器刷新屏幕的频率。一幅静态图片,你可以说这副图片的fps是0帧/秒,但绝对不能说此时屏幕的刷新率是0Hz,也就是说刷新率不随图像内容的变化而变化。游戏也好浏览器也好,我们谈到掉帧,是指GPU渲染画面频率降低。比如跌落到30fps甚至20fps,但因为视觉暂留原理,我们看到的画面仍然是运动和连贯的。

PS: 以下示例在Chrome环境中运行
一、CSS动画
1.1 Transitions动画

实例:
01<style type="text/css">
02.animate {
03width: 200px;
04height: 200px;
05margin: 0 auto;
06border-radius: 50%;
07background-color: #f00;
08line-height: 200px;
09border-radius: 50%;
10text-align: center;
11color: #fff;
12font-size: 20px;
13}
14.animate-transition {
15transition         : transform 2s linear;
16-moz-transition    : -moz-transform 2s linear;
17-webkit-transition : -webkit-transform 2s linear;
18-o-transition      : -o-transform 2s linear;
19}
2021.animate-transition:hover {
22cursor: pointer;
23transform         : rotate(360deg);
24-moz-transform    : rotate(360deg);
25-webkit-transform : rotate(360deg);
26-o-transform      : rotate(360deg);
27}
28</style>
29<div class="animate animate-transition">Transition Animation</div>查看实例演示
1.2 Keyframes animationKeyframes animation通过定义多个关键帧以及定义每个关键帧中的元素的属性值来实现更为复杂的动画效果。
实例:
01<style type="text/css">
02.animate-keyframes {
03-webkit-animation: frames 2s linear infinite;
04}
0506.animate-keyframes:hover {
07cursor: pointer;
08-webkit-animation: none;
09}
1011@-webkit-keyframes frames {
120% {
13background-color: #f00;
14-webkit-transform: rotate(0deg);
15}
16100% {
17background-color: #f00;
18-webkit-transform: rotate(360deg);
19}
20}
21</style>
22<div class="animate animate-keyframes">keyframes animation</div>查看实例演示
1.3 CSS动画优缺点优点:
简单、高效
声明式的
不依赖与主线程,采用硬件加速(GPU)
简单的控制keyframe animation 播放和暂停缺点:
不能动态的修改或定义动画内容
不同的动画无法实现同步
多个动画彼此无法堆叠另:
1) CSS3 transition强制硬件加速会加大GPU消耗,高负荷情形下将导致运行不流畅。这种情况在移动设备上尤为明显。(特殊情况下,比如当数据在浏览器主线程和排版线程之间传递产生的瓶颈也会导致不流畅)。某些CSS属性,比如transform和opacity,则不受这些瓶颈影响。Adobe在这里精心总结了这些问题。详细请戳transition的兼容性问题是个诟病,IE10+及现代浏览器,使用起来会造成很多不便。由于transition并不是由JavaScript原生控制(而仅仅是由JavaScript触发),浏览器无法获知如何与控制这些transition的JavaScript代码同步地优化他们。2) keyframes animation 的动画曲线会应用到所有变化的属性上,而且手写比较复杂的动画,写起来就是噩梦。
二、SVG动画
2.1 实例
01<div class="animate-svg">
02<svg id="svgAnimation" ns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200">
03<g transform="translate(100,100)">
04<g>
0506<rect width="200" height="200" rx="100" ry="100" fill="red" transform="translate(-100,-100)"></rect>
07<text x="-60" y="-0" font-size="20" fill="white" >SVG Animation</text>
08<!-- Add ease-in-out and infinite iterations to this animation and the code -->
09<animateTransform attributeName="transform" attributeType="xml" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite">SVG Animation</animateTransform>
10</g>
11</g>
12</svg>
13</div>查看实例演示
2.2 SVG动画优缺点优点:
1) 矢量图形,不受像素影响——SVG的这个特性使得它在不同的平台或者媒体下表现良好,无论屏幕分辨率如何
2) SVG对动画的支持较好,其DOM结构可以被其特定语法或者Javascript控制,从而轻松的实现动画
3) Javascript可以完全控制SVG Dom 元素
4) SVG的结构是XML,其可访问性(盲文、声音朗读等)、可操作性、可编程性、可被CSS样式化完胜Canvas。另外,其支持 ARIA 属性,使其如虎添翼。缺点:
1) DOM比正常的图形慢,而且如果其结点多而杂,就更慢。
2) SVG 画点报表什么的,还行;在网页游戏前,就束手无策了;当然可以结合 Canvas + SVG实现。
3) 不能动态的修改动画内容
4) 不能与HTML内容集成
5) 整个SVG作为一个动画
6) 浏览器兼容性问题,IE8-以及Android 2.3默认浏览器是不支持SVG
三、Javascript动画
3.1 jQuery动画jQuery动画使用setInterval实现:
01// 用例
02$("#div").animate({});
0304// 源码
05jQuery.fx.timer = function( timer ) {
06if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
07timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
08}
09};
1011jQuery.fx.interval = 13;jQuery的动画帧宽为什么是13ms呢
How to determine the best “framerate” (setInterval delay) to use in a JavaScript animation loop?
为什么jQuery用setInterval而不用RAF?优点:
易用,低效,兼容好;缺点:
1) setInterval多个间隔可能会被跳过
2) setInterval多个间隔可能比预期小
3) 不同浏览器的精度量级不同:
4) jQuery 无法解决频繁触发 Layout 导致的抽动。
3.2 requestAnimationFrame实例:
01<style type="text/css">
02.animate-RAF {
0304}
0506.animate-input  {
07margin-top: 10px;
08text-align: center;
09}
10</style>
1112<div id="animate-RAF" class="animate animate-RAF">RAF Animation</div>
13<div class="animate-input"><input type="button" id="btn_start" value="Start" style="width:100px;height:30px"></div>
1415<script type="text/javascript">
16var animate_raf   = document.getElementById("animate-RAF"),
17btn_start = document.getElementById("btn_start"),
18frameid   = null;
1920function frame(time) {
21animate_raf.style['-webkit-transform'] = 'rotate('+ Math.cos(time/1000)*360 +'deg)';
22frameid = requestAnimationFrame(frame);
23}
2425// bind Event
26btn_start.addEventListener("click", function(event) {
27var val = this.value;
2829if(val === "Start") {
30frameid = requestAnimationFrame(frame);
31this.value = "Pause";
32}else {
33this.value = "Start";
34cancelAnimationFrame(frameid);
35}
36}, false);
3738</script>查看实例演示
优点:
1) 在每次浏览器更新页面时,能获取通知并执行应用。 简单理解为,RAF能在每个16.7ms间执行一次咱们的函数,不多不少。
2) 最小化的消耗资源,RAF在页面被切换或浏览器最小化时,会暂停执行,等页面再次关注时,继续执行动画。
3) 相比 CSS 动画有更好的掌控,能合理降低CPU的使用。缺点:
1) 无法控制执行时间,执行时间由系统根据屏幕刷新时间决定
2) 浏览器兼容性问题,IE10+及现代浏览器,低版本浏览器建议降级处理,使用setInterval或setTimeout
3.3 Canvas优点:
1) 画2D图形时,页面渲染性能比较高
2) 页面渲染性能受图形复杂度影响小
3) 渲染性能只受图形的分辨率的影响
4) 画出来的图形可以直接保存为 .png 或者 .jpg的图形
5) 最适合于画光栅图像(如游戏和不规则几何图形等),编辑图片还有其他基于像素的图形操作。缺点:
1) 整个就是一张图,无论你往上画什么东西——没有DOM 结点可供操作
2) 没有实现动画的API,你必须依靠定时器和其他事件来更新Canvas
3) 对文本的渲染支持是比较差
4) 对要求有高可访问性(盲文、声音朗读等)页面,比较困难
5) 对交互要求高的(比如TIBCO的很多产品)的界面,不建议使用Canvas
3.4 WebGLWebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。浏览器支持:
Internet Explorer 11+
Google Chrome 9+
Firefox 4+
Opera 12+
Safari 5.1+
3.5 Problems1) 不同的api有不同的模型动画
2) 不必要的维护来支持多种方式实现同样的事情
3) Web开发人员需要学习多种实现技术
4) Javascript不容易设置声明式动画
四、Flash动画(过时)
五、Web Animations 1.0 ——A new general purpose animation model1) W3Web Animations 1.0
2) JavaScript implementation of the Web Animations APIWeb Animations API为CSS和SVG动画提供了单一接口。旨在通过提供更好的性能、更好的控制时间线和播放、灵活、统一的Javascript编程接口,使做一些事情更容易。当前状态:
Specification at First Public Working Draft: www.w3.org/TR/web-animations
Chrome:
CSS Transitions & Animations rewritten on top of the Web Animations model
JavaScript API in development behind a flag
Firefox & Safari: Started implementation
IE: No public signals实例一:A simple example
01var web_animation_1 = document.getElementById("web_animation_1");
0203web_animation_1.addEventListener('click', function() {
04web_animation_1.animate([{
05transform: 'rotate(0deg)'
06}, {
07transform: 'rotate(360deg)'
08}],{
09duration: 2
10});
11}, false);查看实例演示
实例二:More complex timing
01var web_animation_2 = document.getElementById("web_animation_2");
0203web_animation_2.addEventListener('click', function() {
04web_animation_2.animate([{
05transform: 'rotate(0deg)'
06}, {
07transform: 'rotate(360deg)'
08}],{
09direction: 'alternate',
10duration: 1,
11iterations: Infinity,
12easing: 'ease-in-out',
13playbackRate: 2
14});
15}, false);查看实例演示
实例三:Without the syntactic sugar
01var web_animation_3 = document.getElementById("web_animation_3");
0203web_animation_3.addEventListener('click', function() {
04var obj = new Animation(web_animation_3,[{
05transform: 'rotate(0deg)'
06}, {
07transform: 'rotate(360deg)'
08}],{
09duration: 2
10});
11document.timeline.play(obj);
12}, false);查看实例演示
实例四:Parallel animation grouping
01var web_animation_4 = document.getElementById("web_animation_4"),
02parItem1 = document.getElementById("parItem1"),
03parItem2 = document.getElementById("parItem2"),
04parItem3 = document.getElementById("parItem3");
0506web_animation_4.addEventListener('click', function() {
07var obj = new ParGroup([
08new Animation(parItem1, [{width: '0px'}, {width: '500px'}], 1),
09new Animation(parItem2, [{width: '0px'}, {width: '700px'}], 1),
10new Animation(parItem3, [{width: '0px'}, {width: '200px'}], 1),
11])
12document.timeline.play(obj);
13}, false);查看实例演示
实例五:Sequential animation grouping
01var web_animation_5 = document.getElementById("web_animation_5"),
02seqItem1 = document.getElementById("seqItem1"),
03seqItem2 = document.getElementById("seqItem2"),
04seqItem3 = document.getElementById("seqItem3");
0506web_animation_5.addEventListener('click', function() {
07var obj = new SeqGroup([
08new Animation(seqItem1, [{width: '0px'}, {width: '200px'}], 1),
09new Animation(seqItem2, [{width: '0px'}, {width: '300px'}], 1),
10new Animation(seqItem3, [{width: '0px'}, {width: '200px'}], 1),
11])
12document.timeline.play(obj);
13}, false);查看实例演示
实例六:Nested grouped animations
01var web_animation_6 = document.getElementById("web_animation_6"),
02outerSeqItem1 = document.getElementById("outerSeqItem1"),
03outerSeqItem2 = document.getElementById("outerSeqItem2"),
04innerParItem1 = document.getElementById("innerParItem1"),
05innerParItem2 = document.getElementById("innerParItem2"),
06innerParItem3 = document.getElementById("innerParItem3");
0708web_animation_6.addEventListener('click', function() {
09var parobj = new ParGroup([
10new Animation(innerParItem1, [{width: '0px'}, {width: '300px'}], 1),
11new Animation(innerParItem2, [{width: '0px'}, {width: '300px'}], 1),
12new Animation(innerParItem3, [{width: '0px'}, {width: '300px'}], 1),
13]);
14var seqobj = new SeqGroup([
15new Animation(outerSeqItem1, [{width: '0px'}, {width: '200px'}], 1),
16parobj,
17new Animation(outerSeqItem2, [{width: '0px'}, {width: '200px'}], 1),
18]);
19document.timeline.play(seqobj);
20}, false);查看实例演示
实例七:Path animations
01var web_animation_7 = document.getElementById("web_animation_7");
0203web_animation_7.addEventListener('click', function() {
04var obj = new Animation(web_animation_7,
05new PathAnimationEffect(
06'M 100 200 ' +
07'C 200 100 300   0 400 100 ' +
08'C 500 200 600 300 700 200 ' +
09'C 800 100 900 100 900 100', 'auto-rotate'), {
10duration: 2,
11direction: 'alternate',
12easing: 'ease-in-out',
13iterations: Infinity,
14});
1516document.timeline.play(obj);
17}, false);查看实例演示
实例八:Custom animation effects
01function customAnimationEffect(timeFraction, iteration, target) {
02web_animation_8.innerHTML = 'timeFraction: ' + timeFraction.toFixed(2) + '\n' +
03'iteration: ' + iteration;
04}
05var web_animation_8 = document.getElementById("web_animation_8");
0607var obj = new Animation(null,
08{sample: customAnimationEffect},
09{
10duration: 2,
11direction: 'alternate',
12easing: 'ease-in-out',
13iterations: Infinity,
14});
1516var customPlayer = document.timeline.play(obj);
1718window.addEventListener('slideenter', function(event) {
19if (event.slide == customSlide) {
20customPlayer.currentTime = 0;
21}
22}, false);查看实例演示
实例九:综合实例
01(function(document) {
0203'use strict';
04var Animations = {},
05player, controls = document.getElementById('animate-controls');
0607Animations.targets = {
08path: document.getElementById('path'),
09ballContainer: document.getElementById('animate-ball-container'),
10ball: document.getElementById('animate-ball')
11};
1213Animations.keyframeMove = new Animation(Animations.targets.ballContainer, [{
14offset: 0,
15transform: 'translate(0,0)'
16}, {
17offset: 1,
18transform: 'translate(600,0)'
19}], {
20duration: 2000
21});
2223Animations.keyframeSpinRoll = new Animation(Animations.targets.ball, [{
24transform: 'rotate(950deg)'
25}], {
26duration: 2000
27});
2829Animations.motionpathBounce = new Animation(Animations.targets.ballContainer, new MotionPathEffect("M25,25 " + "a150,100 0 0,1 300,0 " + "a75,50 0 0,1 150,0 " + "a35,20 0 0,1 70,0 " + "a2,1 0 0,1 35,0 " + "h45"), {
30duration: 2500
31});
3233Animations.keyframeSpinBounce = new Animation(Animations.targets.ball, [{
34transform: 'rotate(950deg)'
35}], {
36duration: 2500
37});
3839Animations.animationGroupRoll = new AnimationGroup([Animations.keyframeMove, Animations.keyframeSpinRoll], {
40easing: 'ease-out'
41});
4243Animations.animationGroupBounce = new AnimationGroup([Animations.motionpathBounce, Animations.keyframeSpinBounce], {
44easing: 'ease-out'
45});
4647controls.addEventListener('click', function(event) {
48if (event.target) {
49var targetElement = event.target;
50switch (targetElement.id) {
51case 'keyframe-start':
52player = document.timeline.play(Animations.animationGroupRoll);
53break;
54case 'motionpath-start':
55player = document.timeline.play(Animations.animationGroupBounce);
56break;
57case 'pause':
58player.pause();
59break;
60case 'cancel':
61player.cancel();
62break;
63case 'play':
64player.play();
65break;
66case 'reverse':
67player.reverse()
68}
69}
70})
71})(document);查看实例演示
六、现行兼容性方案1) 页面增强动画建议使用CSS动画2) 复杂动画交互建议使用RAF及setInterval 或setTimeout优雅降级处理
01(function() {
02var lastTime = 0,
03vendors = ['webkit', 'moz'];
0405for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
06window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
0708window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
09}
1011if (!window.requestAnimationFrame) {
12window.requestAnimationFrame = function(callback, element) {
13var currTime = new Date().getTime(),
14timeToCall = Math.max(0, 16.6 - (currTime - lastTime) ),
15id = window.setTimeout(function() {
16callback(currTime + timeToCall);
17},timeToCall);
1819lastTime = currTime + timeToCall;
20return id;
21};
22}
2324if (!window.cancelAnimationFrame) {
25window.cancelAnimationFrame = function(id) {
26clearTimeout(id);
27};
28}
2930})();3) 推荐动画库Velocity.js、GreenSock:1) Velocity.js是一款动画切换的jQuery插件,它重新实现了jQuery的$.animate()方法从而加快动画切换的速度。Velocity.js只有7k的大小,它不仅包含了$.animate()的所有功能,并且还包含了颜色切换、转换(transform)、循环、缓动、CSS切换、Scroll功能,它是jQuery、 jQuery UI、CSS变换 在动画方面的最佳组合。Velocity.js支持IE8+、Chrome、Firefox等浏览器,并支持Andriod以及IOS。Velocity.js在内部实现中使用了jQuery的$.queue()方法,因此它比 jQuery的$.animate()、$.fade()、$.delay()方法更加流畅,其性能也高于CSS的animation属性。2) GreenSock:GSAP v12平台非常快的速度:性能是非常重要的,尤其是在移动设备上。GSAP不断优化,以保证互动项目的快速响应、高效率及平滑,你可以从这里查看动画效果测试。异想天开的强劲:内置众多引擎的功能,如动画色彩、贝塞尔曲线、CSS样式属性、Flash滤镜、数组等等,定义不同的回调,可以通过帧或者秒定义运动。兼容性:Flash,HTML5,jQuery,Canvas,CSS,新浏览器,旧浏览器,RequireJS,EaseIJS,移动设备等等-GSAP都可以很好的与他们兼容,你可以选择你熟悉的工具来使用。Javascript,AS3/AS2:选择适合你的语言来完成动画。轻量与可扩展性:模块化与插件式的结构保持了核心引擎的轻量,TweenLite包非常小(基本上低于7kb)。没有依赖:GSAP没有基于第三方工具来构建(虽然它将jQuery作为选择器),因此能保证最短的加载时间与最大化性能。高等序列:不用受限于线性序列,可以重叠动画序列,你可以通过精确时间控制,灵活地使用最少的代码实现动画。良好的技术支持:可以通过论坛反馈,会有专家和资深活跃用户回答问题。任何对象都可以实现动画:是的,任何,不用预定义的属性,任何对象的任意数字属性都可以实现动画,如果这些属性(如颜色,滤镜,非数值属性等)需要处理,插件可以实现。如果没有,我们可以实现一个。重写管理:GSAP帮助防止动画引擎的冲突以及高级选项的设置。易于学习:文档、教程、 示例、学习指南、论坛,还有很多学习资源,非常地丰富。许可证:除商业用途意外,GSAP完全免费。

主流动画实现方式总结相关推荐

  1. Leetcode上的解法看不懂?试着用动画的方式去辅助理解

    推荐一个用动画的方式演示leetcode题目解题思路的github仓库: https://github.com/MisterBooo/LeetCodeAnimation 超过15000个star: 用 ...

  2. 「镁客·请讲」小i机器人朱频频:会话AI将成为主流人机交流方式,积累和深度学习是关键...

    消费级服务机器人技术还没达到一个理想的状态,但积累很重要. 和小i机器人创始人&CEO朱频频的见面是在由中国服务机器人应用及推广联盟主办的2017国际服务机器人产业高峰论坛上.因为人很多,所以 ...

  3. 【Unity笔记】连招动画切换方式(一)

    连招动画切换方式(一) 此方法可以实现的连击效果: 通过连续点击鼠标左键 攻击1 接 攻击2 接 攻击3 结束 在任意攻击动作中停止点击鼠标左键,则连击中断 一.Animator中的设置 先将一套连招 ...

  4. LayaAir2.13新特性:新增VR相关功能、渐变环境光、3D自定义分辨率、新的渲染命令、新的动画插值方式、新的粒子功能等等...

    在两个小版本之后,LayaAir引擎再次迎来了2.13这个大版本的更新. 本次版本中,我们不仅继续进行了大量的引擎优化,例如,优化3D渲染架构.优化后期处理流程.优化AO算法等等. 还增加了若干重要的 ...

  5. 虚拟化正成为主流IT运营方式

    本文讲的是虚拟化正成为主流IT运营方式,[IT168 资讯]VMware公司在2008年取得了骄人的业绩,2008财年总收入为19亿美元,比2007财年增长了42%.通过利用虚拟化技术成功消除了长期存 ...

  6. unity3d android 路径动画制作,Lesson11.Unity路径动画、路径变形动画实现方式

    鲸鱼的絮絮叨叨 Lesson01.unity简介和菜单栏介绍 Lesson02.unity粒子系统_1 Lesson02.unity粒子系统_2 Lesson03.3dmax粒子系统_1 Lesson ...

  7. CSS知识点汇总(六)--垂直居中动画实现方式

    文章目录 1. CSS 垂直居中有哪些实现方式? 2.css加载会造成阻塞吗? 3. 前端实现动画有哪些方式? 1. CSS 垂直居中有哪些实现方式? 在布局一个页面时,通常都会用到水平居中和垂直居中 ...

  8. 关于Android项目中的Toast那些动画实现方式

    最近产品给了一个竞品App的Toast动画,希望开发可以去实现它,经过一段时间的深(不)思(停)熟(百)虑(度)之后,发现事情其实并不简单,所以这里记录一下关于Android~Toast动画实现的相关 ...

  9. 认证登录时代来临,主流验证登录方式盘点

    对于手机用户来说,身份验证是个必不可少的环节.目前国内的APP内的用户验证主要有账号密码.短信验证.第三方账号(微信/QQ等)登录和免密认证.前三种占据主流但依然存在着自身局限和漏洞,并不能完全满足用 ...

最新文章

  1. python定时任务contrib_django+celery配置(定时任务+循环任务)
  2. byte与char区别
  3. android Java BASE64编码和解码一:基础
  4. 计算机连上网没网络连接,电脑显示本地网络连接但是宽带没连上怎么办? 爱问知识人...
  5. Atcoder AGC031B Reversi (DP计数)
  6. 500个爆文标题_我研究了999篇100万+爆文,终于发现这10条标题规律!
  7. 色彩的狂欢:看嘎玛·多吉次仁的画展
  8. OpenShift上的Java EE工作流(技术提示#64)
  9. 摄影测量--点位精度评定
  10. Android 系统(246)---SystemServer进程的启动流程
  11. java list 元素排序_对arraylist中元素进行排序实例代码
  12. sbit和sfr的定义
  13. 三菱MX Component通信应用
  14. 手动解除加密文件夹 lockdir产生的文件com1.{d3e34b21-9d75-101a-8c3d-00aa001a1652}
  15. 魔兽世界单机版(模拟器)入门介绍--Starting off with WoW Emulation. 翻译
  16. 3dmax2016的破解和安装
  17. uart通信协议详解
  18. Unity TextMesh Pro标记
  19. SQLServer2000数据库导入步骤
  20. android 模拟自动点击,自动点击器(模拟点击)

热门文章

  1. ggplot绘制柱状图 python_ggplot2|绘制GO富集柱形图
  2. Node-RED通过npm安装的方式对应卸载
  3. 开源中国翻译贡献排名靠谱吗?
  4. 【Android】Android Studio下安装部署虚拟真机
  5. Java - 读取Excel并转CSV格式
  6. 中文版php代码生成器,PHPCMS V9代码生成器
  7. ORA-01722:invalid number-解决GAT项目中车辆维修Bug(续)
  8. oracle转trs,ORACLE常规恢复之应用数据文件丢失
  9. oracle 存储过程中 truncate,procedure中truncate other schema’s table
  10. 收费企业邮箱,适合媒体行业的企业邮箱