网页实现拍照,涂鸦,背景三合一的基础功能

<!DOCTYPE html>
<html lang="en">

<head>
	<title>相机测试</title>
	<script src="./jquery-3.5.1.min.js"></script>
	<style>
		* {
			padding: 0;
			margin: 0;
			box-sizing: border-box;
		}

		#pictureBox {
			background: red;
			width: 100%;
			height: 100%;
			position: fixed;
		}

		.btn {
			width: 180px;
			height: 87px;
			text-align: center;
			line-height: 87px;
			border-radius: 4px;
			background: #ff5415;
			text-align: center;
			color: #fff;
			cursor: pointer;
			border: none;
			font-size: 36px;
		}

		#camera-video {
			width: 493px;
			height: 500px;
			border-radius: 4px;
			position: absolute;
			right: 0;
			top: 80px;
			z-index: 99;
			background: #000;
		}

		#camera-canvas {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
		}

		canvas {
			width: 600px;
			height: 300px;
			border: 1px solid #ff5415;
			border-radius: 4px;
			margin-left: 5px;
		}

		.camera-warpper {
			width: 100%;
		}

		.video-container {}

		.btns {
			width: 500px;
			padding: 15px 37px;
			position: absolute;
			top: 580px;
			right: 0;
		}

		.btns>img {
			margin: 15px;
		}

		button+button {
			margin-left: 10px;
		}

		/* 视频留言 */
		#videoCard {
			width: 600px;
			height: 300px;
			border: 1px solid #000;
			margin: 0 auto;
			padding: 5px;
		}

		.cardVideoPart {
			border: blue 1px solid;
		}

		/* 画笔控制 */
		.centerBtn {
			padding: 20px 0;
			display: flex;
			align-items: center;
			justify-content: center;
			position: absolute;
			bottom: 40px;
			left: 99px;
		}

		.centerBtn>span {
			font-size: 36px;
			color: #fff;
			margin: 0 20px;
		}

		/* 画笔颜色 */
		.circleList {
			margin-left: 30px;
			display: flex;
			align-items: center;
			justify-content: center;
		}

		.circleList>span {
			font-size: 36px;
			color: #fff;
			margin-left: 16px;
			margin-right: 40px;
		}

		.open {
			position: absolute;
			right: 110px;
			top: 265px;
			z-index: 101;
		}

		#clean {
			margin-left: 80px;
		}

		/* 保存后的弹窗 */
		#endMask {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
			background: rgba(0, 0, 0, 0.5);
			z-index: 102;
			display: none;
		}

		#endMask>.img {
			width: 1420px;
			height: 799px;
			background: #fff;
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
			padding: 10px;
		}

		#endMask>.img>img {
			width: 100%;
			height: 100%;
		}

		#endMask>.btn {
			position: absolute;
			left: 50%;
			bottom: 25px;
			transform: translate(-50%);
		}
	</style>

	<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> -->
</head>

<body>
	<div id="pictureBox">
		<div class="camera-warpper">
			<div class="video-container">
				<video id="camera-video" onclick="takePicture()"></video>
				<div>
					<canvas id="camera-canvas" width="500" height="500"></canvas>
				</div>

			</div>
			<div class="centerBtn">
				<div class="circleList">
					<img src="./img/white.png" onclick="changeColor('white')" alt=""><span>白色</span>
					<img src="./img/black.png" onclick="changeColor('black')" alt=""><span>黑色</span>
				</div>
				<span>细</span>
				<input type="range" min="0" max="20" step="1" class="custom-range" id="customRange1"
					style="width: 150px;">
				<span>粗</span>
				<img src="./img/clear.png" id="clean" alt="">

			</div>
			<!-- 照片模式 -->
			<div class="btns">
				<img src="img/tackePicture.png" onclick="takePicture()" alt="">
				<img src="img/savePicture.png" onclick="downPhoto()" alt="">
				<img src="img/again.png" onclick="again()" alt="">
				<img src="img/quit.png" onclick="goHome()" alt="">
			</div>
			<div class="open" id="open">
				<img src="./img/open.png" onclick="openCamera()" alt="">
			</div>
		</div>
		<!-- 保存后的弹窗 -->
		<div id="endMask">
			<!-- 保存后的签名图片 -->
			<div class="img">
				<img src="./img/cePicture.png" alt="">
			</div>
			<div class="btn">
				<img src="img/quit.png" onclick="hideEndMask()" alt="">
			</div>
		</div>
	</div>

