// 画布宽-屏幕宽
const canvasWidth=window.screen.width;
// 画布高
const canvasHeight=window.screen.height;
// 圆形/巨型配置
let setting={}
// 圆形/巨型配置
const guideNewConfig={
type: 'circle',
dom: '#targetCity',
radius: 65
}
const stepClear=0.2;
/**
* @description 获取元素中心点
* @param {Document} element dom元素
* @returns {Object}
*/
function getElePositionCenter(element) {
const data = element.getBoundingClientRect();
return {
x: parseInt(data.left + data.width / 2, 10),
y: parseInt(data.top + data.height / 2, 10)
};
}
// 获取dom,获取dom相关位置信息
function initDom() {
const {
dom, // 目标元素
type, // 圆还是长方形
radius, // 圆角
width, // 宽
height// 高
} = guideNewConfig;// 传入的一些配置项
// 获取dom
setTimeout(() => {
const ballEle = document.querySelector(dom);
if (!ballEle) return;
const ballPos = getElePositionCenter(ballEle);
const { x, y } = ballPos || {};
const set = {
// 如果是在蒙层中画个圆
circle: {
radius,
srcPx: x,
srcPy: y,
},
// 如果是在蒙层中画个矩形
round: {
srcPx: x
srcPy: y,
width,
height
}
};
// 自定义调整位置
let left = x + 25;
let top = y + 25;
// 忽略这段代码 为了增加一些dom元素的样式
handEle.setAttribute('style', `
left: ${left}px;
top: ${top}px;
`);
// 忽略这段代码 为了增加一些dom元素的样式
tipEle.setAttribute('style', `
left: ${tipl}px;
top: ${tipt}px;
background-image:url(${this.tipUrl});
`);
setting = set[type];
initCanvas();
}, 0);
// 获取canvas
function initCanvas() {
const canvas = document.querySelector('#guideCanvas');
const context = canvas.getContext('2d');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
drawRect(context);
}
/**
* @description: 绘制图形蒙层和透明区域
* @param {*} ctx context
* @return {*}
*/
function drawRect(ctx) {
// 绘制黑色蒙层
ctx.fillStyle = 'rgba(0, 0, 0, 0.68)';
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// 画透明圆形区域
const { radius, srcPx, srcPy } = setting;
const {
type, // 圆还是长方形
width, // 宽
height// 高
} = guideNewConfig;
// 画圆
if (type === 'circle') {
clearCircle(ctx, srcPx, srcPy, radius);
// 画圆环减弱锯齿
ctx.beginPath();
ctx.strokeStyle = 'rgba(157, 157, 161, 1)';
ctx.arc(srcPx, srcPy, radius, 0, 2 * Math.PI);
ctx.stroke();
} else {
// 画矩形
drawRound(ctx, srcPx, srcPy, width, height, 10);
}
},
/**
* @description: 画透明圆形区域方法,主要使用 canvas 的 clearRect 方法
* @param {*} ctx context
* @param {Number} srcPx 起点x
* @param {Number} srcPy 起点y
* @param {Number} radius 圆半径
* @return {*}
*/
function clearCircle(ctx, srcPx, srcPy, radius) {
const calcWidth = radius - stepClear;
const calcHeight = Math.sqrt(radius * radius - calcWidth * calcWidth);
const posX = srcPx - calcWidth;
const posY = srcPy - calcHeight;
const widthX = 2 * calcWidth;
const heightY = 2 * calcHeight;
if (stepClear <= radius) {
ctx.clearRect(posX, posY, widthX, heightY);
stepClear += 1;
clearCircle(ctx, srcPx, srcPy, radius);
}
},
// 画圆角矩形
function drawRound(ctx, x, y, w, h, r) {
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(157, 157, 161, 1)';
ctx.stroke();
clearDrawEound(ctx);
ctx.fill();
},
// 清楚圆角矩形
function clearDrawEound(ctx) {
ctx.globalCompositeOperation = 'destination-out';
}
使用canvas实现刮刮乐功能
最新推荐文章于 2024-07-25 09:24:40 发布