Toggle navigation
在线编辑器
在线代码
文本比较
jQuery下载
前端库
在线手册
登录/注册
下载代码
html
css
js
分享到微信朋友圈
X
html
20
c
Monday 22 August
css
@import "https://fonts.googleapis.com/css?family=Lato:300"; @import "https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.min.css"; html, body, .background { width: 100%; height: 100%; margin: 0; padding: 0; font-family: 'Lato', sans-serif; } html { background: #fff; } body { background: #eee; background: -webkit-linear-gradient(bottom, rgba(0, 0, 200, 0.2), rgba(0, 0, 200, 0)); background: linear-gradient(0deg, rgba(0, 0, 200, 0.2), rgba(0, 0, 200, 0)); } .background { background: #eee; background: -webkit-linear-gradient(330deg, rgba(50, 150, 100, 0.2), rgba(0, 0, 100, 0)); background: linear-gradient(120deg, rgba(50, 150, 100, 0.2), rgba(0, 0, 100, 0)); } .container { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; -webkit-box-align: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; margin: 0; padding: 0; height: 100%; width: 100%; overflow: auto; position: relative; background: #eee; background: -webkit-linear-gradient(210deg, rgba(150, 50, 50, 0.3), rgba(0, 0, 200, 0)); background: linear-gradient(240deg, rgba(150, 50, 50, 0.3), rgba(0, 0, 200, 0)); } nav ul { margin: 20px 20px 0 20px; list-style-type: none; padding: 0; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } nav li a { display: block; width: 50px; text-align: center; color: #aaa; cursor: pointer; } nav li a:hover { color: #444; } nav li a.active { color: #4444ff; } #card { box-shadow: 9px 7px 40px -6px rgba(0, 0, 0, 0.25); overflow: hidden; width: 300px; padding: 0; height: 400px; min-height: 300px; margin: 20px; border-radius: 5px; position: relative; } #card .details { position: absolute; top: 0; left: 0; right: 0; padding: 16px 20px; color: #888; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; -webkit-transition: color 2s ease; transition: color 2s ease; } .thunder #card .details { color: #ddd; } #card .details .right { text-align: right; } #card .details #date { margin: 4px 0; } #card .details #summary { font-weight: 600; font-size: 22px; } #card .details .temp { font-size: 60px; line-height: 60px; } #card .details .temp span { font-size: 18px; line-height: 30px; vertical-align: top; margin-left: 5px; } .weather { background-color: #DAE3FD; -webkit-transition: background-color 2s ease; transition: background-color 2s ease; } .thunder .weather { background-color: #9FA4AD; } .rain .weather { background-color: #D8D8D8; } .sun .weather { background-color: #ccccff; } .weather #inner { background-color: white; background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 100%); background: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 100%); } .weather .cloud { -webkit-transition: fill 2s ease; transition: fill 2s ease; } .weather #cloud1 { fill: #efefef; } .thunder .weather #cloud1 { fill: #9FA4AD; } .weather #cloud2 { fill: #E6E6E6; } .thunder .weather #cloud2 { fill: #8B8E98; } .weather #cloud3 { fill: #D5D5D5; } .thunder .weather #cloud3 { fill: #7B7988; } #outer, #back { position: fixed; pointer-events: none; }
JavaScript
// ?? Fetch all DOM nodes in jQuery and Snap SVG var container = $('.container'); var card = $('#card'); var innerSVG = Snap('#inner'); var outerSVG = Snap('#outer'); var backSVG = Snap('#back'); var summary = $('#summary'); var date = $('#date'); var weatherContainer1 = Snap.select('#layer1'); var weatherContainer2 = Snap.select('#layer2'); var weatherContainer3 = Snap.select('#layer3'); var innerRainHolder1 = weatherContainer1.group(); var innerRainHolder2 = weatherContainer2.group(); var innerRainHolder3 = weatherContainer3.group(); var innerLeafHolder = weatherContainer1.group(); var innerSnowHolder = weatherContainer1.group(); var innerLightningHolder = weatherContainer1.group(); var leafMask = outerSVG.rect(); var leaf = Snap.select('#leaf'); var sun = Snap.select('#sun'); var sunburst = Snap.select('#sunburst'); var outerSplashHolder = outerSVG.group(); var outerLeafHolder = outerSVG.group(); var outerSnowHolder = outerSVG.group(); var lightningTimeout; // Set mask for leaf holder outerLeafHolder.attr({ 'clip-path': leafMask }); // create sizes object, we update this later var sizes = { container: {width: 0, height: 0}, card: {width: 0, height: 0} } // grab cloud groups var clouds = [ {group: Snap.select('#cloud1')}, {group: Snap.select('#cloud2')}, {group: Snap.select('#cloud3')} ] // set weather types ?? ?? ?? ? ?? var weather = [ { type: 'snow', name: 'Snow'}, { type: 'wind', name: 'Windy'}, { type: 'rain', name: 'Rain'}, { type: 'thunder', name: 'Storms'}, { type: 'sun', name: 'Sunny'} ]; // ?? app settings // in an object so the values can be animated in tweenmax var settings = { windSpeed: 2, rainCount: 0, leafCount: 0, snowCount: 0, cloudHeight: 100, cloudSpace: 30, cloudArch: 50, renewCheck: 10, splashBounce: 80 }; var tickCount = 0; var rain = []; var leafs = []; var snow = []; // ? initialize app init(); // ?? watch for window resize $(window).resize(onResize); // ?? start animations requestAnimationFrame(tick); function init() { onResize(); // ?? bind weather menu buttons for(var i = 0; i < weather.length; i++) { var w = weather[i]; var b = $('#button-' + w.type); w.button = b; b.bind('click', w, changeWeather); } // ?? draw clouds for(var i = 0; i < clouds.length; i++) { clouds[i].offset = Math.random() * sizes.card.width; drawCloud(clouds[i], i); } // ?? set initial weather TweenMax.set(sunburst.node, {opacity: 0}) changeWeather(weather[0]); } function onResize() { // ?? grab window and card sizes sizes.container.width = container.width(); sizes.container.height = container.height(); sizes.card.width = card.width(); sizes.card.height = card.height(); sizes.card.offset = card.offset(); // ?? update svg sizes innerSVG.attr({ width: sizes.card.width, height: sizes.card.height }) outerSVG.attr({ width: sizes.container.width, height: sizes.container.height }) backSVG.attr({ width: sizes.container.width, height: sizes.container.height }) TweenMax.set(sunburst.node, {transformOrigin:"50% 50%", x: sizes.container.width / 2, y: (sizes.card.height/2) + sizes.card.offset.top}); TweenMax.fromTo(sunburst.node, 20, {rotation: 0}, {rotation: 360, repeat: -1, ease: Power0.easeInOut}) // ?? The leaf mask is for the leafs that float out of the // container, it is full window height and starts on the left // inline with the card leafMask.attr({x: sizes.card.offset.left, y: 0, width: sizes.container.width - sizes.card.offset.left, height: sizes.container.height}); } function drawCloud(cloud, i) { /* ?? We want to create a shape thats loopable but that can also be animated in and out. So we use Snap SVG to draw a shape with 4 sections. The 2 ends and 2 arches the same width as the card. So the final shape is about 4 x the width of the card. */ var space = settings.cloudSpace * i; var height = space + settings.cloudHeight; var arch = height + settings.cloudArch + (Math.random() * settings.cloudArch); var width = sizes.card.width; var points = []; points.push('M' + [-(width), 0].join(',')); points.push([width, 0].join(',')); points.push('Q' + [width * 2, height / 2].join(',')); points.push([width, height].join(',')); points.push('Q' + [width * 0.5, arch].join(',')); points.push([0, height].join(',')); points.push('Q' + [width * -0.5, arch].join(',')); points.push([-width, height].join(',')); points.push('Q' + [- (width * 2), height/2].join(',')); points.push([-(width), 0].join(',')); var path = points.join(' '); if(!cloud.path) cloud.path = cloud.group.path(); cloud.path.animate({ d: path }, 0) } function makeRain() { // ?? This is where we draw one drop of rain // first we set the line width of the line, we use this // to dictate which svg group it'll be added to and // whether it'll generate a splash var lineWidth = Math.random() * 3; // ? line length is made longer for stormy weather var lineLength = currentWeather.type == 'thunder' ? 35 : 14; // Start the drop at a random point at the top but leaving // a 20px margin var x = Math.random() * (sizes.card.width - 40) + 20; // Draw the line var line = this['innerRainHolder' + (3 - Math.floor(lineWidth))].path('M0,0 0,' + lineLength).attr({ fill: 'none', stroke: currentWeather.type == 'thunder' ? '#777' : '#0000ff', strokeWidth: lineWidth }); // add the line to an array to we can keep track of how // many there are. rain.push(line); // Start the falling animation, calls onRainEnd when the // animation finishes. TweenMax.fromTo(line.node, 1, {x: x, y: 0- lineLength}, {delay: Math.random(), y: sizes.card.height, ease: Power2.easeIn, onComplete: onRainEnd, onCompleteParams: [line, lineWidth, x, currentWeather.type]}); } function onRainEnd(line, width, x, type) { // first lets get rid of the drop of rain ?? line.remove(); line = null; // We also remove it from the array for(var i in rain) { if(!rain[i].paper) rain.splice(i, 1); } // If there is less rain than the rainCount we should // make more. if(rain.length < settings.rainCount) { makeRain(); // ?? If the line width was more than 2 we also create a // splash. This way it looks like the closer (bigger) // drops hit the the edge of the card if(width > 2) makeSplash(x, type); } } function makeSplash(x, type) { // ?? The splash is a single line added to the outer svg. // The splashLength is how long the animated line will be var splashLength = type == 'thunder' ? 30 : 20; // splashBounce is the max height the line will curve up // before falling var splashBounce = type == 'thunder' ? 120 : 100; // this sets how far down the line can fall var splashDistance = 80; // because the storm rain is longer we want the animation // to last slighly longer so the overall speed is roughly // the same for both var speed = type == 'thunder' ? 0.7 : 0.5; // Set a random splash up amount based on the max splash bounce var splashUp = 0 - (Math.random() * splashBounce); // Sets the end x position, and in turn defines the splash direction var randomX = ((Math.random() * splashDistance) - (splashDistance / 2)); // Now we put the 3 line coordinates into an array. var points = []; points.push('M' + 0 + ',' + 0); points.push('Q' + randomX + ',' + splashUp); points.push((randomX * 2) + ',' + splashDistance); // Draw the line with Snap SVG var splash = outerSplashHolder.path(points.join(' ')).attr({ fill: "none", stroke: type == 'thunder' ? '#777' : '#0000ff', strokeWidth: 1 }); // We animate the dasharray to have the line travel along the path var pathLength = Snap.path.getTotalLength(splash); var xOffset = sizes.card.offset.left;//(sizes.container.width - sizes.card.width) / 2 var yOffset = sizes.card.offset.top + sizes.card.height; splash.node.style.strokeDasharray = splashLength + ' ' + pathLength; // Start the splash animation, calling onSplashComplete when finished TweenMax.fromTo(splash.node, speed, {strokeWidth: 2, y: yOffset, x: xOffset + 20 + x, opacity: 1, strokeDashoffset: splashLength}, {strokeWidth: 0, strokeDashoffset: - pathLength, opacity: 1, onComplete: onSplashComplete, onCompleteParams: [splash], ease: SlowMo.ease.config(0.4, 0.1, false)}) } function onSplashComplete(splash) { // ?? The splash has finished animating, we need to get rid of it splash.remove(); splash = null; } function makeLeaf() { var scale = 0.5 + (Math.random() * 0.5); var newLeaf; var areaY = sizes.card.height/2; var y = areaY + (Math.random() * areaY); var endY = y - ((Math.random() * (areaY * 2)) - areaY) var x; var endX; var colors = ['#76993E', '#4A5E23', '#6D632F']; var color = colors[Math.floor(Math.random() * colors.length)]; var xBezier; if(scale > 0.8) { newLeaf = leaf.clone().appendTo(outerLeafHolder) .attr({ fill: color }) y = y + sizes.card.offset.top / 2; endY = endY + sizes.card.offset.top / 2; x = sizes.card.offset.left - 100; xBezier = x + (sizes.container.width - sizes.card.offset.left) / 2; endX = sizes.container.width + 50; } else { newLeaf = leaf.clone().appendTo(innerLeafHolder) .attr({ fill: color }) x = -100; xBezier = sizes.card.width / 2; endX = sizes.card.width + 50; } leafs.push(newLeaf); var bezier = [{x:x, y:y}, {x: xBezier, y:(Math.random() * endY) + (endY / 3)}, {x: endX, y:endY}] TweenMax.fromTo(newLeaf.node, 2, {rotation: Math.random()* 180, x: x, y: y, scale:scale}, {rotation: Math.random()* 360, bezier: bezier, onComplete: onLeafEnd, onCompleteParams: [newLeaf], ease: Power0.easeIn}) } function onLeafEnd(leaf) { leaf.remove(); leaf = null; for(var i in leafs) { if(!leafs[i].paper) leafs.splice(i, 1); } if(leafs.length < settings.leafCount) { makeLeaf(); } } function makeSnow() { var scale = 0.5 + (Math.random() * 0.5); var newSnow; var x = 20 + (Math.random() * (sizes.card.width - 40)); var endX; // = x - ((Math.random() * (areaX * 2)) - areaX) var y = -10; var endY; if(scale > 0.8) { newSnow = outerSnowHolder.circle(0, 0, 5) .attr({ fill: 'white' }) endY = sizes.container.height + 10; y = sizes.card.offset.top + settings.cloudHeight; x = x + sizes.card.offset.left; //xBezier = x + (sizes.container.width - sizes.card.offset.left) / 2; //endX = sizes.container.width + 50; } else { newSnow = innerSnowHolder.circle(0, 0 ,5) .attr({ fill: 'white' }) endY = sizes.card.height + 10; //x = -100; //xBezier = sizes.card.width / 2; //endX = sizes.card.width + 50; } snow.push(newSnow); TweenMax.fromTo(newSnow.node, 3 + (Math.random() * 5), {x: x, y: y}, {y: endY, onComplete: onSnowEnd, onCompleteParams: [newSnow], ease: Power0.easeIn}) TweenMax.fromTo(newSnow.node, 1,{scale: 0}, {scale: scale, ease: Power1.easeInOut}) TweenMax.to(newSnow.node, 3, {x: x+((Math.random() * 150)-75), repeat: -1, yoyo: true, ease: Power1.easeInOut}) } function onSnowEnd(flake) { flake.remove(); flake = null; for(var i in snow) { if(!snow[i].paper) snow.splice(i, 1); } if(snow.length < settings.snowCount) { makeSnow(); } } function tick() { tickCount++; var check = tickCount % settings.renewCheck; if(check) { if(rain.length < settings.rainCount) makeRain(); if(leafs.length < settings.leafCount) makeLeaf(); if(snow.length < settings.snowCount) makeSnow(); } for(var i = 0; i < clouds.length; i++) { if(currentWeather.type == 'sun') { if(clouds[i].offset > -(sizes.card.width * 1.5)) clouds[i].offset += settings.windSpeed / (i + 1); if(clouds[i].offset > sizes.card.width * 2.5) clouds[i].offset = -(sizes.card.width * 1.5); clouds[i].group.transform('t' + clouds[i].offset + ',' + 0); } else { clouds[i].offset += settings.windSpeed / (i + 1); if(clouds[i].offset > sizes.card.width) clouds[i].offset = 0 + (clouds[i].offset - sizes.card.width); clouds[i].group.transform('t' + clouds[i].offset + ',' + 0); } } requestAnimationFrame(tick); } function reset() { for(var i = 0; i < weather.length; i++) { container.removeClass(weather[i].type); weather[i].button.removeClass('active'); } } function updateSummaryText() { summary.html(currentWeather.name); TweenMax.fromTo(summary, 1.5, {x: 30}, {opacity: 1, x: 0, ease: Power4.easeOut}); } function startLightningTimer() { if(lightningTimeout) clearTimeout(lightningTimeout); if(currentWeather.type == 'thunder') { lightningTimeout = setTimeout(lightning, Math.random()*6000); } } function lightning() { startLightningTimer(); TweenMax.fromTo(card, 0.75, {y: -30}, {y:0, ease:Elastic.easeOut}); var pathX = 30 + Math.random() * (sizes.card.width - 60); var yOffset = 20; var steps = 20; var points = [pathX + ',0']; for(var i = 0; i < steps; i++) { var x = pathX + (Math.random() * yOffset - (yOffset / 2)); var y = (sizes.card.height / steps) * (i + 1) points.push(x + ',' + y); } var strike = weatherContainer1.path('M' + points.join(' ')) .attr({ fill: 'none', stroke: 'white', strokeWidth: 2 + Math.random() }) TweenMax.to(strike.node, 1, {opacity: 0, ease:Power4.easeOut, onComplete: function(){ strike.remove(); strike = null}}) } function changeWeather(weather) { if(weather.data) weather = weather.data; reset(); currentWeather = weather; TweenMax.killTweensOf(summary); TweenMax.to(summary, 1, {opacity: 0, x: -30, onComplete: updateSummaryText, ease: Power4.easeIn}) container.addClass(weather.type); weather.button.addClass('active'); // windSpeed switch(weather.type) { case 'wind': TweenMax.to(settings, 3, {windSpeed: 3, ease: Power2.easeInOut}); break; case 'sun': TweenMax.to(settings, 3, {windSpeed: 20, ease: Power2.easeInOut}); break; default: TweenMax.to(settings, 3, {windSpeed: 0.5, ease: Power2.easeOut}); break; } // rainCount switch(weather.type) { case 'rain': TweenMax.to(settings, 3, {rainCount: 10, ease: Power2.easeInOut}); break; case 'thunder': TweenMax.to(settings, 3, {rainCount: 60, ease: Power2.easeInOut}); break; default: TweenMax.to(settings, 1, {rainCount: 0, ease: Power2.easeOut}); break; } // leafCount switch(weather.type) { case 'wind': TweenMax.to(settings, 3, {leafCount: 5, ease: Power2.easeInOut}); break; default: TweenMax.to(settings, 1, {leafCount: 0, ease: Power2.easeOut}); break; } // snowCount switch(weather.type) { case 'snow': TweenMax.to(settings, 3, {snowCount: 40, ease: Power2.easeInOut}); break; default: TweenMax.to(settings, 1, {snowCount: 0, ease: Power2.easeOut}); break; } // sun position switch(weather.type) { case 'sun': TweenMax.to(sun.node, 4, {x: sizes.card.width / 2, y: sizes.card.height / 2, ease: Power2.easeInOut}); TweenMax.to(sunburst.node, 4, {scale: 1, opacity: 0.8, y: (sizes.card.height/2) + (sizes.card.offset.top), ease: Power2.easeInOut}); break; default: TweenMax.to(sun.node, 2, {x: sizes.card.width / 2, y: -100, leafCount: 0, ease: Power2.easeInOut}); TweenMax.to(sunburst.node, 2, {scale: 0.4, opacity: 0, y: (sizes.container.height/2)-50, ease: Power2.easeInOut}); break; } // lightning startLightningTimer(); }
粒子
时间
文字
hover
canvas
3d
游戏
音乐
火焰
水波
轮播图
鼠标跟随
动画
css
加载动画
导航
菜单
按钮
滑块
tab
弹出层
统计图
svg
×
Close
在线代码下载提示
开通在线代码永久免费下载,需支付20jQ币
开通后,在线代码模块中所有代码可终身免费下!
您已开通在线代码永久免费下载,关闭提示框后,点下载代码可直接下载!
您已经开通过在线代码永久免费下载
对不起,您的jQ币不足!可通过发布资源 或
直接充值获取jQ币
取消
开通下载
<!doctype html> <html> <head> <meta charset="utf-8"> <title>天气动画选项卡-jq22.com</title> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <style>
</style> </head> <body>
<script>
</script>
</body> </html>
2012-2021 jQuery插件库版权所有
jquery插件
|
jq22工具库
|
网页技术
|
广告合作
|
在线反馈
|
版权声明
沪ICP备13043785号-1
浙公网安备 33041102000314号