</body>
<script>
	var windowWidth = window.screen.width;
	var windowHeight = window.screen.height;
	console.log("屏幕高", windowWidth);
	console.log("屏幕宽", windowHeight);
	const config = {
		// video属性设置
		video: {
			width: 500,
			height: 500
		},
		// audio属性设置
		audio: true
	}
	// 展示签名图
	var endMask = document.getElementById("endMask");
	// 开启摄像头
	const open = document.getElementById('open');
	const video = document.getElementById('camera-video');
	const canvas = document.getElementById("camera-canvas");
	var ctx = canvas.getContext('2d');
	var img = new Image();
	img.src = "img/pictureBanner.png";
	img.onload = function () {
		drawPicture();
	}

	function drawPicture() {
		ctx.drawImage(img, 0, 0, windowWidth, windowHeight);
	}



	/**
	 * 开启摄像
	 */
	function openCamera() {
		navigator.mediaDevices.getUserMedia(config).then(mediaStream => {
			//接收一个mediaStream参数与video标签进行对接
			console.log(mediaStream);
			open.style.display = "none";
			video.srcObject = mediaStream;
			video.play();
		}).catch((err) => {
			console.error(err);
		});
	}

	/**
	 * 拍照、canvas绘制
	 */
	function takePicture() {
		ctx.drawImage(video, 1427, 80, config.video.width, config.video.height);
		// 预览框照片隐藏
		video.style.display = "none";
	}

	// 重新拍照
	function again() {
		// 预览框照片隐藏
		video.style.display = "block";
	}
	var newStr = sessionStorage.getItem("userName");
	var str; //图片名称

	/**
	 * canvas下载图片
	 */
	function downPhoto() {
		const MIME_TYPE = "image/png";
		const dlLink = document.createElement('a');
		// 图片名称
		str = sessionStorage.getItem("userName");
		dlLink.download = `${str}`;
		// 图片地址
		dlLink.href = canvas.toDataURL(MIME_TYPE);


		// 压缩方法1
		compress(
			dlLink.href, //别人传过来的图片
			1, //越小越清晰
			function (base64) {

				// console.log("最新压缩", base64) //压缩后的图片大小
				AAA(base64)
			}
		)
		console.log("最新压缩", newStr) //压缩后的图片大小

		console.log("下载地址", dlLink.href);
		dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');
		document.body.appendChild(dlLink);
		dlLink.click();
		document.body.removeChild(dlLink);
		// 展示签名图
		setTimeout(() => {
			endMask.style.display = "block";
		}, 2000);

	}

	function AAA(params) {
		console.log("最新压缩aaaa", params);
		console.log("图片名字", newStr);
	}

	function draw() {
		var pattern = ctx.createPattern(img, "no-repeat")
		ctx.fillStyle = pattern;
		ctx.fillRect(0, 0, 500, 500)
	}

	// 涂鸦


	// 画板大小 windowWidth, windowWidth
	canvas.width = windowWidth
	canvas.height = windowHeight
	// 背景颜色
	ctx.fillStyle = 'white'
	ctx.fillRect(0, 0, canvas.width, canvas.height)

	// 线宽提示
	var range = document.getElementById('customRange1')
	range.oninput = function () {
		this.title = 'lineWidth: ' + this.value
	}

	var lineColor = "white"
	//线条颜色
	function changeColor(color) {
		console.log("color", color);
		lineColor = color;
	}


	// 开始绘画  判断是不是触摸屏
	if ('ontouchstart' in window) {
		console.log("触摸屏",ctx);
		
		ctx.clearRect(0, 0, windowWidth, windowHeight);
		let x = 0;
		let y = 0;
		//触屏下,需要计算画布内焦点的坐标
		let vertex = canvas.getBoundingClientRect();
		$('#camera-canvas').on('mousedown touchstart', function (e) {
			//禁用事件默认动作,如果不加,再触屏情况下,可能出现问题
			e.preventDefault();
			ctx.beginPath();
			x = e.offsetX || (e.originalEvent.changedTouches[0].pageX - vertex.left);
			y = e.offsetY || (e.originalEvent.changedTouches[0].pageY - vertex.top);
			ctx.lineTo(x, y);
			ctx.stroke();

			$('#camera-canvas').on('mousemove touchmove', function (e) {
				x = e.offsetX || (e.originalEvent.changedTouches[0].pageX - vertex.left);
				y = e.offsetY || (e.originalEvent.changedTouches[0].pageY - vertex.top);
				ctx.lineTo(x, y);
				ctx.lineWidth = range.value;
				ctx.strokeStyle = lineColor;
				ctx.stroke();
			});
		});
		$('#camera-canvas').on('mouseleave mouseup touchend', function (e) {
			$('#signatureCanvas').off('mousemove touchmove');
			ctx.closePath();
		});
	} else {
		console.log("鼠标",ctx);
		var Mouse = {
			x: 0,
			y: 0
		}
		var lastMouse = {
			x: 0,
			y: 0
		}
		var painting = false

		canvas.onmousedown = function () {
			painting = !painting
		}


		canvas.onmousemove = function (e) {
			lastMouse.x = Mouse.x
			lastMouse.y = Mouse.y
			Mouse.x = e.pageX - this.offsetLeft
			Mouse.y = e.pageY - this.offsetTop
			if (painting) {
				/*
				画笔参数:
				    linewidth: 线宽
				    lineJoin: 线条转角的样式, 'round': 转角是圆头
				    lineCap: 线条端点的样式, 'round': 线的端点多出一个圆弧
				    strokeStyle: 描边的样式, 'white': 设置描边为白色
				*/
				ctx.lineWidth = range.value
				ctx.lineJoin = 'round'
				ctx.lineCap = 'round'
				ctx.strokeStyle = lineColor

				// 开始绘画
				ctx.beginPath()
				ctx.moveTo(lastMouse.x, lastMouse.y);
				ctx.lineTo(Mouse.x, Mouse.y);
				ctx.closePath()
				ctx.stroke()
			}
		}

		canvas.onmouseup = function () {
			painting = !painting
		}
	}






	// 清空画布
	var clean = document.getElementById('clean')
	clean.onclick = function () {
		ctx.clearRect(0, 0, canvas.width, canvas.height)
		ctx.fillStyle = 'white'
		ctx.fillRect(0, 0, canvas.width, canvas.height)
		var img = new Image();
		img.src = "img/pictureBanner.png";
		img.onload = function () {
			drawPicture();
		}
		location.reload([bForceGet])
	}

	// 返回首页
	function goHome() {
		window.location.href = 'home.html';
	}

	function hideEndMask() {
		endMask.style.display = "none";
	}


	//压缩方法1
	function compress(
		base64, // 源图片
		rate, // 缩放比例
		callback // 回调
	) {
		//处理缩放,转格式
		var _img = new Image();
		_img.src = base64;
		_img.onload = function () {
			var _canvas = document.createElement("canvas");
			var w = this.width / rate;
			var h = this.height / rate;
			_canvas.setAttribute("width", w);
			_canvas.setAttribute("height", h);
			_canvas.getContext("2d").drawImage(this, 0, 0, w, h);
			var base64 = _canvas.toDataURL("image/jpeg");
			_canvas.toBlob(function (blob) {
				if (blob.size > 300 * 1024) { //如果还大,继续压缩,不超过300kb
					compress(base64, rate, callback);
				} else {
					callback(base64);
				}
			}, "image/jpeg");
		}
	}
</script>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值