Canvas星空效果(JS面向对象)
Posted 前端向朔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canvas星空效果(JS面向对象)相关的知识,希望对你有一定的参考价值。
概述
更多Canvas实例可以看GitHub,不定时更新:https://github.com/xiangshuo1992/canvas-demo
这个Demo主要有以下几点可以讨论:
1.html5 canvas的基础API,如 context.beginPath();
2.获取屏幕大小,并响应窗口大小变化
3.JS面向对象
先看效果 Canvas星空效果
width="100%" height="400" scrolling="no" title="Canvas星空效果" src="//codepen.io/xiangshuo1992/embed/MGgeOR/?height=265&theme-id=0&result&embed-version=2" allowfullscreen="true">See the Pen <a href="https://codepen.io/xiangshuo1992/pen/MGgeOR/">Canvas星空效果</a> by Luke.Deng (<a href="https://codepen.io/xiangshuo1992">@xiangshuo1992</a>) on <a href="https://codepen.io">CodePen</a>. 代码实现
HTML
<canvas id="canvas"></canvas>
CSS
#canvas
position: absolute;
left: 0;
top: 0;
background-color: #000;
JS
<script>
/**
* canvas 创建星空
*/
// 定义变量
let canvas,
context,
screenW,
screenH,
stars = [];
// 定义常量
const FPS = 50,
numStars = 2000;
window.onload = function ()
//获取canvas
canvas = document.getElementById('canvas');
// 设置画布大小
render();
//获取canvas执行上下文
context = canvas.getContext('2d');
// ===========组件应用层============
//创建星星
for (let i = 0; i < numStars; i++)
let x = Math.round(Math.random() * screenW);
let y = Math.round(Math.random() * screenH);
let length = 1 + Math.random() * 2;
let opacity = Math.random();
// 创建星星实例
let star = new Star(x, y, length, opacity);
stars.push(star);
// 星星闪动
setInterval(animate, 1000 / FPS);
// ============组件定制层==============
/**
* Star
*
* @param int x
* @param int y
* @param int length
* @param float opacity
*/
// 星星构造函数
function Star(x, y, length, opacity)
this.x = parseInt(x);
this.y = parseInt(y);
this.length = parseInt(length);
this.opacity = opacity;
this.factor = 1;
this.increment = Math.random() * 0.03;
//对象原型方法
/**
* 画星星
*
* @param context
*/
Star.prototype.draw = function (context)
context.rotate(Math.PI * 1 / 10);
//save the context
context.save();
//move into the middle of the canvas,just make room
context.translate(this.x, this.y);
//change the opacity
if (this.opacity > 1)
this.factor = -1;
else if (this.opacity <= 0)
this.factor = 1;
// 更新一次星星位置
this.x = Math.round(Math.random() * screenW);
this.y = Math.round(Math.random() * screenH);
// factor 控制方向,淡入或淡出,每次重绘,星星的透明度都在变化
this.opacity += this.increment * this.factor;
context.beginPath();
//画线
for (var i = 5; i > 0; i--)
context.lineTo(0, this.length);
context.translate(0, this.length);
context.rotate(Math.PI * 2 / 10);
context.lineTo(0, -this.length);
context.translate(0, -this.length);
context.rotate(-(Math.PI * 6 / 10));
context.lineTo(0, this.length);
context.closePath();
context.fillStyle = 'rgba(255,255,200, ' + this.opacity + ')';
context.shadowBlur = 5;
context.shadowColor = '#ffff33';
context.fill();
context.restore();
/**
* 获取窗口大小信息
*/
function getScreenInfo()
//获取窗口宽度
if (window.innerWidth)
winWidth = window.innerWidth;
else if ((document.body) && (document.body.clientWidth))
winWidth = document.body.clientWidth;
//获取窗口高度
if (window.innerHeight)
winHeight = window.innerHeight;
else if ((document.body) && (document.body.clientHeight))
winHeight = document.body.clientHeight;
//通过深入Document内部对body进行检测,获取窗口大小
if (document.documentElement &&
document.documentElement.clientHeight &&
document.documentElement.clientWidth)
winHeight = document.documentElement.clientHeight;
winWidth = document.documentElement.clientWidth;
// 将上述方法简化
// screenW = window.innerWidth ||
// document.body.clientWidth ||
// document.documentElement.clientWidth;
// screenH = window.innerHeight ||
// document.body.clientHeight ||
// document.documentElement.clientHeight;
return
'winWidth': winWidth,
'winHeight': winHeight
/**
* canvas设置,修复窗口变化,画布大小不变的问题
*/
function render()
//获取屏幕大小
screenW = getScreenInfo().winWidth;
screenH = getScreenInfo().winHeight;
// 设置canvas
// canvas.setAttribute('width', screenW);
// canvas.setAttribute('height', screenH);
canvas.width = screenW;
canvas.height = screenH;
window.addEventListener('resize', render);
/**
* 星星闪动函数
*/
function animate()
context.clearRect(0, 0, screenW, screenH);
for (let i = 0; i < stars.length; i++)
stars[i].draw(context);
</script>
HTML5 Canvas基础API(只列举用到的)
//获取canvas
canvas = document.getElementById('canvas');
//获取canvas执行上下文
context = canvas.getContext('2d');
//用于保存当前绘图环境
context.save();
//用户恢复最近一次的绘图环境
context.restore();
//开始一段新的路径绘图
context.beginPath();
//结束当前路径绘图
context.closePath();
//绘制起点到(x,y)点的直线
context.lineTo(x, y);
//当前绘图环境位移,水平X,垂直y
context.translate(x, y);
//当前绘图环境旋转angle度(弧度制)degree * Math.PI / 180
context.rotate(angle);
//设置或返回用于填充绘画的颜色、渐变或模式
context.fillStyle;
//填充当前绘图(路径)
context.fill()
//设置或返回用于阴影的模糊级别
context.shadowBlur
//设置或返回用于阴影的颜色
context.shadowColor
获取屏幕大小并监听
监听窗口/文档大小变化事件,保证canvas铺满屏幕
function render()
//获取屏幕大小
screenW = window.innerWidth ||
document.body.clientWidth ||
document.documentElement.clientWidth;
screenH = window.innerHeight ||
document.body.clientHeight ||
document.documentElement.clientHeight;
// 设置canvas大小
// canvas.setAttribute('width', screenW);
// canvas.setAttribute('height', screenH);
canvas.width = screenW;
canvas.height = screenH;
window.addEventListener('resize', render);
JS面向对象写法
//构造函数(类)
function Star(config)this.config = config;
//给类添加方法,JS用原型实现
Star.prototype.draw = function () /*do something*/
//实例化一个Star对象
let star = new Star(config)
当然这个对象写的不是很好,应该可以拆分出更细的一些操作放到原型上。
这里我把对象当组件来看,其实面向对象可能是组件化的一个过程。我们将面向对象的写法理解成组件化的过程可以这样理解:
============组件定制层==============
创建对象——>创建组件
对象属性——>组件配置属性
对象方法——>组件方法
============组件应用层==============
实例化对象——>实例化组件
之所以给组件分层,是因为除了基本的应用和定制层,一般组件还会有组件核心(基础)层
=========组件核心(基础)层==========
jQuery/Vue/…
ES6
const/let
// 定义变量
let canvas,
context,
screenW,
screenH,
stars = [];
// 定义常量
const FPS = 50,
numStars = 2000;
箭头函数
//ES6定义函数
let fn = (param)=> /*do something*/
//相当于
var fn = function(param) /*do something*/
总结
纸上得来终觉浅,绝知此事要躬行!——《冬夜读书示子聿》陆游
以上是关于Canvas星空效果(JS面向对象)的主要内容,如果未能解决你的问题,请参考以下文章