整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML5 Canvas逼真水波纹动画特效

多特效代码请添加HTML5前端交流群581549454

废话不多说上代码!

normalize.css

article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"1C" "1D" "18" "19";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}

zzsc.css

body, html { font-size: 100%; padding: 0; margin: 0;}

/* Reset */

*,

*:after,

*:before {

-webkit-box-sizing: border-box;

-moz-box-sizing: border-box;

box-sizing: border-box;

}

/* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */

.clearfix:before,

.clearfix:after {

content: " ";

display: table;

}

.clearfix:after {

clear: both;

}

body{

background: #494A5F;

color: #D5D6E2;

font-weight: 500;

font-size: 1.05em;

font-family: "Microsoft YaHei","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif;

}

a{ color: rgba(255, 255, 255, 0.6);outline: none;text-decoration: none;-webkit-transition: 0.2s;transition: 0.2s;}

a:hover,a:focus{color:#74777b;text-decoration: none;}

网站代码

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>HTML5 Canvas逼真水波纹动画特效</title>

<link rel="stylesheet" type="text/css" href="css/normalize.css" />

<link rel="stylesheet" type="text/css" href="css/zzsc.css">

<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>

<script type="text/javascript" src="js/jquery.waterrippleeffect.min.js"></script>

<style type="text/css">

html, body, div, span, applet, object, iframe,

h1, h2, h3, h4, h5, h6, p, blockquote, pre,

a, abbr, acronym, address, big, cite, code,

del, dfn, em, font, img, ins, kbd, q, s, samp,

small, strike, strong, sub, sup, tt, var,

b, u, i, center,

dl, dt, dd, ol, ul, li,

fieldset, form, label, legend,

table, caption, tbody, tfoot, thead, tr, th, td {

margin: 0;

padding: 0;

border: 0;

outline: 0;

font-size: 100%;

vertical-align: baseline;

/*background: transparent;*/

box-sizing: border-box;

}

body {

overflow: hidden;

}

.container{

width: 480px;

height: 480px;

margin:20px auto;

position: relative;

}

.clear {

clear: both;

height: 0;

font-size: 0;

line-height: 0;

}

</style>

<script>

$( document ).ready( function() {

//------------------------------------------------------------------------

$( '#preloaderDiv' ).delay( 1000 ).fadeTo( 1000 , 0, function() {

$( this ).css( 'display', 'none' );

} );

$( '#startDiv' ).css( 'cursor', 'pointer' ).click( function() {

//$( this ).css( 'display', 'none' );

$( this ).delay( 10 ).fadeTo( 1000 , 0, function() {

$( this ).css( 'display', 'none' );

} );

init();

} );

//------------------------------------------------------------------------

function init() {

//Settings - params for WaterRippleEffect

var settings = {

image: './img/SwimmingPool.jpg',//image path

rippleRadius: 3,//radius of the ripple

width: 480,//width

height: 480,//height

delay: 1,//if auto param === true. 1 === 1 second delay for animation

auto: true//if auto param === true, animation starts on it´s own

};

//------------------------------------------------------------------------

//standalone

//init

var waterRippleEffect = new WaterRippleEffect( document.getElementById( 'holder' ), settings );

document.getElementById( 'holder' ).style.cursor = 'pointer';

//on click

document.getElementById( 'holder' ).addEventListener( 'click', function( e ) {

var mouseX = e.layerX;

var mouseY = e.layerY;

waterRippleEffect.disturb( mouseX, mouseY );

} );

//on mousemove

document.getElementById( 'holder' ).addEventListener( 'mousemove', function( e ) {

var mouseX = e.layerX;

var mouseY = e.layerY;

waterRippleEffect.disturb( mouseX, mouseY );

} );

//------------------------------------------------------------------------

//jQuery

//init

/*

$( '#holder' ).waterRippleEffect( settings );

$( '#holder' ).css( 'cursor', 'pointer' );

*/

//on click

/*

$( '#holder' ).click( function( e ) {

var mouseX = e.pageX - $( this ).offset().left;

var mouseY = e.pageY - $( this ).offset().top;

$( '#holder' ).waterRippleEffect( "disturb", mouseX, mouseY );

} );

*/

//on mousemove

/*

$( '#holder' ).mousemove( function( e ) {

var mouseX = e.pageX - $( this ).offset().left;

var mouseY = e.pageY - $( this ).offset().top;

$( '#holder' ).waterRippleEffect( "disturb", mouseX, mouseY );

} );

*/

};

//------------------------------------------------------------------------

} );

</script>

</head>

<body><script src="/demos/googlegg.js"></script>

<div>

<div id='holder' style='width:480px; height:480px; position:absolute;'></div>

<div id='startDiv' style='background-color:#000; position:absolute; width:480px; height:480px;'>

<img src='img/startBt.jpg' width='480px' height='480px' alt='Start' style='position:absolute; top:50%; left:50%; margin-top:-240px; margin-left:-240px;'>

</div>

<div id='preloaderDiv' style='background-color:#000; position:absolute; width:480px; height:480px; pointer-events:none'>

<img src='img/PreloaderDark.gif' width='44px' height='48px' alt='Preloader' style='position:absolute; top:50%; left:50%; margin-top:-22px; margin-left:-24px;'>

</div>

</div>

<div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';">

<p>适用浏览器:360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗. 不支持IE8及以下浏览器。</p>

<p>来源:<a href="http://www.aaa-cg.com.cn/xue/?lcc" target="_blank">素材</a></p>

</div>

</body>

</html>

SS伪元素主要是指HTML中没有定义、存在的元素,伪元素本身不是真正的页面元素,但是伪元素在使用过程中,其用法与效果与其他真正页面元素是一样的。伪元素只能在定义基础上动态显示其运行效果,在HTML源文件中并没有该元素的真正代码。CSS3中所定义的所有伪元素与伪类描述如下图所示:

CSS伪元素与伪类


按钮波纹ripple效果展示

ripple波纹

按钮的波纹效果主要是指按钮在点击时展示出的动态效果。在实现效果过程中可行的方法方式较多,例如可以使用JavaScript、CSS动画、JQuery等。网上目前按钮波纹实现效果较多,部分样式效果展示如下:

波纹效果展示


CSS 伪类波纹效果实现

CSS伪类波纹效果主要借助于before、after伪类与hover悬停选择器等实现类似波纹效果,本文主要借助after及hover等实现按钮的波纹效果,本例设计两种类似波纹效果,最终实现效果展示如下图所示:

设计样式1

设计样式2

本文设计实现的两类波纹效果样式描述如上图gif所示,其实现过程描述如下:

1、按钮基本样式设计

本例按钮基本样式主要包括宽度、高度、背景颜色等。使用元素选择器与类选择器定义了按钮元素的基本样式,其样式实现代码描述如下:

button,.button2,.button{width: 200px; height: 50px; background-color: green;border: 0; cursor: pointer;color: #FFF; font-size: 16px; position: relative;}

.button类主要用以实现设计样式1,.button2类主要用于实现设计效果2,两类按钮定义描述如下:

<button type="button" class="button">Ripple1</button>
<button type="button" class="button2">Ripple2</button>

2、after伪元素使用

after伪元素主要用于实现在指定元素的后面添加新的内容。本例提供的两种设计方式都是在button元素的后面添加新的类似div的新元素,其中样式1,新添加的元素与button本身重合,尺寸也一致。设计样式2中after元素位于button的底部位置,宽度与button相同,高度为指定尺寸5px。两个设计中after元素样式为实现动态展开效果都涉及宽度width为0。after元素的样式定义如下:

.button::after{content: " "; width: 0; height: 50px; position: absolute; left:50%;top: 0%;background-color: red;opacity: 0; transition: all .4s; }
.button2::after{content: " "; width: 0; height: 5px; position: absolute; left:50%;top: 100%;background-color: red;transition: all .4s; }

after元素CSS样式定义中使用了transition属性实现动画效果,即在0.4s内实现宽度从0改变为100%。

3、hover选择器的使用

hover选择器为悬停选择器,主要对鼠标在HTML元素悬停时样式进行设置。本例两个涉及效果都是借助hover悬停选择器对after样式进行设置,在初始化设置宽度为0的基础上宽度改变为100%,最终实现两端伸展的效果。hover选择器定义after元素样式描述如下所示:

.button:hover::after{left:0%; width: 100%; opacity: 0.6;}
.button2:hover::after{left:0%; width: 100%;}

以上给出了CSS伪元素实现波纹效果,主要借助了after、before伪元素与hover悬停选择器等。设计实现效果完整源文件截图如下:

案例完整代码


以上给出了JavaScript中的事件基本概念及案例分析,如有问题可在评论区讨论。本头条号长期关注编程资讯分享;编程课程、素材、代码分享及编程培训。如果您对以上方面有兴趣或代码错误、建议与意见,可以联系作者,共同探讨。期待大家关注!相关文章链接如下:

前端开发-JavaScript中的事件(Event)及事件处理总结

前端开发-CSS3动画实现焦点(图文轮播)图效果

前端开发-JavaScript DOM动态生成文本框

前端设计-教你如何快速绘制HTML5动画

前端设计-响应式页面开发基础

前端设计-Ajax技术及实例展示

天躺在床上刷抖音的时候,看见了一个马克笔随便画星空的视频,很有意思。


先看效果:


开始需求分析:

1、渐变色的背景

2、画一颗树和一些草

3、水面的倒影

4、随便画点星星

5、画一颗流星


1、渐变色的背景

先确定200*500的区域,使用css3的线性渐变属性,依次深蓝、浅蓝、紫色、粉色、黄色画出一个渐变色的背景。

为了使背景更真实,使用同样的颜色顺序,在不同的角度,加上一些模糊和透明。再画一遍重叠起来。

再重叠一层黑色,使画布更暗一些。

.bg-color {
  background-image: linear-gradient(170deg, #000093 13%, #9f35ff, #ff8000 70%, #f9f900 );
}
.bg-color2 {
  background-image: linear-gradient( 180deg, #000093 13%, #9f35ff, #ff8000 80%, #f9f900 );
  opacity: 0.3;
  filter: blur(6px);
}
.bg-color3 {
  background: rgba(0,0,0,.2);
}


2、画一棵树和草

使用html来画一棵树的话,需要很多个节点,性能和效果都很差。这里使用canvas来画树。

画树的教程,公众号出过好几次了,这里就不在重写了。

基本原理就是,从一个点向一个方向画一条直线。从终点开始,重新这个流程。期间可以修改一个角度画出一分支。

草就更加简单。随便在底部画一些杂乱的直线。

// 画一棵树
function drawTree(x, y, deg, step, type) {
  var deg1 = step % 2 == 0 ? 0.1 : -0.1;
  var x1 = x + Math.cos(deg + deg1) * (step + 5) * 0.9;
  var y1 = y + Math.sin(deg + deg1) * (step - 1) * 0.9;
  ctx.beginPath();
  ctx.lineWidth = step / 3;
  ctx.moveTo(x, y);
  ctx.lineTo(x1, y1);
  ctx.stroke();
  if (step > 12) {
    ctx.arc(x, y, step / 6, 0, Math.PI * 2);
    ctx.fill();
  }
  if (step < 3 && Math.random() > 0.7) {
    var r = 2 + Math.random() * 2;
    ctx.arc(x1 + Math.random() * 3, y1 + Math.random() * 3, r, r, Math.PI + r);
    ctx.fill();
  }
  step--;
  if (step > 0) {
    drawTree(x1, y1, deg, step, type);
    if (step % 2 == 1 && step < 17)
      drawTree(x1, y1, deg + 0.2, Math.round(step / 1.13));
    if (step % 2 == 0 && step < 17)
      drawTree(x1, y1, deg - 0.2, Math.round(step / 1.13) );
  }
}


3、水面的倒影

最简单的做法,就是使用canvas.toDataUrl 拿到canvas的图片数据。在底部放一个反转的图片就可以。

我这里希望水面的倒影可以动起来。

新建一个canvas,使用ctx.getImageData拿到我们画好的树的像素点数据。

使用正弦给像素的x轴做一些偏移,得到一个新的数据。put到倒影的canvas上。

在使用requestAnimationFrame,做出一个流畅的左右摆动的倒影动画。

最后,在原数据基础上,增加一些杂色,使得倒影有一些黑白的横线,模拟水波的高亮。

var startWave = 0 // 水波起始位置
// 倒影增加水波纹效果
function wave(star){
  var newImgData = ctxShadow.createImageData(200,150)
  var pos = 0
  var source = 0
  startWave += 0.2
  start = startWave
  for(var y = 0 ; y < CANVAS_HEIGHT ; y ++) {
    start += 0.5
    for(var x = 0 ; x < CANVAS_WIDTH ; x ++) {
      pos = (y * CANVAS_WIDTH + x) * 4
      source = (y * CANVAS_WIDTH + x + Math.round(Math.sin(start)* 1.5)) * 4
      newImgData.data[pos + 0] = imgData.data[source + 0];
      newImgData.data[pos + 1] = imgData.data[source + 1];
      newImgData.data[pos + 2] = imgData.data[source + 2];
      newImgData.data[pos + 3] = imgData.data[source + 3];
    }
  }
  ctxShadow.putImageData(newImgData,0,0)
  requestAnimationFrame(wave)
}


4、画星空

这个简单,就不再写代码了,就随意写一些白色的div,随机插入背景上。


其实到这一步,已经基本上完成了。


5、加一些流星

要画流星,需要画出一个渐渐变淡变窄的白线。

这里偷了个懒,在视觉效果上,一个渐渐变淡的白线,人眼看到,就感觉渐渐变窄。

这里使用白色加透明渐变,画出一个流星的轮廓。加入从右到左动画效果。

再加入一个外包的div,做一下旋转和缩放。


效果完成!!!!


具体效果,建议查看原文。

代码仓库地址:

https://github.com/shb190802/html5

演示地址:

http://suohb.com/demo/win/starrySky.html