html代码。
<ul class="hf-reversal">
<li class="hf-item" onclick="showEffect('showCss')">
<img th:src="@{images/reversal/1.png}"/>
<div class="hf-cover">
Css效果展示
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/2.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/3.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/4.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/5.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/6.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/7.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/8.png}"/>
<div class="hf-cover">
</div>
</li>
<li class="hf-item">
<img th:src="@{images/reversal/9.png}"/>
<div class="hf-cover">
</div>
</li>
</ul>
css代码。
.hf-reversal .hf-item .hf-cover.hf-hover{
transform: rotate(0deg) !important;
-webkit-transform: rotate(0deg) !important;
-moz-transform: rotate(0deg) !important;
}
js代码
以一个li为单位,在其周围生成8个相同的遮罩。
主要是animation的css动画不支持翻转,只能通过transfrom来做,需要以边为单位翻转。
当所有li关联起来的时时候,记录上一个翻转方向,达到连贯性
var initImgCover = function(){
var directionObj = {
"top-left":"rotate(-90deg)",
"left-top":"rotate(90deg)",
"top-right":"rotate(90deg)",
"right-top":"rotate(-90deg)",
"bottom-left":"rotate(90deg)",
"left-bottom":"rotate(-90deg)",
"bottom-right":"rotate(-90deg)",
"right-bottom":"rotate(90deg)"
};
function transFormByDirection(element,direction,isEnter){
var currentCoverName= element.attr("cover-name")||"",item = element.closest("li"),currentCover;
function transFormCover(defaultName){
var name = null;
var arr = ["top","right","bottom","left"];
for(var i=0;i< arr.length;i++){
if(element.hasClass(arr[i])){
name = direction +"-"+ arr[i];
break;
}
}
if(!name || !directionObj[name]){
name = defaultName;
}
element.removeClass("top left right bottom").addClass(direction);
if(isEnter){
currentCoverName = name;
currentCover = item.find(".hf-clone."+currentCoverName);
currentCover.addClass("hf-hover");
}else{
var cssText = item.find(".hf-clone."+name)[0].style.cssText;
currentCover = item.find(".hf-clone."+currentCoverName);
currentCover[0].style.cssText = cssText;
currentCover.removeClass("hf-hover");
currentCoverName = name;
}
element.attr("cover-name",currentCoverName);
}
function getDefaultCoverName(defaultName,num){
var name = defaultName[0],coverName="";
if(isEnter){
var ul = item.closest("ul"),index = item.index() +num,prevItem,prevCoverName;
if(index >=0 && index < 9 ){
prevItem = ul.children("li:eq("+index+")");
prevCoverName = prevItem.find(".hf-cover:not(.hf-clone)").attr("cover-name");
if(prevCoverName){
coverName = direction + "-"+ prevCoverName.split("-")[1];
}
}
}else{
coverName = direction + "-"+currentCoverName.split("-")[1];
}
if(defaultName.indexOf(coverName)!= -1){
name = coverName;
}
return name;
}
switch (direction){
case "top":
// -3
transFormCover( getDefaultCoverName(["top-right","top-left"],-3));
break;
case "right":
// +1
transFormCover(getDefaultCoverName(["right-bottom","right-top"],1));
break;
case "bottom":
// +3
transFormCover(getDefaultCoverName(["bottom-left","bottom-right"],3));
break;
case "left":
// -1
transFormCover(getDefaultCoverName(["left-top","left-bottom"],-1));
break;
}
}
function initCover(element){
element.find(".hf-clone").remove();
var cover = element.find(".hf-cover:not(.hf-clone)");
$.each(directionObj,function(k,v){
var clone = cover.clone();
var obj = {
"transform-origin":k.replace("-"," "),
"transform":v,
"display":"block"
};
clone.removeAttr("cover-name").addClass("hf-clone").addClass(k).css(obj).appendTo(element);
});
}
$(".hf-reversal .hf-item").bind({
"pointerenter":function(e){
var chromePointerEvents = typeof PointerEvent === 'function';
if (chromePointerEvents) {
if (e.pointerId === undefined) {
return;
}
// mouseleave不触发
this.setPointerCapture(e.pointerId);
}
var item = $(this), cover = item.find(".hf-cover:not(.hf-clone)");
initCover(item);
item.mDirection(e,function(direction){
transFormByDirection(cover,direction,true);
})
},
"pointerleave":function(e){
var that = this,item = $(this),cover = item.find(".hf-cover:not(.hf-clone)");
$(this).mDirection(e,function(direction){
transFormByDirection(cover,direction,false);
var chromePointerEvents = typeof PointerEvent === 'function';
if (chromePointerEvents) {
if (e.pointerId === undefined) {
return;
}
that.releasePointerCapture(e.pointerId);
}
})
}
})
}
if (typeof jQuery === 'undefined') {
throw new Error('mDirection JavaScript requires jQuery')
}
+function ($) {
'use strict';
var Direction = function(element){
this.$element = element;
};
Direction.DEFAULTS = {
};
Direction.prototype.init = function (enterObj,leaveObj) {
var $this = this
var $el = this.$element
$el.addEventListener('mouseenter',function(e){
var directionNumber = $this.getDirectionNumber(e);
var funArray = [enterObj.top,enterObj.right,enterObj.bottom,enterObj.left];
funArray[directionNumber]($el);
},false);
$el.addEventListener('mouseleave',function(e){
var directionNumber = self.main(e);
var funArray = [leaveObj.top,leaveObj.right,leaveObj.bottom,leaveObj.left];
funArray[directionNumber]($el);
},false);
};
Direction.prototype.getDirectionNumber = function(e){
var $el = this.$element
var width = $el.width()
var height = $el.height()
// 获得相对于中心点的 x,y坐标
var x = (e.pageX - $el.offset().left-( width / 2 )) * (width >height ? (height / width ):1);
var y = (e.pageY- $el.offset().top -( height / 2 )) * (height >width ? (width / height):1);
// Math.atan2(y,x) 获得斜率 -PI 到PI之间的数
var number = Math.round((((Math.atan2(y, x) * 180 / Math.PI) + 180) / 90) + 3) % 4;
return number;
}
Direction.prototype.getDirection = function(e){
var directionNumber = this.getDirectionNumber(e);
var direction = "";
switch (directionNumber)
{
case 0 :
direction = "top";
break;
case 1:
direction = "right";
break;
case 2:
direction = "bottom";
break;
case 3:
direction = "left";
break;
}
return direction;
}
$.fn.mDirection = function(e,callback){
var $element = this;
var mDirection = new Direction($element);
if(callback){
callback.call($element,mDirection.getDirection(e));
}else{
return mDirection.getDirection(e);
}
};
$.fn.mDirection.Constructor = function(element,enterObj,leaveObj){
var $element = $(element);
var mDirection = new Direction($element);
mDirection.init(enterObj,leaveObj)
}
}(jQuery);