支持Android iOS,firefox(其它未测)的图片上传客户端预览、缩放、裁切。
var version = '007';
var host = window.location.host;
function $$(id){return document.getElementById(id);}
function l(s){console.log(s);};
function setCookie(name, value, isForever) {
document.cookie = name + "=" + escape(value) + ";domain="+host + (isForever?";expires="+ (new Date(2099,12,31)).toGMTString():"");
} function getCookie(name) {
var search = name + "=";
if(document.cookie.length > 0) {
offset = document.cookie.indexOf(search);
if(offset != -1) {
offset += search.length;
end = document.cookie.indexOf(";", offset);
if(end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(offset, end));
}
else return "";
}
} var email = $$('email');
var page = 1;
if(email){
email.value = 'testFXS@qq.com';
$$('password').value='123456';
}else page=2; try{
document.getElementById("page-intro").innerHTML = "version="+version;
}catch(e){}
var isAndroid = navigator.userAgent.indexOf('Android')!=-1;
var isiPhone = navigator.userAgent.indexOf('iOS')!=-1||navigator.userAgent.indexOf('iPhone')!=-1||navigator.userAgent.indexOf('iPad')!=-1;
var isPc = !(isiPhone || isAndroid);
function $$(id){return document.getElementById(id);} var px_ratio = typeof(window.devicePixelRatio)=='undefined'?1:window.devicePixelRatio;
var page_width = 320;//页面dom的最大宽度
var w = isAndroid ? window.innerWidth : (window.screen.availWidth-30);
function resetDpi(evt){
try{
if(navigator.appVersion.indexOf("Android")!=-1 )
{
var objs = document.getElementsByTagName("meta");
for(var i=0;i<objs.length; i++)
{
if(objs[i].name=="viewport"){
var setting = 'target-densitydpi=medium-dpi, width='+page_width+', initial-scale=1, user-scalable=yes, minimum-scale='+(document.body.offsetWidth/page_width*1.129)+', maximum-scale=5.0';
objs[i].content = setting;
break;
}
}
}
} catch(e) {
alert('///////////////////////////////////////////////////error: '+e);
}
}
function setUsePc(f){
if(f)
setCookie('usePc', 'true', true);
else
setCookie('usePc', '', true); window.location.reload();
}
var MAX_IMG_SCALE_WIDTH = 520;
var MAX_IMG_SCALE_HEIGHT = 720;
var IMG_ORIGIN_DATA = '';
var scaleImgCb = scaleCallback;
var CUT_AREA_WIDTH = 280;
var BASE_SCALE_RATE = CUT_AREA_WIDTH/MAX_IMG_SCALE_WIDTH;
var CUT_AREA_HEIGHT = MAX_IMG_SCALE_HEIGHT/MAX_IMG_SCALE_WIDTH*CUT_AREA_WIDTH; var WINDOW_AVIABLE_HEIGHT = window.screen.availHeight-90; if(CUT_AREA_HEIGHT+40>WINDOW_AVIABLE_HEIGHT)
WINDOW_AVIABLE_HEIGHT = CUT_AREA_HEIGHT+40; var PREVIEW_TOP = 40;
var eventData;
var myTchMv;
var filename;
var user_scale_rate = 1;
var image_orgin_width = 0;
var image_orgin_height = 0;
var ouser_scale_rate = 1;
function fileChange(e){
try{
var file = e.target.files[0];
var name = file.name;
filename = name;
var ext = name.substr(-3).toLocaleLowerCase();
var type = 'image/jpeg';
if(ext=='png'){
type = 'image/png';
}else if(ext=='gif'){
type = 'image/gif';
}else if(ext=='bmp'){
type = 'image/bmp';
}
var reader = new FileReader(); reader.onload = function(o) {
try{
eventData = o.target.result;
var pre = eventData.substr(5);
if(isAndroid&&pre.indexOf('image/')==-1)
eventData = 'data:'+type+';' +eventData.substr(5); var html =
'<div style="width:'+page_width+'px;background-color:#ccc;position:absolute;float:left;left:0;top:0px;height:'+(WINDOW_AVIABLE_HEIGHT)+'px">'
+'<div id="previewHead" style="line-height:21px;position:absolute;left:0;top:16px;text-align:center;z-index:1;width:'+page_width+'px">'
+' <div style="position: absolute;left: 5px;top: -7px;width: 50px;"><input type="button" value="上传" id="upBtn" onclick="doUpload();"/><br />'
+'<img onmousedown="userScaleRate(true,true);if(window.event)window.event.preventDefault();" onmouseup="userScaleRate(true,false)" style="margin-top:6px" src="/resources/images/scale_up.png"></div>'
+' <div style="color:#900;font-size:14px;width:200px;margin:-6px auto 0;text-align:center" id="upheadCenter">滑动来调整图片显示区域</div>'
+' <div style="position: absolute;right: 5px;top: -7px;width: 50px;"><input type="button" value="取消" onclick="doCancel();"id="cancelBtn"/><br />'
+'<img onmousedown="userScaleRate(false,true);if(window.event)window.event.preventDefault();"onmouseup="userScaleRate(false,false)" style="margin-top:6px" src="/resources/images/scale_down.png"></div>'
+'</div>'
+'<div style="height:'+PREVIEW_TOP+'px;"></div>'
+'<div id="previewDivInner" style="border:2px solid #eee;padding:0px;margin:0 auto;width:'+(CUT_AREA_WIDTH)
+'px;margin:0 auto;height:'+CUT_AREA_HEIGHT+'px;overflow:hidden;background-color:#000">'
+' <img onload="cutImgOnload(this)" id="previewImage" src="'+ eventData+'">'
+'</div>'
+'</div>';
user_scale_rate = 1;
ouser_scale_rate = 1;
$$('preview').innerHTML = ""+html+"";
$$('upHead').addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
}catch(e){
alert("reader.onload="+e);
}
};
reader.readAsDataURL(file);
}catch(e){alert("fileChange="+e);}
}
function doUpload(){
try{
scaleImg(eventData);
tips('压缩图片中……');
$$('upBtn').disabled=true;
$$('cancelBtn').disabled=true;
}catch(e){alert("doUpload"+e);}
}
function doCancel(){
if(confirm('确定取消')){
$$('upDiv').innerHTML = '';
document.body.removeChild($$('upDiv'));
$$('body-wrapper').style.display = '';
}
}
function setScrollTop(y){
try{
window.scrollTo(0,y);
}catch(e){
alert('setScrollTop='+e);
return 5;
}
}
var scaleTo = false;
function userScaleRate(isUp,flag){
try{
if(scaleTo||!flag){
clearTimeout(scaleTo);
scaleTo = false;
if(!flag) return;
} ouser_scale_rate = user_scale_rate;
if(isUp)
user_scale_rate *= 1.02;
else
user_scale_rate *= 0.98; if(
CUT_AREA_WIDTH>BASE_SCALE_RATE*user_scale_rate*image_orgin_width
||
CUT_AREA_HEIGHT>BASE_SCALE_RATE*user_scale_rate*image_orgin_height
||
user_scale_rate>1
){
user_scale_rate = ouser_scale_rate;
tips(isUp?"已经到最大":"已经到最小");
}else{
myTchMv.xMove = $$('previewDivInner').scrollLeft;
myTchMv.yMove = $$('previewDivInner').scrollTop;
updateCutImageShow();
scaleTo = setTimeout( function(){userScaleRate(isUp,flag);}, 150);
tips("倍数:"+(BASE_SCALE_RATE*user_scale_rate).toFixed(2));
} }catch(e){
alert('userScaleRate='+e);
}
}
function cutImgOnload(image){
try{
myTchMv = new touch(g('previewDivInner'),slowmv,true,'previewImg');
image_orgin_width = image.width;
image_orgin_height = image.height;
if(image_orgin_width*BASE_SCALE_RATE*user_scale_rate>CUT_AREA_WIDTH*2 && image_orgin_height*BASE_SCALE_RATE*user_scale_rate>CUT_AREA_HEIGHT*2)
user_scale_rate = (CUT_AREA_WIDTH*2)/(image_orgin_width*BASE_SCALE_RATE*user_scale_rate);
updateCutImageShow();
}catch(e){
alert('cutImgOnload='+e);
}
}
function tips(s){
$$('upheadCenter').innerHTML = s;
}
function updateCutImageShow(){
try{
var rate = BASE_SCALE_RATE*user_scale_rate; $$('previewImage').width = image_orgin_width*rate;
$$('previewImage').height = image_orgin_height*rate;
$$('previewImage').style.width = image_orgin_width*rate;
$$('previewImage').style.height = image_orgin_height*rate;
}catch(e){
alert('updateCutImageShow='+e);
}
}
function showProgress(loaded, total){
var percent = (loaded / total * 100).toFixed(2) + '%';
var w = (loaded / total ) * 200;
tips('<div style="width:200px;border:1px solid #eee;height:18px; line-height:18px;margin:0 auto"><div style="width:'+w+'px;height:18px; background-color:#00a; line-height:18px;text-align:center">'+percent+'</div></div>');
}
function scaleCallback(s){
tips('数据大小:'+Math.floor(s.length/1024)+'K');
setTimeout(function(){
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// 上传中
xhr.upload.addEventListener("progress", function(e) {
showProgress(e.loaded, e.total);
}, false); // 文件上传成功或是失败
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
tips(xhr.responseText);
} else {
tips('上传失败');
//self.onFailure(file, xhr.responseText);
}
$$('upBtn').disabled=false;
$$('cancelBtn').disabled=false;
}
}; // 开始上传
xhr.open("POST", 'http://'+window.location.host+'/php/?m=uploadHairStyle', true);
xhr.setRequestHeader("X_FILENAME", filename);
var fd = new FormData();
fd.append('hairstyle', s);
xhr.send(fd); //xhr.send(eventData);
}
},1500);
}
function scaleImg(src) {
try{
// 创建一个 Image 对象
var image = new Image();
// 绑定 load 事件处理器,加载完成后执行
image.onload = function(){scaleImgOnload(this);};
image.width = image_orgin_width;
image.onerror = function(){
tips(printEvent(arguments[0]));
};
// 设置src属性,浏览器会自动加载。
// 记住必须先绑定事件,才能设置src属性,否则会出同步问题。
image.src = src;
}catch(e){
alert("scaleImg="+e);
}
};
function scaleImgOnload(image){
try{
//var image = this;
// 获取 canvas DOM 对象
var canvas = document.getElementById("myCanvas");
if(!canvas){
canvas = document.createElement('canvas');
canvas.id = "myCanvas";
canvas.width = MAX_IMG_SCALE_WIDTH;
canvas.height = MAX_IMG_SCALE_HEIGHT;
//canvas.style.display = 'none';
canvas.style.cssText = 'position:absolute;left:330px;top:0px;';
//$$('preview').style.display = 'none';
$$('preview').appendChild(canvas);
} var rate = BASE_SCALE_RATE*user_scale_rate; var ctx = canvas.getContext("2d");s=3;
ctx.clearRect(0, 0, MAX_IMG_SCALE_WIDTH, MAX_IMG_SCALE_HEIGHT); var sx=parseInt(myTchMv.xMove/rate);
var sy=parseInt(myTchMv.yMove/rate);
var sw=parseInt(CUT_AREA_WIDTH/rate);
var sh=parseInt(CUT_AREA_HEIGHT/rate);
var sParam = ('sx='+sx + ",sy=" + sy +",\nsw="+ sw +",sh="+ sh+",rate="+rate+",move("+myTchMv.xMove+","+myTchMv.yMove+")");
console.log(sParam);
ctx.drawImage(image, sx, sy, sw, sh, 0, 0, MAX_IMG_SCALE_WIDTH, MAX_IMG_SCALE_HEIGHT); var data = canvas.toDataURL();
scaleCallback(data);s=8;
}catch(e){
alert("scaleImgOnload="+e);
}
}
function uploadInit(){
var upDiv = $$('upDiv');
if(!upDiv){
upDiv = document.createElement("div");
upDiv.id = 'upDiv';
upDiv.style.cssText = 'float:left; background-color:#f9f9f9;';
upDiv.innerHTML = '<div style="margin:0 auto;width:316px;min-height:640px;border:1px solid #eee;background-color:#f9f9f9;border-radius:5px;"><div id="upHead" style="background-color:#aaa;line-height:24px; height:24px; text-indent:12px; font-weight:bold;color:#090">发型上传</div>'+
'<div id="step_2" style="">'
+'<input type="file" id="file1" onchange="fileChange(event)"></div><div id="preview" style="float:left;width:'+page_width+'px"></div>'
+'</div><div id="dbg"></div></div>';
document.body.appendChild(upDiv);
setScrollTop(0);
$$('body-wrapper').style.display = 'none';
}
upDiv.style.display = '';
} function getRadioParam(name){
var obj;
var i = 1;
while(true){
obj = $$(name+'_'+(i++));
if(!obj) return'';
if(obj.checked) return obj.value;
}
}
function nextStep(){
$$('step_1').style.display='none';
$$('step_2').style.display='';
}
isPc = false;
try{
var setUsePcVersion = getCookie('usePc');
l('setUsePcVersion='+setUsePcVersion);
if(!isPc && !setUsePcVersion){
window.onload = function(e){
resetDpi(e);
}; }else if(!isPc) document.getElementById("page-intro").innerHTML = '<a href="javascript:setUsePc(false);">切换到手机版</a> - '+version + ' '+navigator.userAgent;
}catch(e){
alert("e="+e);
} function printVar(v)
{
if(v==null) return 'null';
var type = typeof(v);
var rtn = '';
switch(type)
{
case 'boolean':
if(v)
rtn='true';
else
rtn='false';
break;
case 'object':
var i = 0;
if(typeof(v.length)=='undefined')
{
rtn = '{';
for(var x in v)
{
if(i==0)
rtn+=x+':'+printVar(v[x]);
else
rtn+=','+x+':'+printVar(v[x]);
i++;
}
rtn += '}';
}else{
rtn = '[';
for(var i=0;i<v.length;i++)
{
if(i==0)
rtn+=printVar(v[i]);
else
rtn+=','+printVar(v[i]);
}
rtn += ']';
}
break;
case 'string':
rtn = '"'+v.replace(/"/g,'\\"').replace(/\r\n/g,"\\r\\n")+'"';
break;
case 'number':
default:
rtn = v;
}
return rtn;
}
function printEvent(evt)
{
try
{
var tmp = '';
for(var i in evt)
{
tmp += i+':';
var v = evt[i]+'';
if(v=='[object HTMLDivElement]')
{
tmp+=' <b>div</b> - '+evt[i].id+'<br/>';
}
else if(''+(evt[i])=='[object TouchList]')
{
tmp+=' <br/> <b>touchlist</b>:<div style="border:1px solid red; margin:1px"> ';
for(var x in evt[i])
{
if(''+(evt[i][x])=='[object Touch]')
{
tmp+='<br> ----'+x+':'+' <b>Touch</b><br/><div style="border:1px solid blue;margin:1px">';
for(var y in evt[i][x])
{
if(evt[i][x][y]=='[object HTMLDivElement]')
{
tmp+=' ----'+y+':<b>div</b> - '+evt[i][x][y].id+'<br/>';
}else tmp+='<br> ----'+y+':'+evt[i][x][y]+'<br/>';
}
tmp+='</div>';
}else
tmp+='<br> '+x+':'+evt[i][x]+'<br/>';
}
tmp+='</div>';
}else if(typeof(evt[i])=='number'){
tmp+='<font color="green">'+v+'</font><br/>';
}
else tmp+=''+v+'<br/>';
}
return tmp;
}catch(e){
alert(e);
}
}
function getxy(e){
var a=new Array();
var t=e.offsetTop;
var l=e.offsetLeft;
var w=e.offsetWidth;
var h=e.offsetHeight;
while(e=e.offsetParent){
t+=e.offsetTop;
l+=e.offsetLeft;
}
a[0]=w;a[1]=h;
a[2]=l;a[3]=t;
return a;
}
function touch(obj,func)
{
try{
if(arguments.length>2)
this.leftRightOnly = arguments[2];
else
this.leftRightOnly = false; if(arguments.length>4){//4,5个参数设置后会帮你设定子元素的宽度,帮助滚动效果
var fchild = g(arguments[3]);
if(fchild){
var fchildCTagName = arguments[4];
var childs = fchild.getElementsByTagName(fchildCTagName);
var w = 0; for(var i=0;i<childs.length;i++){
var xy = getxy(childs[i]);
w += xy[0];
}
fchild.style.width = w+"px";
}
} this.yMove = 0;
this.xMove = 0;
this.swipe_function[obj.id] = func;
this.id = obj.id;
if(!this.id){
alert("第一个参数必须有一个id");
return;
}
this.isPc = navigator.userAgent.indexOf('Windows')!=-1||navigator.platform.indexOf('Mac')!=-1;
this.startFlag = false;
obj.data = this; if(this.isPc){
this.bind(obj,'mousedown',function(e){this.data.touchstart(e);});
this.bind(obj,'mouseup',function(e){this.data.touchend(e);});
this.bind(obj,'mouseout',function(e){this.data.touchend(e);});
this.bind(obj,'mousemove',function(e){this.data.touchmove(e);});
}else{
this.bind(obj,'touchstart',function(e){this.data.touchstart(e);});
this.bind(obj,'touchend',function(e){this.data.touchend(e);});
this.bind(obj,'touchmove',function(e){this.data.touchmove(e);});
}
}catch(e){
alert("touch: "+e);
}
}
touch.prototype.tch_start = {};
touch.prototype.tch_mv = {};
touch.prototype.swipe_function = {};
touch.prototype.bind = function(obj,evt,fun)
{
if(typeof obj.attachEvent != 'undefined')
{
obj.attachEvent('on'+evt,fun);
}else{
obj.addEventListener(evt,fun,true);
}
};
touch.prototype.touchstart=function(evt)
{
try{
var tch;
if(this.isPc)
tch = evt;
else
tch = evt['touches'][0];
var id = ""; if(this.isPc)
id = this.id;
else
id = tch.target.id; this.tch_start[id] = [tch.clientX,tch.clientY];
l("this.tch_start[id]="+this.tch_start[id]+",id="+id);
this.startFlag = true;
evt.preventDefault();
}catch(e){
alert('this.tch_start='+this.tch_start+'<br />'+e);
}
};
touch.prototype.touchend=function (evt)
{
try{
if(!this.startFlag) return;
if(!this.isPc && (typeof(evt.changedTouches)=='undefined'||evt.changedTouches.length<1)) return; var id = ""; if(this.isPc)
id = this.id;
else
id = evt.changedTouches[0].target.id; var pid = evt.currentTarget.id;
var now = this.tch_mv[id];
var start = this.tch_start[id]; l('end= '+start+","+now+",id="+id); var xdiff = now[0]-start[0];
var ydiff = now[1]-start[1]; var f = this.swipe_function[pid];
evt.preventDefault();
this.startFlag = false;
if(Math.abs(xdiff)>Math.abs(ydiff))
{
if(xdiff<0)
{
this.swipe(pid,'left',xdiff,f);
return;
}
if(xdiff>0)
{
this.swipe(pid,'right',xdiff,f);
return;
}
}else{
if(ydiff<0)
{
this.swipe(pid,'up',ydiff,f);
return;
}
if(ydiff>0)
{
this.swipe(pid,'down',ydiff,f);
return;
}
}
}catch(e){
alert('touchend error='+e);
}
};
touch.prototype.touchmove=function(evt)
{
try{
if(!this.startFlag) return;
var id,tch;
if(this.isPc){
id = this.id;
tch = evt;
}else{
tch = evt['touches'][0];
id = tch.target.id;
}
var now = [tch.clientX,tch.clientY];
this.tch_mv[id] = now; if(this.leftRightOnly)
{
var start = this.tch_start[id];
l('move='+start+","+now+",id="+id);
var xdiff = start[1] - now[1];
var ydiff = start[0] - now[0];
var obj = g(this.id);
obj.scrollTop += xdiff;
obj.scrollLeft += ydiff;
start[0] = now[0];
start[1] = now[1]; this.xMove = obj.scrollLeft;
this.yMove = obj.scrollTop;
tips('偏移:'+this.xMove+","+this.yMove);
}
evt.preventDefault();
}catch(e){
console.log('touchmove error='+e);
//l(printEvent(evt));
}
};
touch.prototype.swipe = function(pid,dir,xydiff,func)
{
} function g(id)
{
return document.getElementById(id);
}
var swiping = false;
var step = 16;
function slowmv(pid,v,v1)
{
}
直接调用:uploadInit();
支持Android iOS,firefox(其它未测)的图片上传客户端预览、缩放、裁切。的更多相关文章
- ckeditor 实现图片上传以及预览(亲测有效)
引用ckeditor <script type="text/javascript" src="static/ckeditor/ckeditor.js"&g ...
- 移动端上传照片 预览+Draw on Canvas's Demo(解决 iOS 等设备照片旋转 90 度的 bug)
背景: 本人的一个移动端H5项目,需求如下: 需求一:手机相册选取或拍摄照片后在页面上预览 需求二:然后绘制在canvas画布上 这里,我们先看一个demo(http://jsfiddle.net/q ...
- android 拍照或者图库选择 压缩后 图片 上传
通过拍照或者从相册里选择图片通过压缩并上传时很多应用的常用功能,记录一下实现过程 一:创建个临时文件夹用于保存压缩后需要上传的图片 /** * path:存放图片目录路径 */ private Str ...
- 前端图片预览,上传前预览,兼容IE7、8、9、10、11,Firefox,Chrome(学习到的知识)
文章地址:http://www.cnblogs.com/rubylouvre/p/4597344.html 一.window.URL 在Chrome中,window.URL和window.webkit ...
- 在附件管理模块中增加对FTP 上传和预览的支持
在之前介绍的附件管理模块里面<Winform开发框架之通用附件管理模块>以及<Winform开发框架之附件管理应用>,介绍了附件的管理功能,通过对数据库记录的处理和文件的管理, ...
- 支持多文件上传,预览,拖拽,基于bootstrap的上传插件fileinput 的ajax异步上传(转载)
首先需要导入一些js和css文件 <link href="__PUBLIC__/CSS/bootstrap.css" rel="stylesheet"&g ...
- 支持多文件上传,预览,拖拽,基于bootstra的上传插件fileinput 的ajax异步上传
首先需要导入一些js和css文件 <link href="__PUBLIC__/CSS/bootstrap.css" rel="stylesheet"&g ...
- iOS利用AFNetworking(AFN) 实现图片上传
1.上传图片以二进制流的形式上传 1 #pragma mark - 文件上传 2 - (IBAction)uploadImage 3 { 4 /* 5 此段代码如果需要修改, ...
- android拍照选择图片上传服务器自定义控件
做android项目的时候总免不了遇到图片上传功能,虽然就是调用android系统的拍照和相册选择功能,但是总面部了把一大推代码写在activity里,看上去一大推代码头都昏了.不如把这些功能都集成一 ...
随机推荐
- JAVA基础语法。
1.java数据类型和变量布尔型.短整型.整型.长整型.浮点型.双精度型.字符型.字节型.8中数据类型结构.2. 变量的作用域3.常量.关键字.标识符4.运算符和表达式 4.1算术运算符 4.2位运算 ...
- 替换所有字符串,获取url参数值
替换所有的字符串: var newStr = str.replace(/null/g, ""); 获取url参数值 <script type="text/javas ...
- 介绍Android HAL的一篇好文章
从Linux driver到HAL再到JNI再到Java都讲了一个遍,算是对HAL有一个基本的了解了,其中hw_module_t的设计非常巧妙,每个module都会有自己的特定函数,而HAL是不知道的 ...
- python:页面布局 后台管理页面之常用布局
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- linux下安装及配置和启动memcached
一.下载文件: 下载memcached和libevent,放到/hom/zwl/目录下 # wget http://www.danga.com/memcached/dist/memcached-1.2 ...
- 使用BigDecimal进行精确计算工具类
package com.develop.util; import java.math.BigDecimal; import java.math.RoundingMode; public class M ...
- JAVA线程同步辅助类Exchanger-交换
可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象.Exchanger 可能被视为 Synchro ...
- R----Shiny包介绍学习
为什么用Shiny Shiny让数据分析师写完分析与可视化代码后,稍微再花几十分钟,就可以把分析代码工程化,将分析成果快速转化为交互式网页分享给别人.所以,如果你是一名使用R的数据分析师,选择Shin ...
- opengl视图变换 投影变换推导
视图变换在opengl中,视图变换的输入是:(1)眼睛位置(或者说相机位置)eys:(2)眼睛朝向的中心center,(就是眼睛朝哪里看);(3)头的方向up.任何一点经过视图变换后都会转化到眼睛坐标 ...
- 【转载】C++中的位拷贝和值拷贝
---恢复内容开始--- 原文:C++中的位拷贝和值拷贝 原文:http://blog.csdn.net/liam1122/article/details/1966617 为了便于说明我们以Strin ...