1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Canvas星空效果(JS面向对象)

Canvas星空效果(JS面向对象)

时间:2019-03-27 03:45:22

相关推荐

Canvas星空效果(JS面向对象)

概述

更多Canvas实例可以看GitHub,不定时更新:/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&#26143;&#31354;&#25928;&#26524;</a> by Luke.Deng (<a href="https://codepen.io/xiangshuo1992">@xiangshuo1992</a>) on <a href="https://codepen.io">CodePen</a>.&#10;

代码实现

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 () {//获取canvascanvas = 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 contextcontext.save();//move into the middle of the canvas,just make roomcontext.translate(this.x, this.y);//change the opacityif (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(只列举用到的)

//获取canvascanvas = document.getElementById('canvas');//获取canvas执行上下文context = canvas.getContext('2d');//用于保存当前绘图环境context.save();//用户恢复最近一次的绘图环境context.restore();//开始一段新的路径绘图context.beginPath();//结束当前路径绘图context.closePath();//绘制起点到(x,y)点的直线context.lineTo(x, y);//当前绘图环境位移,水平X,垂直ycontext.translate(x, y);//当前绘图环境旋转angle度(弧度制)degree * Math.PI / 180context.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*/ }

总结

纸上得来终觉浅,绝知此事要躬行!——《冬夜读书示子聿》陆游

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。