JS框架_(JQuery.js)模拟刮奖
百度云盘:传送门 密码:6p5q
纯CSS模拟刮奖效果

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
} p {
position: fixed;
top: 60%;
left: 0;
right: 0;
text-align: center;
transform: translateY(-50%);
font-size: 40px;
font-weight: 900;
color: white;
text-shadow: 0 0 50px black;
text-transform: capitalize;
font-family: 'Roboto','Helvetica','Arial',sans-serif;
letter-spacing: 5px;
} .box{
margin: 80px;
position: relative;
width: 300px;
height: 180px;
left: 460px;
}
#canvas{
position: absolute;
top: 0;
left: 0;
z-index: 5;
}
.bk{
width: 300px;
height: 180px;
background: #fff;
position: absolute;
top: 0;
left: 0;
text-align: center;
line-height: 180px;
}
#freshBtn{
margin-left: 660px;
user-select: none;
background: #ddd;
width: 80px;
height: 40px;
text-align: center;
line-height: 40px;
}
</style>
<body>
<p>Gary</p>
<div class="box">
<div class="bk">
一等奖
</div>
<canvas id="canvas"></canvas>
</div>
<div id="freshBtn">重置</div>
</body>
<script src="./js/canvas.js"></script>
<script>
var canvas = new canvasInit({
id: 'canvas',
text: '刮开抽奖',
cover: '#1f1f1f',
coverType: 'color',
width: 300,
height: 180,
drawPercentCallback: (num) => {
if(num > 30) {
alert('恭喜获得一等奖')
canvas.fresh() // 重置
}
}
})
</script>
</html>
index.html
class canvasClass {
constructor (id,text,cover,coverType,width,height,drawPercentCallback) {
this.conId = id; /*canvasID */
this.conNode = document.getElementById(this.conId);
this.ctx = this.conNode.getContext('2d');
this.coverText = text;
this.cover = cover; /**图层颜色或图片 */
this.coverType = coverType; /**图层类型(image/color) */
this.width = width;
this.height = height;
this.drawPercentCallback = drawPercentCallback
this.clientRect = null;
this.isMouseDown = false;
}
/**
* 绘制canvas
*/
fillCanvas () {
this.conNode.setAttribute('width', this.width);
this.conNode.setAttribute('height', this.height);
if (this.coverType == 'color') {
this.ctx.save();
this.ctx.fillStyle = this.cover;
this.ctx.fillRect(0, 0, this.width, this.height);
this.ctx.restore();
this.ctx.save();
var fontSize = 30;
this.ctx.font = '30px Arial';
this.ctx.textAlign = 'center';
this.ctx.fillStyle = '#fff';
this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
this.ctx.restore();
this.ctx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image') {
var image = new Image(this.width, this.height)
image.onload = () => {
this.ctx.drawImage(image, 0, 0, this.width, this.height);
}
image.src = this.cover;
}
this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
}
/**
* 事件监听
*/
bindEvent () {
/**移动端检测 */
var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
var clickEvt = device ? 'touchstart' : 'mousedown';
var moveEvt = device ? 'touchmove' : 'mousemove';
var x1,y1,x2,y2;
if (!device) {
document.addEventListener('mouseup', (e) => {
this.isMouseDown = false;
})
} else {
document.addEventListener("touchmove", (e) => {
if (this.isMouseDown) {
e.preventDefault();
}
})
document.addEventListener("touchend", (e) => {
this.isMouseDown = false;
})
}
/**添加监听 */
this.conNode.addEventListener(clickEvt, (e) => {
this.isMouseDown = true;
x1 = device ? e.touches[0].offsetX : e.offsetX;
y1 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1)
})
this.conNode.addEventListener(moveEvt, (e) => {
if (!device && !this.isMouseDown) {
return false;
}
this.isMouseDown = true;
x2 = device ? e.touches[0].offsetX : e.offsetX;
y2 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1, x2, y2)
// console.log(x1,x2,y1,y2)
x1 = x2
y1 = y2
// [x1, y1] = [x2, y2]
})
}
/**
* 抹去, 返回百分比
*/
drawPoint (x1, y1, x2, y2) {
var bar = 20; // 半径
this.ctx.beginPath();
if (x2) {
/**
* 优化绘制路径
*/
var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
var x3 = x1+asin;
var y3 = y1-acos;
var x4 = x1-asin;
var y4 = y1+acos;
var x5 = x2+asin;
var y5 = y2-acos;
var x6 = x2-asin;
var y6 = y2+acos;
this.ctx.save();
this.ctx.beginPath();
this.ctx.moveTo(x3,y3);
this.ctx.lineTo(x5,y5);
this.ctx.lineTo(x6,y6);
this.ctx.lineTo(x4,y4);
this.ctx.closePath();
this.ctx.clip();
this.ctx.clearRect(0,0,this.width,this.height);
this.ctx.restore();
this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
} else {
this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
}
this.ctx.fill();
if (this.drawPercentCallback) {
this.drawPercentCallback(this.getTransparentPercent());
}
}
getTransparentPercent () {
var imgData = this.ctx.getImageData(0, 0, this.width, this.height),
pixles = imgData.data,
transPixs = [];
for (var i = 0, j = pixles.length; i < j; i += 4) {
var a = pixles[i + 3];
if (a < 128) {
transPixs.push(i);
}
}
return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
}
}
function canvasInit(json) {
var arr = []
for (let item in json) {
arr.push(json[item])
}
this.init = new canvasClass(...arr)
this.init.fillCanvas()
this.init.bindEvent()
var btn = document.querySelector('#freshBtn');
btn.addEventListener('click', (e) => {
this.init.fillCanvas()
});
}
canvasInit.prototype.fresh = function () {
console.log(this.init)
this.init.fillCanvas()
this.init.isMouseDown = false
}
canvas.css
(直接复制就可以使用了O(∩_∩)O~ ES6编写)
=>是es6语法中的arrow function(箭头函数)
举例:
(x) => x + 6
相当于
function(x){
return x + 6;
}
实现过程
CSS
画板.class
class canvasClass {
constructor (id,text,cover,coverType,width,height,drawPercentCallback) {
this.conId = id; /*canvasID */
this.conNode = document.getElementById(this.conId);
this.ctx = this.conNode.getContext('2d');
this.coverText = text;
this.cover = cover; /**图层颜色或图片 */
this.coverType = coverType; /**图层类型(image/color) */
this.width = width;
this.height = height;
this.drawPercentCallback = drawPercentCallback
this.clientRect = null;
this.isMouseDown = false;
}
/**
* 绘制canvas
*/
fillCanvas () {
this.conNode.setAttribute('width', this.width);
this.conNode.setAttribute('height', this.height);
if (this.coverType == 'color') {
this.ctx.save();
this.ctx.fillStyle = this.cover;
this.ctx.fillRect(0, 0, this.width, this.height);
this.ctx.restore();
this.ctx.save();
var fontSize = 30;
this.ctx.font = '30px Arial';
this.ctx.textAlign = 'center';
this.ctx.fillStyle = '#fff';
this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
this.ctx.restore();
this.ctx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image') {
var image = new Image(this.width, this.height)
image.onload = () => {
this.ctx.drawImage(image, 0, 0, this.width, this.height);
}
image.src = this.cover;
}
this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
}
/**
* 事件监听
*/
bindEvent () {
/**移动端检测 */
var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
var clickEvt = device ? 'touchstart' : 'mousedown';
var moveEvt = device ? 'touchmove' : 'mousemove';
var x1,y1,x2,y2;
if (!device) {
document.addEventListener('mouseup', (e) => {
this.isMouseDown = false;
})
} else {
document.addEventListener("touchmove", (e) => {
if (this.isMouseDown) {
e.preventDefault();
}
})
document.addEventListener("touchend", (e) => {
this.isMouseDown = false;
})
}
/**添加监听 */
this.conNode.addEventListener(clickEvt, (e) => {
this.isMouseDown = true;
x1 = device ? e.touches[0].offsetX : e.offsetX;
y1 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1)
})
this.conNode.addEventListener(moveEvt, (e) => {
if (!device && !this.isMouseDown) {
return false;
}
this.isMouseDown = true;
x2 = device ? e.touches[0].offsetX : e.offsetX;
y2 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1, x2, y2)
// console.log(x1,x2,y1,y2)
x1 = x2
y1 = y2
// [x1, y1] = [x2, y2]
})
}
/**
* 抹去, 返回百分比
*/
drawPoint (x1, y1, x2, y2) {
var bar = 20; // 半径
this.ctx.beginPath();
if (x2) {
/**
* 优化绘制路径
*/
var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
var x3 = x1+asin;
var y3 = y1-acos;
var x4 = x1-asin;
var y4 = y1+acos;
var x5 = x2+asin;
var y5 = y2-acos;
var x6 = x2-asin;
var y6 = y2+acos;
this.ctx.save();
this.ctx.beginPath();
this.ctx.moveTo(x3,y3);
this.ctx.lineTo(x5,y5);
this.ctx.lineTo(x6,y6);
this.ctx.lineTo(x4,y4);
this.ctx.closePath();
this.ctx.clip();
this.ctx.clearRect(0,0,this.width,this.height);
this.ctx.restore();
this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
} else {
this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
}
this.ctx.fill();
if (this.drawPercentCallback) {
this.drawPercentCallback(this.getTransparentPercent());
}
}
getTransparentPercent () {
var imgData = this.ctx.getImageData(0, 0, this.width, this.height),
pixles = imgData.data,
transPixs = [];
for (var i = 0, j = pixles.length; i < j; i += 4) {
var a = pixles[i + 3];
if (a < 128) {
transPixs.push(i);
}
}
return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
}
}
class canvasClass
1、绘制canvas画布
2、添加事件监听
3、刮奖效果
构造函数省略...
1、绘制canvas画布
fillCanvas () {
this.conNode.setAttribute('width', this.width);
this.conNode.setAttribute('height', this.height);
if (this.coverType == 'color') {
this.ctx.save();
this.ctx.fillStyle = this.cover;
this.ctx.fillRect(0, 0, this.width, this.height);
this.ctx.restore();
this.ctx.save();
var fontSize = 30;
this.ctx.font = '30px Arial';
this.ctx.textAlign = 'center';
this.ctx.fillStyle = '#fff';
this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
this.ctx.restore();
this.ctx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image') {
var image = new Image(this.width, this.height)
image.onload = () => {
this.ctx.drawImage(image, 0, 0, this.width, this.height);
}
image.src = this.cover;
}
this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
}
2、添加事件监听
bindEvent () {
/**移动端检测 */
var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
var clickEvt = device ? 'touchstart' : 'mousedown';
var moveEvt = device ? 'touchmove' : 'mousemove';
var x1,y1,x2,y2;
if (!device) {
document.addEventListener('mouseup', (e) => {
this.isMouseDown = false;
})
} else {
document.addEventListener("touchmove", (e) => {
if (this.isMouseDown) {
e.preventDefault();
}
})
document.addEventListener("touchend", (e) => {
this.isMouseDown = false;
})
}
/**添加监听 */
this.conNode.addEventListener(clickEvt, (e) => {
this.isMouseDown = true;
x1 = device ? e.touches[0].offsetX : e.offsetX;
y1 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1)
})
this.conNode.addEventListener(moveEvt, (e) => {
if (!device && !this.isMouseDown) {
return false;
}
this.isMouseDown = true;
x2 = device ? e.touches[0].offsetX : e.offsetX;
y2 = device ? e.touches[0].offsetY : e.offsetY;
this.drawPoint(x1, y1, x2, y2)
// console.log(x1,x2,y1,y2)
x1 = x2
y1 = y2
// [x1, y1] = [x2, y2]
})
}
3、刮奖效果
drawPoint (x1, y1, x2, y2) {
var bar = 20; // 半径
this.ctx.beginPath();
if (x2) {
/**
* 优化绘制路径
*/
var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
var x3 = x1+asin;
var y3 = y1-acos;
var x4 = x1-asin;
var y4 = y1+acos;
var x5 = x2+asin;
var y5 = y2-acos;
var x6 = x2-asin;
var y6 = y2+acos;
this.ctx.save();
this.ctx.beginPath();
this.ctx.moveTo(x3,y3);
this.ctx.lineTo(x5,y5);
this.ctx.lineTo(x6,y6);
this.ctx.lineTo(x4,y4);
this.ctx.closePath();
this.ctx.clip();
this.ctx.clearRect(0,0,this.width,this.height);
this.ctx.restore();
this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
} else {
this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
}
this.ctx.fill();
if (this.drawPercentCallback) {
this.drawPercentCallback(this.getTransparentPercent());
}
}
初始化canvas.class画布
function canvasInit(json) {
var arr = []
for (let item in json) {
arr.push(json[item])
}
this.init = new canvasClass(...arr)
this.init.fillCanvas()
this.init.bindEvent()
var btn = document.querySelector('#freshBtn');
btn.addEventListener('click', (e) => {
this.init.fillCanvas()
});
}
按钮
#freshBtn{
margin-left: 660px;
user-select: none;
background: #ddd;
width: 80px;
height: 40px;
text-align: center;
line-height: 40px;
}
刮奖区域
.box{
margin: 80px;
position: relative;
width: 300px;
height: 180px;
left: 460px;
}
DOM
设置文档内容和显示文本
<div class="box">
<div class="bk">
一等奖
</div>
<canvas id="canvas"></canvas>
</div>
<div id="freshBtn">重置</div>
模拟抽奖效果时bk中文字可以用随机
给canvas.class画布传参
<script>
var canvas = new canvasInit({
id: 'canvas',
text: '刮开抽奖',
cover: '#1f1f1f',
coverType: 'color',
width: 300,
height: 180,
drawPercentCallback: (num) => {
if(num > 30) {
alert('恭喜获得一等奖')
canvas.fresh() // 重置
}
}
})
</script>
JS框架_(JQuery.js)模拟刮奖的更多相关文章
- JS框架_(JQuery.js)绚丽的3D星空动画
百度云盘: 传送门 密码:8ft8 绚丽的3D星空动画效果(纯CSS) (3D星空动画可以用作网页背景,Gary为文本文字) <!doctype html> <html lang=& ...
- JS框架_(JQuery.js)圆形多选菜单选项
百度云盘 传送门 密码:zb1c 圆形多选菜单选项效果: <!DOCTYPE html> <html lang="en" > <head> &l ...
- JS框架_(JQuery.js)Tooltip弹出式按钮插件
百度云盘 传送门 密码:7eh5 弹出式按钮效果 <!DOCTYPE html> <html > <head> <meta charset="UTF ...
- JS框架_(JQuery.js)夜晚天空满天星星闪烁动画
百度云盘 传送门 密码:xftr 满天星星闪烁动画效果: (可用星空动画来作为页面背景,白色文字改为文章或者其他的O(∩_∩)O) <!doctype html> <html> ...
- JS框架_(JQuery.js)文章全屏动画切换
百度云盘 传送门 密码:anap 文章全屏动画切换效果 <!doctype html> <html lang="zh"> <head> < ...
- JS框架_(JQuery.js)动画效果鼠标跟随
百度云盘 传送门 密码 :4n9u 火狐浏览器上纯CSS_动画效果鼠标跟随效果: (作者:lily_lcj 传送门) <!DOCTYPE html PUBLIC "-//W3C//DT ...
- JS框架_(JQuery.js)点赞按钮动画
百度云盘 传送门 密码: 0ihy 点赞按钮动画效果: (点击一次随机生成一颗小爱心,作为点赞动画~) <!doctype html> <html lang="en&quo ...
- JS框架_(JQuery.js)图片相册掀开切换效果
百度云盘 传送门 密码:y0dk 图片掀开切换效果: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...
- JS框架_(JQuery.js)上传进度条
百度云盘 传送门 密码: 1pou 纯CSS上传进度条效果: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...
随机推荐
- liunx 安装rsync
新建一个rsync.s文件,把下面的代码写入文件里: #!/usr/bin/env bash mkdir -p /data/app/rsync/etc/ mkdir -p /data/logs/rsy ...
- mongodb 数据操作(2)
查询 db.student.find({}) 查询db.student.find({name:"李强1"}) 查询 条件查询 db.student.find({sex:&quo ...
- python之函数、面向对象
学习python到了函数这一块进度有所放缓,主要还是想理解透彻,毕竟直觉告诉我函数是python是其中的关键,不管是模块.还是包.或者是库,都是建立在若干个函数定义上面. 章节后面就是关于面向对象编程 ...
- 使用 vscode将本地项目上传到github、从github克隆项目以及删除github上的某个文件夹
安装Git后,可以看到windows环境下有两个命令输入窗口Git CMD 和Git Bash Git GUI是可视化图形界面 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能 ...
- Hive编程指南读书笔记(1):
1.Mapreduce是一种计算模型,将计算任务分割成多个可以在服务器集群中并行执行的任务,然后分散到一群家用的或者服务器级别的硬件机器上,从而降低成本并提供水平可伸缩性. 2.mapreduce的两 ...
- Hbase1.4.9的安装
HBase介绍 HBase – Hadoop Database,是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群. HB ...
- htpasswd 使用&&在线生成器
1.简单介绍 htpasswd-管理用于基本身份验证的用户文件. 这个文件可以用来控制nginx或Apache的目录访问控制权限,例如,nginx的在配置nginx_status的态的时候(如下图所示 ...
- linux centos 7安装 apache php 及mariadb
1安装Apache, PHP, MySQL以及php库组件. yum -y install httpd php mysql php-mysql 2 安装apache扩展 yum -y install ...
- 标准C语言(8)
指针变量用来记录地址数据,指针变量的用途就是找到另外一个变量,没有记录有效地址的指针不能用来找到其它变量,声明指针变量时必须在变量名称前写*.如果一个指针变量记录了另外一个变量的地址就可以认为它们之间 ...
- 标准C语言(6)
数组名称不可以代表任何存储区(数组名称不可以被赋值),数组名称可以代表数组里第一个存储区的地址 /* * 数组练习 * */ #include <stdio.h> #include < ...