傻吊表情包加文字功能(canvas+node)
生活随笔
收集整理的這篇文章主要介紹了
傻吊表情包加文字功能(canvas+node)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
靈感來自微博@bangbang93
大佬寫了個記仇生成器,作為表情包大王的我不禁想學習一番。
然而菜雞如我,寫的還是有些不盡如人意,比如canvas圖片跨域問題還是沒有解決明白,圖片大的話保存速度會很慢,代碼有些地方略顯冗余等。希望有大佬指教一下。
<html> <head> <title>文件上傳</title> <style> #bigImg{ width:300px; height:239.31px; } #write{ width: 300px; border: none; overflow-y:visible; font-size: 15px; margin-top: 10px;} #canvas{ width:300px; height:300px; display: none;} #form{ display: none;} #sub{ margin-top: 20px;} </style> </head> <body> <div id="container"> </div> <script> var jc = new jichou({ container:"container",//容器 initImg:"", //初始圖片,不能跨域 initText:"", //初始文字,沒有默認“請輸入” method:"/upload",//提交位置 canvasWidth:300, canvasHeight:300, canvasFont:"normal normal normal 15px Microsoft YaHei UI", fontSize:12, lineHeight:20}) //構造函數 function jichou(jcObject){ let that = this; //默認文字 if(!jcObject.initText){ jcObject.initText = "請輸入"} //獲取id this.getId=function(id){ return document.getElementById(id)} //填充內容 var innerHTML = "<img id = 'bigImg' src="+jcObject.initImg+"><br />"; innerHTML += "<div id='write' contenteditable='true'/>"+jcObject.initText+"</div>"; innerHTML += "<form action="+jcObject.method+" method='post' enctype='multipart/form-data' id = 'form'>"; innerHTML += "<input type='file' name='image' id='image'>"; innerHTML += "<br />"; innerHTML += "<input type='hidden' name='base' id='base'>"; innerHTML += "</form>"; innerHTML += "<input type='button' value='保存' id='sub' />"; innerHTML += "<br/>"; innerHTML += "<canvas id='canvas' width='"+jcObject.canvasWidth+"' height='"+jcObject.canvasHeight+"'>"; innerHTML += "</canvas>"; this.getId(jcObject.container).innerHTML = innerHTML; //上傳文件的input var image = this.getId('image'); //顯示文件的img var bigImg = this.getId('bigImg'); //顯示文字的div var write = this.getId('write'); //表單 var form = this.getId('form'); //保存base64的input var base = this.getId('base'); //畫布 var canvas = this.getId('canvas'); var context = canvas.getContext('2d'); //填充顏色 this.drawCanvas = function(canvas,left,top,width,height,color) { context.fillStyle=color; context.fillRect(left,top,width,height); } //清空畫布 this.clearCanvas = function(canvas,left,top,width,height,color) { context.clearRect(left,top,width,height); //再填充一下 that.drawCanvas(canvas,left,top,width,height,color);} //初始化 if(jcObject.initImg||jcObject.initText){ //初始化canvas window.onload=function(){ that.saveImg(jcObject.initImg); that.saveText(jcObject.initText); }} //保存圖片 this.saveImg = function(imgUrl){ //創建image對象 var img = new Image; img.src = imgUrl; img.crossOrigin = 'anonymous'; img.onload = function(){ //畫圖 canvas.height = bigImg.clientHeight + write.clientHeight + 10; canvas.style.height = bigImg.clientHeight + write.clientHeight + 10 +"px"; context.drawImage(img,0,0,jcObject.canvasWidth,bigImg.height);} context.stroke(); } //先填充白色防止透明色塊 this.drawCanvas(canvas,0,0,canvas.width,canvas.height,"#ffffff"); //canvas文字換行 this.canvasTextAutoLine = function(str,canvas,initX,initY,lineHeight,context){ var context = canvas.getContext('2d'); context.fillStyle="#000000"; var lineWidth = 0; var canvasWidth = canvas.width; var lastSubStrIndex= 0; for(let i=0;i<str.length;i++){ lineWidth+=context.measureText(str[i]).width; if(lineWidth>canvasWidth-initX){//減去initX,防止邊界出現的問題 context.fillText(str.substring(lastSubStrIndex,i),initX,initY); initY+=lineHeight; lineWidth=0; lastSubStrIndex=i;} if(i==str.length-1){ context.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);}}} //換圖時修改路徑 image.onchange = function(){ var imgUrl = window.URL.createObjectURL(this.files[0]); bigImg.src = imgUrl; bigImg.style.height = "auto"; image.onload = that.saveImg(imgUrl)} //點擊圖片換圖 bigImg.onclick = function(){ image.click();} //點擊保存 sub.onclick = function(){ var text = write.innerHTML; that.saveText(text); //提交表單 window.setTimeout(function(){ var strDataURI = canvas.toDataURL(); base.value = strDataURI; form.submit();},1000) } //存文字 this.saveText = function(text){ //文字樣式 context.font=jcObject.canvasFont; //清空文字 that.clearCanvas(canvas,0,bigImg.clientHeight+jcObject.fontSize,canvas.width,write.clientHeight+jcObject.lineHeight,"#ffffff"); //文字換行 that.canvasTextAutoLine(text,canvas,0,bigImg.clientHeight+jcObject.lineHeight,jcObject.lineHeight,content) context.stroke(); } } </script> </body></html>
upload.js
var express = require('express');var app = express();var fs = require('fs');var router = express.Router();//用于解析數據var bodyParser = require('body-parser');//上傳文件中間件var multer = require('multer');app.use(express.static('static'));app.use(bodyParser.urlencoded({extended:false}));app.use(multer({dest:'/tmp/'}).array('image'));
app.get('/upload.html',function(req,res){ res.sendFile(__dirname + '/' + "upload.html")})//設置跨域訪問app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", ' 3.2.1'); res.header("Content-Type", "application/json;charset=utf-8"); next();});app.post('/upload',function(req,res){
var imgData = req.body.base.replace(/^data:image\/\w+;base64,/, ''); var imageName = imgData.substr(0,10) + Math.random().toString(16); console.log(imageName) var dataBuffer = new Buffer(imgData, 'base64'); //寫入文件 fs.writeFile('D:/my/node/static/images/'+imageName+'.png', dataBuffer, function(err){ if(err){ res.end(err);}else{ res.end(JSON.stringify('保存成功'));}});
})var server = app.listen(3300,function(req,res){ var host = server.address().address; var port = server.address().port; console.log('running at http://%s:%s',host,port)})
總結
以上是生活随笔為你收集整理的傻吊表情包加文字功能(canvas+node)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM默认内存大小
- 下一篇: 宁愿写两遍代码,也不用C++跨iOS、A