说明&使用

项目仅用于测试交流, 如有侵权, 请联系我删除.
引擎版本: LayaAir2.10.0
Github地址: LayaEffect
clone LayaEffect项目 → 打开 Lightning.scene 场景 → F6 编译运行

注:

由于laya引擎代码可能随着版本更新进行优化, 此项目目前只在2.10.0版本运行通过.

思路

● 通过 CanvasRenderingContext2D 绘制图案
● 通过 Laya.Sprite.graphics.drawImage 将图案显示在 Sprite 中

效果

实现

管理类

import { Lightning } from "./Lightning";
import { LightningCfg } from "./LightningCfg";
import { LightningVector } from "./LightningVector";/** 闪电管理器 */
export class LightningMgr {private static _ins: LightningMgr;public static get ins() {if (!this._ins) {this._ins = new LightningMgr();}return this._ins;}private isInit: boolean = false;private sprite: Laya.Sprite;private canvas: Laya.HTMLCanvas;private lightning: Lightning;private lightningCfg: LightningCfg;private isDrawing: boolean = true;private points: LightningVector[] = [];private posVec: LightningVector;public init(sprite: Laya.Sprite) {if (!this.isInit) {this.isInit = true;this.sprite = sprite;this.canvas = new Laya.HTMLCanvas(true);this.canvas.size(Laya.stage.width, Laya.stage.height);this.lightningCfg = new LightningCfg();this.lightning = new Lightning(this.lightningCfg);this.posVec = new LightningVector(0, 0, 0, 0);this.points.push(new LightningVector(0, 0, this.canvas.width / 2, this.canvas.height / 2));this.points.push(new LightningVector(0, 0, 20, 20));this.points.push(new LightningVector(0, 0, this.canvas.width / 2, 20));this.points.push(new LightningVector(0, 0, this.canvas.width - 20, 20));this.points.push(new LightningVector(0, 0, 20, this.canvas.height - 20));this.points.push(new LightningVector(0, 0, this.canvas.width / 2, this.canvas.height - 20));this.points.push(new LightningVector(0, 0, this.canvas.width - 20, this.canvas.height - 20));}}public startTimer() {if (this.isInit) {this.stopTimer();Laya.timer.frameLoop(1, this, this.update);}}public stopTimer() {Laya.timer.clearAll(this);}public beginDraw(posX: number, posY: number) {if (this.isInit) {this.isDrawing = true;this.posVec.X = 0;this.posVec.Y = 0;this.posVec.X1 = posX;this.posVec.Y1 = posY;}}public pauseDraw() {this.isDrawing = false;}private update() {if (this.isDrawing) {this.canvas.clear();        // 清空画布内容this.points.forEach(lightningVec => {this.lightning.cast(this.canvas.context as any, lightningVec, this.posVec);});this.sprite.graphics.drawImage(this.canvas.getTexture());}}/** 清空画布内容 */public clearCanvas() {if (this.canvas) {this.canvas.clear();}}public destroy() {this.stopTimer();this.canvas.clear();        // 清空画布, 释放GPU空间占用this.canvas.destroy();      // 销毁画布, 释放CPU空间占用this.canvas = null;this.sprite = null;this.lightningCfg = null;this.lightning = null;this.points = [];this.isInit = false;}
}

配置类

/** 闪电配置 */
export class LightningCfg {public segments: number = 40;// 值越大, 固定点显示越多public threshold: number = 0.5;public circle = {// 线尺寸lineWidth: 1,// 线颜色strokeStyle: "#ffffff",// 线阴影尺寸(外边框)shadowBlur: 0.1,// 线阴影颜色shadowColor: "#006dff"}public line = {// 线尺寸lineWidth: 1,// 线颜色strokeStyle: "#ffffff",// 线阴影尺寸(外边框)shadowBlur: 5,// 线阴影颜色shadowColor: "#127bca"}
}

闪电类

import { LightningCfg } from "./LightningCfg";
import { LightningVector } from "./LightningVector";/** 闪电类 */
export class Lightning {public config: LightningCfg;constructor(cfg: LightningCfg) {this.config = cfg;}public cast(context: CanvasRenderingContext2D, from: LightningVector, to: LightningVector) {if (!from || !to) {return;}// 主节点let mainVector = new LightningVector(from.X1, from.Y1, to.X1, to.Y1);// skip cas if not close enoughif (this.config.threshold && mainVector.length() > context.canvas.width * this.config.threshold) {return;}// 两点间总长度let mainLength = mainVector.length();// 两点间长度/画布宽度let posLenRateInCanvas = (mainLength / context.canvas.width)// 使用的节点数let usingSegmentCount = Math.floor(this.config.segments * posLenRateInCanvas);// 每个节点间宽度let perNodeDis = mainLength / usingSegmentCount;let fromPos = from;for (let i = 1; i <= usingSegmentCount; i++) {// position in the main vectorlet tempPos = mainVector.multiply((1 / usingSegmentCount) * i);// add position noiseif (i != usingSegmentCount) {tempPos.X1 += perNodeDis * Math.random();tempPos.Y1 += perNodeDis * Math.random();}// new vector for segmentlet toPos = new LightningVector(fromPos.X1, fromPos.Y1, tempPos.X1, tempPos.Y1);// main linethis.line(context, toPos);fromPos = toPos;}this.circle(context, from, posLenRateInCanvas);this.circle(context, to, posLenRateInCanvas);context.restore();}private circle(context: CanvasRenderingContext2D, pos: LightningVector, posLenRateInCanvas: number) {let cfg = this.config;context.shadowBlur = cfg.circle.shadowBlur;context.shadowColor = cfg.circle.shadowColor;context.strokeStyle = cfg.circle.strokeStyle;context.lineWidth = cfg.circle.lineWidth;context.beginPath();context.arc(pos.X1 + Math.random() * 10 * posLenRateInCanvas,            // x                                                   pos.Y1 + Math.random() * 10 * posLenRateInCanvas,            // y                                                   5,                                                           // radius           半径0,                                                           // startAngle       开始角度 2 * Math.PI,                                                 // endAngle         结束角度      false                                                        // counterclockwise 逆时针方向      );context.stroke();}private line(context: CanvasRenderingContext2D, vec: LightningVector) {let cfg = this.config;context.shadowBlur = cfg.line.shadowBlur;             // 清除阴影context.shadowColor = cfg.line.shadowColor;context.strokeStyle = cfg.line.strokeStyle;context.lineWidth = cfg.line.lineWidth;context.beginPath();context.moveTo(vec.X, vec.Y);context.lineTo(vec.X1, vec.Y1);// context.globalAlpha = c.Alpha;context.stroke();}private random(min: number, max: number) {return Math.floor(Math.random() * (max - min)) + min;}
}

向量类

/** 闪电向量 */
export class LightningVector {public X: number;public Y: number;public X1: number;public Y1: number;constructor(x, y, x1, y1) {this.X = x;this.Y = y;this.X1 = x1;this.Y1 = y1;}delX() {return this.X1 - this.X;}delY() {return this.Y1 - this.Y;}normalized() {let len = this.length();return new LightningVector(this.X,this.Y,this.X + (this.delX() / len),this.Y + (this.delY() / len));}length() {return Math.sqrt(Math.pow(this.delX(), 2) + Math.pow(this.delY(), 2));}multiply(num: number) {return new LightningVector(this.X,this.Y,this.X + this.delX() * num,this.Y + this.delY() * num);}clone() {return new LightningVector(this.X, this.Y, this.X1, this.Y1);}
}

场景控制类

import { ui } from "../../ui/layaMaxUI";
import { LightningMgr } from "./LightningMgr";export default class LightningSceneCtrl extends ui.canvas.LightningUI {onAwake(): void {console.log('onAwake');this.addUIEvent();}onEnable(): void {LightningMgr.ins.init(this.sp_lightning);LightningMgr.ins.startTimer();}addUIEvent() {Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onHandler);Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onHandler);Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onHandler);}removeUIEvent() {Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onHandler);Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onHandler);Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onHandler);}onHandler(e: Laya.Event) {switch (e.type) {case Laya.Event.MOUSE_DOWN:case Laya.Event.MOUSE_MOVE:LightningMgr.ins.beginDraw(e.stageX, e.stageY);break;case Laya.Event.MOUSE_UP:LightningMgr.ins.pauseDraw();break;}}onDestroy(): void {this.removeUIEvent();}
}

