纯JS写的头像编辑AJAX上传功能 [ 2.0 版本 ]
网上大部分头像上传插件文件太多,用起来太复杂,还不如自己写一个快,于是本人手写了一个。其实一点也不复杂,抛弃太古老浏览器兼容用到一些HTML5技术,尽量精简实现的话,总共也就三百行左右的代码,一般使用没什么问题,有些缺陷或设计不合理或可以改善的地方希望高手指出,大家一起交流。
CSS
css和js直接视图里注入即可
.mask{
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
display:none;
background-color:rgba(0,0,0,0.3);
}
.white-bg{
margin:auto;
margin-top:100px;
width:700px;
height:420px;
position:relative;
background-color:#FFF;
border:1px solid #FFF;
}
.white-bg2{
margin-bottom:20px;
height:300px;
}
.cnt0{
border:1px solid #DDD;
position:relative;
margin:20px;
display:inline-block;
}
.div0{
position:absolute;
border: 1px dashed #555;
display:inline-block;
min-width:30px;
min-height:30px;
}
.div1{
position:absolute;
bottom:0;
right:0;
border:1px solid #AAA;
background-color:rgba(0,0,0,0.3);
cursor:se-resize;
}
#img0{
max-height:256px;
max-width:256px;
display:block;
}
#cs0{
display:none;
}
.btns{
margin:auto;
width:500px;
height:50px;
text-align:center;
line-height:50px;
}
#file{
display: inline-block;
height: 34px;
}
#cs1,#cs2{
display:inline-block;
position:absolute;
border:1px solid #DDD;
margin:20px;
}
#cs1{
left:360px;
}
#cs2{
right:0;
}
.progress{
margin:10px 20px;
}
HTML
宽高需要直接在标签里改
<button id="modify" class="btn btn-default">修改头像</button>
<div class="mask" id="mask">
<div class="white-bg">
<div class="white-bg2">
<div class="cnt0" id="cnt0" style="max-width:258px; max-height:258px;"><img id="img0"><div class="div0" id="div0" style="width:150px; height:150px;left:0;top:0;"><div class="div1" id="div1" style="width:10px; height:10px;"></div></div></div>
<canvas id="cs0" width="256" height="256"></canvas>
<canvas id="cs1" width="140" height="140"></canvas>
<canvas id="cs2" width="70" height="70"></canvas>
</div>
<div class="progress">
<div id="progress-bar" class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width:0%"></div>
</div>
<div class="btns">
<input type="file" value="上传头像" id="file" class="btn btn-default"> <button id="confirm" class="btn btn-default">确定</button> <button id="cancel" class="btn btn-default">取消</button>
</div>
</div>
</div>
<div id="res"></div>
JS
document.getElementById("cancel").onclick=function(){
document.getElementById("mask").style.display="none";
};
document.getElementById("modify").onclick=function(){
document.getElementById("mask").style.display="block";
};
document.getElementById("file").onclick=function(e){
var E=e||event;
E.stopPropagation();
};
document.getElementById("file").onchange=function(e){
var E=e||event;
E.stopPropagation();
var file=document.getElementById("file").files[0];
img["element"].src=window.URL.createObjectURL(file);
img["type"]=file.type;
function getNat(){
if(document.getElementById("img0").src!="")
{
img["nat_width"]=parseInt(img["element"].naturalWidth);
img["nat_height"]=parseInt(img["element"].naturalHeight);
cnt0["width"]=parseInt(window.getComputedStyle(cnt0["element"]).getPropertyValue("width"));
cnt0["height"]=parseInt(window.getComputedStyle(cnt0["element"]).getPropertyValue("height"));
div0["top"]=0;
div0["left"]=0;
div0["element"].style.top="0px";
div0["element"].style.left="0px";
drawImg();
}
}
setTimeout(getNat,200);
};
function drawImg()
{
canvas["large_ctx"].clearRect(0,0,canvas["large"].width,canvas["large"].height);
canvas["middle_ctx"].clearRect(0,0,canvas["middle"].width,canvas["middle"].height);
canvas["small_ctx"].clearRect(0,0,canvas["small"].width,canvas["small"].height);
canvas["large_ctx"].drawImage(img["element"],div0["left"]/cnt0["width"]*img["nat_width"],div0["top"]/cnt0["height"]*img["nat_height"],div0["width"]/cnt0["width"]*img["nat_width"],div0["height"]/cnt0["height"]*img["nat_height"],0,0,canvas["large"].width,canvas["large"].height);//图片画到canvas画布上
canvas["middle_ctx"].drawImage(img["element"],div0["left"]/cnt0["width"]*img["nat_width"],div0["top"]/cnt0["height"]*img["nat_height"],div0["width"]/cnt0["width"]*img["nat_width"],div0["height"]/cnt0["height"]*img["nat_height"],0,0,canvas["middle"].width,canvas["middle"].height);
canvas["small_ctx"].drawImage(img["element"],div0["left"]/cnt0["width"]*img["nat_width"],div0["top"]/cnt0["height"]*img["nat_height"],div0["width"]/cnt0["width"]*img["nat_width"],div0["height"]/cnt0["height"]*img["nat_height"],0,0,canvas["small"].width,canvas["small"].height);
};
var cnt0={};
cnt0["element"]=document.getElementById("cnt0");
var div1={};
div1["draggable"]=false;
div1["element"]=document.getElementById("div1");
div1["width"]=parseInt(div1["element"].style.width);
div1["height"]=parseInt(div1["element"].style.height);
var div0={};
div0["draggable"]=false;
div0["element"]=document.getElementById("div0");
div0["width"]=parseInt(div0["element"].style.width);
div0["height"]=parseInt(div0["element"].style.height);
div0["t_size"]=div0["width"];
div0["top"]=parseInt(div0["element"].style.top);
div0["left"]=parseInt(div0["element"].style.left);
var img={};
img["element"]=document.getElementById("img0");
var canvas={};
canvas["large"]=document.getElementById("cs0");
canvas["large_ctx"]=canvas["large"].getContext("2d");
canvas["middle"]=document.getElementById("cs1");
canvas["middle_ctx"]=canvas["middle"].getContext("2d");
canvas["small"]=document.getElementById("cs2");
canvas["small_ctx"]=canvas["small"].getContext("2d");
div1["element"].onmousedown=function(e){
var E=e||event;
E.stopPropagation();
E.preventDefault();
div1["draggable"]=true;
div0["draggable"]=false;
div1["mouse_x"]=E.clientX;
div1["mouse_Y"]=E.clientY;
div0["width"]=parseInt(div0["element"].style.width);
div0["height"]=parseInt(div0["element"].style.height);
div0["top"]=parseInt(div0["element"].style.top);
div0["left"]=parseInt(div0["element"].style.left);
div0["t_size"]=div0["width"];
div0["t_pos"]=Math.max(div0["top"],div0["left"]);
div1["left"]=div0["width"]-div1["width"];
div1["top"]=div0["height"]-div1["height"];
};
div0["element"].onmousedown=function(e){
var E=e||event;
E.stopPropagation();
E.preventDefault();
div1["draggable"]=false;
div0["draggable"]=true;
div0["mouse_x"]=E.clientX;
div0["mouse_y"]=E.clientY;
div0["left"]=parseInt(div0["element"].style.left);
div0["top"] =parseInt(div0["element"].style.top);
};
cnt0["element"].onmousemove=function(e){
var E=e||event;
E.stopPropagation();
E.preventDefault();
if(div1["draggable"])
{
var x=E.clientX-div1["mouse_x"];
var y=E.clientY-div1["mouse_y"];
div0["t_size"]=Math.min((div0["t_pos"]+div0["width"]+x-2>cnt0["width"]?cnt0["width"]-div0["left"]-2:div0["width"]+x-2),(div0["t_pos"]+div0["height"]+x-2>cnt0["height"]?cnt0["height"]-div0["top"]-2:div0["height"]+x-2));
div0["element"].style.width=div0["element"].style.height=div0["t_size"]+"px";
}
else if(div0["draggable"])
{
var x=E.clientX-div0["mouse_x"];
var y=E.clientY-div0["mouse_y"];
div0["element"].style.left=div0["left"]+x+"px";
div0["element"].style.top=div0["top"]+y+"px";
parseInt(div0["element"].style.top)<0?div0["element"].style.top="0px":"";
parseInt(div0["element"].style.left)<0?div0["element"].style.left="0px":"";
cnt0["width"]-parseInt(div0["element"].style.width)-parseInt(div0["element"].style.left)<0?div0["element"].style.left=cnt0["width"]-parseInt(div0["element"].style.width)-2+"px":"";
cnt0["height"]-parseInt(div0["element"].style.height)-parseInt(div0["element"].style.top)<0?div0["element"].style.top=cnt0["height"]-parseInt(div0["element"].style.height)-2+"px":"";
}
};
document.getElementById("mask").onmouseup=function(e){
var E=e||event;
E.stopPropagation();
div0["draggable"]=div1["draggable"]=false;
div0["width"]=div0["height"]=div0["t_size"];
div0["top"]=parseInt(div0["element"].style.top);
div0["left"]=parseInt(div0["element"].style.left);
drawImg();
};
document.getElementById("confirm").onclick=function(e){
var E=e||event;
E.stopPropagation();
var fd=new FormData();
fd.append("_csrf","'.Yii::$app->request->csrfToken.'");
fd.append("large_img",canvas["large"].toDataURL(img["type"],0.9));//画布转成Base64来传输,不再用到文件传输功能
//fd.append("middle_img",canvas["middle"].toDataURL(img["type"],0.9));
//fd.append("small_img",canvas["small"].toDataURL(img["type"],0.9));
var xhr=new XMLHttpRequest();
xhr.open("post","'.Url::to(['site/upload-avatar']).'",true);
var progressBar=document.getElementById("progress-bar");
xhr.upload.onprocess=function(t){
if(t.lengthComputable)
{
progressBar.style.width=(t.loaded/t.total*100).toFixed(2)+"%";
}
};
xhr.onreadystatechange=function(){
if(xhr.readyState===4&&xhr.status===200)
{
document.getElementById("res").innerHTML=xhr.responseText;//返回的路径可直接修改头像的src
document.getElementById("mask").style.display="none";
}
};
xhr.setRequestHeader("X-Request-with","XMLHttpRequest");
xhr.send(fd);
};
控制器里
public function actionUploadAvatar()
{
$user_id=Yii::$app->user->identity->id;
$large_img=Yii::$app->request->post("large_img");
$img_id=$this->convertToImg($large_img);
if($img_id&&$user_id)
{
//此处img_id与user_id一起写入数据库
//可再次读取用户信息并return图片路径,验证写入是否正确
}
}
private function convertToImg($base64Steam)
{
$base64Steam=str_replace(' ', '+', $base64Steam);//base64在传输中,加号可能会被转成空格,需要将其还原
$img_type=explode(';', $base64Steam,2);
$img_type=explode('/', $img_type[0]);//读取图片类型
if($img_type[1]=='jpeg')
{
$img_type='jpg';//确定图片扩展名
$data=base64_decode(str_replace('data:image/jpeg;base64,', '', $base64Steam));//base64转成二进制数据
}
elseif ($img_type[1]=='png')
{
$img_type='png';
$data=base64_decode(str_replace('data:image/png;base64,', '', $base64Steam));
}
elseif ($img_type[1]=='bmp')
{
$img_type='bmp';
$data=base64_decode(str_replace('data:image/bmp;base64,', '', $base64Steam));
}
if($data)
{
$dir='images/';//要保存的路径
mkdir($dir,0777,true);//php自带的递归创建目录函数
$name = '图片名';
$path=$dir.$name;
file_put_contents($path.'.'.$img_type, $data);//二进制数据转成图片并保存
list($width,$height,$type,$attr)=getimagesize($path.'.'.$img_type);//读取图片的各种信息
//此时已可将图片的各种信息写入数据库并return图片记录的id
}
}
a753255157 杭州
注册时间:2016-03-23
最后登录:2019-08-21
在线时长:67小时37分
最后登录:2019-08-21
在线时长:67小时37分
- 粉丝3
- 金钱1130
- 威望10
- 积分1900
共 1 条评论
这编辑器也是醉了,部分CSS少了#,排版全乱掉了,还不能修改
这是markdown,现在很火的,我帮你修改了,可以自己修改帖子吧