前言:这个制作纯属今天上课实在太无聊了瞎搞的不过感觉想要的效果已经实现了~~~ 先来看看实现的效果吧:
HTML5小试牛刀之―――制作可实时预览的照片裁剪特效

我们可以看到左侧区域有一张图片,上面是很熟悉的区域选择矩形,右侧是实时预览区域(他的大小跟随框选区大小实时变化)。

然后我们来看一下上面效果的一些小细节:

1.框选区域上面的八个点连同整个区域都有各自不同的点击效果。

2.无论鼠标拖拽左侧框选区怎样移动都无法超出底面图片的边界。

3.无论左侧框选区怎样移动右侧的预览区域仅仅是大小和内容跟随移动,它的位置是固定的。

我们先来详细大体的制作方法:

1.怎样实现被选中区域比图片其他区域清晰明亮?

这个实现起来就得说说图层这个东西了,学过ps的同学应该都有对图层的了解,图层的作用就是将想要显示的东西沿着屏幕z轴叠加在一起达到你想要的效果,也就是说这个效果其实是两个图片位置重合的放在一起,在底部的图片我们可以设置其透明度小一些这就达到了视觉上与原图有明暗和清晰的区别,然后只需要截取靠上层的原图的一部分显示就可以了,因为两张图是位置重合的叠在一起所以就会感觉是在一张图片上挑选想要的区域。

2.怎样实现鼠标拖拽图片却不超出区域呢?

这就需要我们在拖拽的过程中计算边界,当鼠标移动距离转化为边长的变化后若边长已经超出边界时我们就只让其最大长度为框选区的八个点钟水平距离最远的点到其拖拽指向的那个边的距离。

3.怎样实现无论左侧框选区怎样移动右侧的预览区域仅仅是大小和内容跟随移动,它的位置是固定的呢?

其实右侧区域也是同左侧原图等大的一张图片,只不过只截取我们想要的区域显示了,至于它为什么可以位置固定我们可以这样想,鼠标每次移动都可以分为x轴和y轴两个方向的移动,当每次移动后都有一个偏移量,offsetX,offsetY,我们可以在固定点减去这两个偏移量就可以抵消图片的移动。

具体实现:

整体我们可以分为一个div中包裹着三层东西,最底层是一个图片它需要有不透明效果(opacity属性,可可以是0-1的任意一个浮点数,值越小越不透明),在它之上是同样一张图片位置与其重合没有不透明效果,最上层是带有八个点的框选区,框选区的制作很简单(使用clip属性来沿着框选区大小在原图层中截出一个矩形区域),就是一个div包裹八个小div并且每个小div具有背景颜色和大小,实现框选区有一个麻烦就是让其中的点分布均匀,所有的点需要沿着边界居中显示,右侧预览区是一个div包裹一个图片。

我们来看看具体代码: 1.关于不透明度以及对齐的样式: <style type="text/css">
#imgBottom{position: absolute;top: 0px;;left: 0px;opacity: 0.3;/*设置不透明度*/
}
.moveBox.leftUp{/*左上角*/position: absolute;left: 0px;top: -4px;margin-left: -4px;cursor: nw-resize;
}
.moveBox.leftMid{/*左边中间点*/position: absolute;left: 0px;top: 50%;margin-left: -4px;cursor: w-resize;
}
.moveBox.leftDown{/*左下角*/position: absolute;left: 0px;bottom: -4px;margin-left: -4px;cursor: sw-resize;
}
</style> 2.具体布局: <body>
<div id="imgBox">
<img src="james先生的logo.png" id="imgBottom">
<img src="james先生的logo.png" id="imgTop">
<div id="clipBox"><div class="moveBox leftUp" id="leftUp"></div><div class="moveBox leftMid" id="leftMid"></div><div class="moveBox leftDown" id="leftDown"></div ><div class="moveBox midUp" id="midUp"></div><div class="moveBox midDown" id="midDown"></div><div class="moveBox rightUp" id="rightUp"></div><div class="moveBox rightMid" id="rightMid"></div><div class="moveBox rightDown" id="rightDown"></div>
</div>
</div>
<div id="preView">
<img src="james先生的logo.png" id="imgView">
</div>
</body> 3.关于鼠标拖拽以及距离限定详解:

说实话搞这个鼠标拖动和距离限定花了我一个下午的时间,有没有很蠢

先看个简单的当向右侧扩大拖拽的情况(鼠标向右拖动框选区右侧中间的点):


HTML5小试牛刀之―――制作可实时预览的照片裁剪特效

为什么说向右拖动扩大时比较简单呢,原因是横向拖动并不会改变框选区纵向的变化,而且也不会影响左边离屏幕的距离,因此就不会发生移动,我们只需关心右侧的参数变化就可以了。

上图中我们需要计算才能得出的是offsetX(鼠标拖动时出现的偏移量),currentWidth(实际扩大后的宽度),clipBoxX(框选区左边距离屏幕左边的距离),其他都是已知量,你们觉得上面那些未知量哪个好求? 其实clipBoxX最好求,它的计算就是将每一层相对于父元素左边的左边距加起来直到无父元素为止。 来看看实现:

function getPosition(node) {
/*offsetLeft获取该元素相对于父元素左边的距离,
将多个相对的左边距加起来直到无父元素则加到边界,
这时就可计算出该组件相对页面左边和顶部的距离*/
var left=node.offsetLeft;
var top=node.offsetTop;
var parent=node.offsetParent;
while(parent!=null)
{
left+=parent.offsetLeft;
top+=parent.offsetTop;
parent=parent.offsetParent;
}
return {"left":left,"top":top};
}

接下来就是来求一下偏移量,从上图很明显它的求出只需要这个公式:

offsetX = mouseX clipBoxX clipBoxWidth ;

当然同理实时长度也是公式可以得出:

currentwidth=boxOffsetX + clipBoxWidth;

因为要考虑边框所占像素,所以clipBoxWidth(裁剪区域宽度)应该比实际宽度少两个border的宽度, 因此currentwidth其实并不能像上面那样求,而是:

currentwidth=boxOffsetX + clipBoxWidth+2*border;

之后就是判断边界了,我的思路是使用currentwidth与 (imgBox_div.offsetWidth-clipBox_div.offsetLeft)的值进行对比,如果currentwidth大则超边界。来看实现:

var currentwidth=boxOffsetX + clipBoxWidth +2;//加回边框
if((imgBox_div.offsetWidth-clipBox_div.offsetLeft)<currentwidth)
{currentwidth=imgBox_div.offsetWidth-clipBox_div.offsetLeft +2;
}
clipBox_div.style.width = currentwidth + "px";

接着我们再来个麻烦点的鼠标拖动框选区上边中点向上拖动:


HTML5小试牛刀之―――制作可实时预览的照片裁剪特效

未知量与向右拖动基本一致, 只是这次我们拖动上边时影响到了框选区的top值,而且top值也有区域限制必须在区域内因此得保证其为正值,因此实现的结果应该是当向上拖动时高度增加而top被减小, 来看实现:

var upOffset=clipBox_div.offsetTop - boxOffsetY;
upOffset=Math.max(0,upOffset);
clipBox_div.style.top= upOffset + "px";
if(upOffset!=0) {clipBox_div.style.height = boxOffsetY + clipBoxHeight + "px";
}

其他两个方向的拖动实现效果类似因此不再赘述。还需要提一句的就是四个角上的拖动其实依然是分解为两个方向拖动的组合就好例如:

switch (divmark){ case "leftMid": leftMove(e); break; case "leftUp": leftMove(e); upMove(e); break;
}

移动框选区域的边界限定是保证x,y各个偏移量大于0,还要保证不超过最大宽、高度,最大高度就是

imgBox_div.offsetHeight-clipBox_div.offsetWidth ,看一下实现:

function clipBoxMove(e) {
e.stopPropagation();
var mouseX = e.pageX;//鼠标横坐标
var mouseY= e.pageY;
var boxHeight=clipBox_div.offsetHeight;
var boxWidth=clipBox_div.offsetWidth;
var imgBoxHeight=imgBox_div.offsetHeight;
var imgBoxWidth=imgBox_div.offsetWidth;
var maxY=imgBoxHeight-boxHeight;
var maxX=imgBoxWidth-boxWidth;
var moveX=0;
var moveY=0;
if(isDraging==true)
{moveX=mouseX-mouseOffsetX;moveY=mouseY-mouseOffsetY;moveX=Math.max(0,moveX);moveY=Math.max(0,moveY);moveX=Math.min(maxX,moveX);moveY=Math.min(maxY,moveY);clipBox_div.style.top=moveY+"px";clipBox_div.style.left=moveX+"px";
}
} 4.实现实时预览区域

这个区域相对来说就好实现多了,直接来看看实现:

//截取显示区域
function setImgVisiable() {
var top=clipBox_div.offsetTop;
var left=clipBox_div.offsetLeft;
var bottom=top+clipBox_div.offsetHeight;
var right=left+clipBox_div.offsetWidth;
var imgTop=document.getElementById('imgTop');
imgTop.style.clip="rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
}
//显示预览窗口
function setPreView() {
var top=clipBox_div.offsetTop;
var left=clipBox_div.offsetLeft;
var bottom=clipBox_div.offsetTop+clipBox_div.offsetHeight;
var right=clipBox_div.offsetLeft+clipBox_div.offsetWidth;
var imgView=document.getElementById('imgView');
imgView.style.clip="rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
imgView.style.top= 100-top +"px";//我选了两个定点为基准点(680,100);
imgView.style.left=680-left +"px";
} 5.最后还需要注意的一些问题:

(1).要在页面加载完成后 消除选中 不然的话鼠标拖动会被影响:

document.onselectstart=new Function('event.returnValue=false;');

(2). 使用e.stopPropagation();来阻止事件冒泡 ,这样的好处就是当鼠标位点击边框时它不会继续触发移动组件的效果,否则的话移动框选区和放大缩小框选区功能偶尔会粘连。

啊啊啊啊啊写完都凌晨两点了。。。。。

这里只给大家罗列出重要的代码,因此想要实现完整样式请参考我的源码: 点我下载html5裁剪特效源码 如果你喜欢我的文章请收藏我的个人网站: http://www.bubblyyi.com

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: HTML5HTML其实矩形个人网站
分页:12
转载请注明
本文标题:HTML5小试牛刀之―――制作可实时预览的照片裁剪特效
本站链接:http://www.codesec.net/view/483073.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(61)