注:

● 将 LightningSceneCtrl 作为场景runtime控制类
● 可修改配置参数, 调节显示效果

Laya Canvas2D闪电特效相关推荐

  1. unity 实现闪电特效

    之前尝试过用trail实现闪电特效,效果并不理想:计算量大.视觉尴尬. 所以后来改用序列帧来实现. step1.准备素材 所需工具: AfterEffect [PhotoShop] 步骤: 1.打开A ...

  2. html生成闪电特效

    可以使用 HTML 和 CSS 来制作闪电特效.首先,使用 HTML 创建一个容器元素,如 div,然后在其中添加一些子元素,如线条或圆形,表示闪电.然后使用 CSS 来设置这些元素的位置.大小.颜色 ...

  3. cocos creator 绘制闪电特效

    核心算法来自这篇帖子,建议先看看原帖: [Cocos2d-x教程(20)-闪电效果]http://blog.csdn.net/u012945598/article/details/18862091 看 ...

  4. Laya Shader消融特效

    说明&使用 项目仅用于测试交流, 如有侵权, 请联系我删除. 引擎版本: LayaAir2.10.0 Github地址: LayaEffect clone LayaEffect项目 → 打开 ...

  5. scratch编程炫酷闪电特效

    scratch2.0编程的闪电主要是一个角色在黑色的背景中的两个角色之间来回移动转弯画出线条,我们先来看看效果: 它是来回移动的,我录不了视频,所以只能截屏了,你注意到了吗?没错,运行这个程序一定要开 ...

  6. UE4 闪电材质 及 闪电特效制作Niagara 学习笔记

    将扰动的输出最小值和最大值做为接近,不然闪电上的点是离散的不是连续的 选好了骨骼位置,然后在骨骼位置上生成粒子 将模型位置设置为骨骼位置类型 发送事件到另一个Emitter过去 将闪电材质放到Ribb ...

  7. 利用ps生成闪电特效

    1.CTRL+N生成500*200像素的背景文档,用渐变工具拉一个从上到下从黑到白的渐变填充,如下所示: 2.滤镜–渲染–分层云彩,得到如下效果(确保前景色与背景色为一黑一白): 3.CTRL+I反相 ...

  8. Unity 2D 闪电特效

    http://www.manew.com/thread-46958-1-1.html?_dsign=23e94f90

  9. Unity3d开发之二十:闪电

    实现原理: 1.逐帧运动的图片切换实现闪电的效果 2.设置出发点,方向,长度实现两点的电流 实现代码: 1.逐帧动画 Shader实现: Shader "Unlit/LightShader& ...

