canvas读取图片,输入文字,调整文字属性,拖拽文字位置,并保存图片

不是专门做前端的,代码写的不太好,权当抛砖引玉。

整体思路:
共有5层,除了背景颜色的div没什么用之外,canvas1用来读取图片作为背景,canvas2把文字展示出来,并记录拖拽文字的位置,canvas4 绘制拖拽后文字的位置,canvas3在最后保存的时候,把背景图片和文字重新绘制出来,canvas4用来把canvas1背景图片和canvas3拖拽后的文字给画到一个canvas上,保存图片,还有一个canvas,判断canvas1是不是空的。

除此之外,还用到了判断当前浏览器支持的字体,和颜色选择器,网络上都可以找到就不说了。

下边儿是效果和代码
请添加图片描述

代码如下

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
		<script type="text/javascript" src="js/font-ch-en.js" charset="utf-8"></script>
		<script type="text/javascript" src="js/isSupportFontFamily.js" charset="utf-8"></script>
		<script type="text/javascript" src="js/jquery1.4.3.js"  charset="utf-8"></script> 
		<script type="text/javascript" src="js/jquery.colorpicker.js"  charset="utf-8"></script>
		<style>
			td{
				text-align: center;
			}
		</style>
	</head>
	<body style="background-color: #F1F2F6;">
		<div>
			<div id="canvas_box" style="overflow: hidden;position: relative;">
				<div style="width: 900px;height: 600px;background: #333;float: left;border-radius: 10px;margin-left: 100px;margin-top: 40px;"></div>
				<canvas id="canvas3" style="width: 900px;height: 600px;display: block;position: absolute;margin-left: 100px;margin-top: 40px;" ></canvas>
				<canvas id="canvas4" style="width: 900px;height: 600px;display: block;position: absolute;margin-left: 100px;margin-top: 40px;" ></canvas>
				<canvas id="canvas1" style="width: 900px;height: 600px;display: block;position: absolute;margin-left: 100px;margin-top: 40px;" ></canvas>
				<canvas id="canvas2" style="width: 900px;height: 600px;display: block;position: absolute;margin-left: 100px;margin-top: 40px;" ></canvas>
			</div>
			<div style="position: absolute;margin-left: 1100px;margin-top: -500px;">
				<table style="border: solid 3px #7399cd;width: 280px;height: 360px;border-radius: 10px;">
					<tr>
						<td >
							<input type="button" value="请选择图片" onclick="javascript:$('input[name=\'file\']').click();" style="border-radius: 5px;background-color: #337AB7;color: #F2FFFF;border: none;height: 35px;width: 90px;"/>
							<input name="fileName" readonly  style="background-color: transparent;border:0;display: none;"/>
							<input type="file" name="file" id="fileOne" accept=".jpg,.png" style="display: none;" onchange="javascript:$('input[name=\'fileName\']').val(this.files[0].name);" />
						</td>
					</tr>
						<td>
							<div >请输入名字&nbsp;
								<input id="name" type="text" style="border-radius: 5px;border: 1px solid #3F3F40;width: 80px;" oninput="changeFont()" />
							</div>
						</td>
					<tr>
						<td>
							<div >请选择字体&nbsp;
								<select id="fontFam" style="border-radius: 5px;border-color: black;width: 88px;height: 22px;" onchange="changeFont()">
									<option>请选择</option>
								</select>
							</div>
						</td>
					</tr>
					<tr>
						<td>
							<div >请选择样式&nbsp;
								<select id="fontSty" style="border-radius: 5px;border-color: black;width: 88px;height: 22px;"  onchange="changeFont()">
									<option value="normal">正常</option>
									<option value="oblique">斜体</option>
								</select>
							</div>
						</td>
					</tr>
					<tr>
						<td>
							<div >请选择粗细&nbsp;
								<select id="fontSty" style="border-radius: 5px;border-color: black;width: 88px;height: 22px;"  onchange="changeFont()">
									<option value="normal">常规</option>
									<option value="600">斜体</option>
									<option value="900">斜体</option>
								</select>
							</div>
						</td>
					</tr>
					<tr>
						<td>
							<div >请选择字号&nbsp;
								<input id="Btn1" type="button" value="+" name=""/>
								<input id="fontSize" value="12" style="border-radius: 5px;border: 1px solid #3F3F40;width: 30px;text-align: center;height: 18px;" onchange="changeFont()"/>
								<input id="Btn2" type="button" value="-" name=""/>
							</div>
						</td>
					</tr>
					<tr>
						<td>
							<div >请选择颜色&nbsp;
								<input type="text" id="fontCol" value="#DBD71E" style="border-radius: 5px;border: 1px solid #3F3F40;width: 80px;" oninput="changeFont()" onchange="changeFont()"/>
							</div>
						</td>
					</tr>
					<tr>
						<td>
							<font style="color: red;" size="2">拖动左侧文字以调整位置</font>
						</td>
					</tr>
					<tr>
						<td >
							<input type="button" id="btn" value="下载图片" style="border-radius: 5px;background: #5CB85C;color: #fcfcf9;border: none;height: 35px;width: 90px;" onclick="downloadimg()"/>
						</td>
					</tr>
				</table>
				<div id="result">
				        
				    </div>
			</div>
		</div>
		<script>
			
			/*  canvas1	显示背景图片
				canvas2	显示文字,并记录拖拽文字的位置
				canvas4	绘制拖拽后文字的位置
				canvas3	最后保存的时候,把背景图片和文字重新绘制出来
			*/
			
			// 文字样式
			const fontSty = document.getElementById('fontSty');
			// 文字内容
			const name = document.getElementById("name");
			// 文字字体
			const fontFam = document.getElementById('fontFam');
			
			// 文字大小
			const fontSi = document.getElementById("fontSize");
			// 文字颜色
			const fontCol = document.getElementById("fontCol");
			
			const oBtn1=document.getElementById("Btn1");
			const oBtn2=document.getElementById("Btn2");
			
			const canvas1 = document.getElementById('canvas1');
			const ctx1 = canvas1.getContext('2d');
			
			const canvas2 = document.getElementById('canvas2');
			const ctx2 = canvas2.getContext('2d');
			
			const canvas3 = document.getElementById('canvas3');
			const ctx3 = canvas3.getContext('2d');
			
			const canvas4 = document.getElementById('canvas4');
			const ctx4 = canvas4.getContext('2d');
			
			const canvas5 = document.getElementById('canvas5');
			
			const inputOne = document.getElementById('fileOne');
			
			window.onload= function(){
				// 获取浏览器支持的字体
				loadFontFamily()
			}
			
			// 字号+-点击动作
			oBtn1.onclick = function(){
				num = fontSi.value;
				num++;
				fontSi.value = num;
				if ("createEvent" in document) {
					var evt = document.createEvent("HTMLEvents");
					evt.initEvent("change", false, true);
					fontSi.dispatchEvent(evt);
				} else {
					fontSi.fireEvent("onchange");
				}
			};
			oBtn2.onclick = function(){
				num = fontSi.value;
				num--;
				fontSi.value = num;
				if ("createEvent" in document) {
					var evt = document.createEvent("HTMLEvents");
					evt.initEvent("change", false, true);
					fontSi.dispatchEvent(evt);
				} else {
					fontSi.fireEvent("onchange");
				}
			}
			
			//颜色拾取器
			$("#fontCol").colorpicker({
			    target:'#title',
			    success:function(o,color){
			        fontCol.value = color
					if ("createEvent" in document) {
						var evt = document.createEvent("HTMLEvents");
						evt.initEvent("change", false, true);
						fontCol.dispatchEvent(evt);
					} else {
						fontCol.fireEvent("onchange");
					}
			    },
			    reset:function(o){
					fontCol.value = '#000000'
			    }
			});
			
			// 获取浏览器支持的字体
			function loadFontFamily(){
				// 数据
				var arrFont = dataFont['windows'].concat(dataFont['OS X'], dataFont['office'], dataFont['open']);
				var option = '';
				arrFont.forEach(function (obj) {
				    var fontFamily = obj.en;
				    if (isSupportFontFamily(fontFamily)) {
				        option = option + '<option value="'+ fontFamily +'">'+ obj.ch +'</option>';
				    }
				});
				fontFam.innerHTML = option;
				fontFam.value = "STXingkai";
			}
			
			//读取本地文件
			inputOne.onchange = function () {
				//1.获取选中的文件列表
				var fileList = inputOne.files;
				var file = fileList[0];
				//读取文件内容
				var reader = new FileReader();
				reader.readAsDataURL(file);
				reader.onload = function (e) {
					//将结果显示到canvas
					showCanvas(reader.result);
				}
			}
			
			//指定图片内容显示
			function showCanvas(dataUrl) {
				//加载图片
				var img = new Image();
				img.src = dataUrl;
				img.onload = function(){
					//设置宽高一定要在canvas节点添加之后
					canvas1.width = img.width;
					canvas1.height = img.height;
					canvas2.width = img.width;
					canvas2.height = img.height;
					
					ctx1.drawImage(this, 0, 0,img.width,img.height);
				}
			}
			
			//canvas2的拖拽动作
			var aa  = 0 
			var bb =  0 
			canvas2.onmousedown = function(args){
			    var evt = args || event;
				
			    var StartX = evt.clientX;
			    var StartY = evt.clientY;
			    let initleft = Number((canvas2.style.left).replace('px',''))
			    let inittop = Number((canvas2.style.top).replace('px',''))
				
			    document.onmousemove = function(ev){   
			        var iEvent = ev||event; 
			        // 鼠标移动的距离
			        let left = iEvent.clientX - StartX;
			        let top = iEvent.clientY - StartY;
			        // 鼠标移动的距离 + 最开始的top 或者 left 就是最终的位置
			        canvas2.style.left = left + initleft + 'px';
			        canvas2.style.top = top + inittop +'px';
					aa = (left + initleft)/900;
					bb = (top + inittop)/600;
					
			    }
			    document.onmouseup = function(){  
			        document.onmousedown = null;  
			        document.onmousemove = null;  
			    };  
			    return false;  
			}
			
			//验证canvas画布是否为空函数
			function isCanvasBlank(canvas) {
			    var blank = document.createElement('canvas');//系统获取一个空canvas对象
			    blank.width = canvas.width;
			    blank.height = canvas.height;
			    return canvas.toDataURL() == blank.toDataURL();//比较值相等则为空
			}
			//修改文字属性
			var fontStyle = ''
			var fontFamily = ''
			var fontSize = ''
			var fontt = ''
			var fontColor = ''
			function changeFont(){
				
				if(isCanvasBlank(canvas1)){
				    alert("请先选择图片");
				    return;
				}
				
				var text = name.value;
				fontStyle = fontSty.value;
				fontFamily = fontFam.value;
				fontSize = fontSi.value;
				fontt = fontStyle+' '+fontSize+'0px'+' '+ fontFamily;
				fontColor = fontCol.value;
				
				canvas2.width = canvas2.width
				canvas3.width = canvas3.width
				if(canvas2.getContext){
					ctx2.beginPath();
					ctx2.fillStyle = fontColor;// 设置填充画笔颜色为红色,即字体颜色
					ctx2.font = fontt;// 设置字体大小
					ctx2.fillText(text,700,1030);// 绘制 "实心" 文字
					// fillText(str, x, y, maxW):str绘制的文字,(x, y)起始坐标,maxW是最大宽度,绘制文字超过该宽度则不显示。
					ctx2.closePath();
				}else{
					alert('不支持');
				}
				
			 }
			 
			 //保存图片
			function downloadimg() {
				
				document.getElementById("btn").disabled = true;
				
				canvas3.getContext('2d');
				canvas3.width = canvas1.width;
				canvas3.height = canvas1.height;
				
				canvas4.width = canvas1.width;
				canvas4.height = canvas1.height;

				ctx4.beginPath();
				ctx4.fillStyle = fontColor;// 设置填充画笔颜色为红色,即字体颜色
				ctx4.font = fontt;// 设置字体大小
				ctx4.fillText(name.value,700+aa*canvas2.width,1030+bb*canvas2.height);// 绘制 "实心" 文字
				ctx4.closePath();
				
				ctx3.drawImage(canvas1, 0, 0, canvas1.width, canvas1.height);
				ctx3.drawImage(canvas4, 0, 0, canvas1.width, canvas1.height);
				
				// 创建一个 a 标签,并设置 href 和 download 属性
				const el = document.createElement('a');
				// 设置 href 为图片经过 base64 编码后的字符串,默认为 png 格式
				el.href = canvas3.toDataURL();
				el.download = name.value;
				// 创建一个点击事件并对 a 标签进行触发
				const event = new MouseEvent('click');
				el.dispatchEvent(event);
				
				canvas4.width = canvas1.width;
				
				document.getElementById("btn").disabled = false;
			}
		</script>
	</body>
</html>

tips:实际应用的时候,发现判断canvas为空这个比较耗资源,会导致填写文字的时候卡卡的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论

打赏作者

Naix1573

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值