最新文章

  1. 04.微博消息的语言检测
  2. 图片裁剪的js有哪些(整理)
  3. linux 系统监控 php,Linux系统资源监控命令简介
  4. 【HDU - 6447】YJJ's Salesman(降维dp,树状数组优化dp)
  5. 想成为阿里160万年薪的P8架构师?你必须掌握如下6大技能体系!
  6. 将serversocket 写在按钮事件中连接不上_看 Netty 在 Dubbo 中如何应用
  7. ASP.NET在主题中添加CSS文件
  8. 让你见识一下什么叫最完整、最系统的前端学习路线
  9. window location href 手机端无法跳转_JavaScriptBOM__History_location(二十)
  10. 【集合论】集合概念与关系 ( 真子集 | 空集 | 全集 | 幂集 | 集合元素个数 | 求幂集步骤 )
  11. 离散数学及其应用 第二章:计数问题
  12. python安装mysqldb报错
  13. 360度全景标定方法_基于IMU辅助的360度全景视图多相机标定方法与流程
  14. 网易称暴雪离婚不离身;苹果发布 M2 Pro 和 M2 Max 芯片;滴滴出行 App 已重新上架安卓应用商店 | 极客头条...
  15. pdf做成翻页电子书_想看书就别用手机了,电子书选购指南
  16. CSS颜色属性、文本文字属性、属性继承
  17. 广义表的存储结构--头尾链表存储表示/扩展线性链表存储表示
  18. 【无标题】非专业45岁,目标:Python对表格的识别转换。(1)基础识别
  19. 让Android屏幕不响应任何点击
  20. 删除数组最后一个元素

热门文章

  1. [Python]简单几行代码带你完成Python切换代理IP
  2. (Java)设计模式——工厂模式
  3. 我国的煤炭资源量及其分布
  4. flash player的版本问题
  5. Selenium 安装、驱动
  6. 华为 android 11,安卓11华为能用吗_安卓11华为手机支持机型
  7. tfidf处理代码_解霸源代码学习——用TF-IDF方法计算词权,jieba,源码,TFIDF,权重
  8. YOLOv5火焰烟雾检测
  9. NotificationManager滑动不退出_切记,iPhone 不要滑动关后台 !
  10. C++ 类继承题目练习详解