作为一名前端的初学者,此篇文章作者只保证原创以及在一般条件下可用。
这是在某个特殊需求中,我个人写的一个异形按钮组件,可以作为初学者学习的参考,主要使用了canvas、js等技术。可以在html页面中创建一个支持像素级操作的异形按钮(需要图片格式支持是为了作为判断是否点击/移动到了图片之上,作为依据。注:png格式/svg格式等才拥有无色区域,无色!=白色!!!;
另外支持使用背景图片或者直接设置宽高的方式处理canvas对象,也可以不设置 由css/html结构中书写。
注:常识性问题:canvas对象的width/height!=style.width/style.height!这个 问题适用于大多数html元素。
由于本插件使用了多个辅助方法。可能会与页面已有方法冲突,如确实有冲突,请更名即可 。
本插件使用类的方式调用,因此支持同页面多个元素同时使用本插件。
注! 某些特殊css样式可能导致获取位置失效。可以参考思路,自己书写异形按钮解决方案。
将下面整体复制后,引入页面即可(推荐使用新的文件,作为引用。)
如果好用请支持js新人,谢谢。欢迎各路大神大仙大哥大姐交流学习。
function getOffsetTop(obj){
var tmp = obj.offsetTop;
var val = obj.offsetParent;
while(val != null){
tmp += val.offsetTop;
val = val.offsetParent;
}
return tmp;
}
function getOffsetLeft(obj){
var tmp = obj.offsetLeft;
var val = obj.offsetParent;
while(val != null){
tmp += val.offsetLeft;
val = val.offsetParent;
}
return tmp;
}
function mousePos(e){
var x,y;
return {
x:e.clientX+document.body.scrollLeft + document.documentElement.scrollLeft,
y:e.clientY+document.body.scrollTop + document.documentElement.scrollTop
};
};
function isin(obj,x,y){
//解析button有没有被点击到(精确到像素)
var xmax = obj['xy'][0] + obj.width;
var ox = x-obj['xy'][0];
var oy = y-obj['xy'][1];
if(ox>=0&&ox<obj.width){
if(oy>=0&&oy<obj.height){
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = obj.width;
canvas.height = obj.height;
context.drawImage(obj, 0, 0, obj.width, obj.height);
var colors = context.getImageData(ox, oy, 1, 1).data;
if(colors[0]!=0&&colors[1]!=0&&colors[2]!=0&&colors[3]!=0){
return true;
}
}
}
return false;
}
function draw(c,b){
c.clearRect(0,0,c['canvas'].width,c['canvas'].height);
for(var i = 0;i<b.length;i++){
if(b[i].isactive||b[i].ishidden){
c.drawImage(b[i],b[i].xy[0],b[i].xy[1]);
}
}
}
function buttabs(can,func,funh){//canvas对象,点击回调函数 , 按钮移动到回调函数
//调用方法 : 1创建本对象 new buttabs ();
//初始化背景图片或者直接设置宽高 (如有需要 可以灵活设置。可以有设置背景图之后有回调函数)
//addbuts(传入的参数示例)[['img.src',x,y,'返回值'],['img.src',x,y,'返回值2']];
//buts的返回值将用于在触发任何回调函数时 返回 (用以区别具体点击了那个button)
//removebuts 清除所有button
this.func = func;//按钮点击回调函数
this.funh = funh;//按钮hover回调函数
this.c = can.getContext('2d');
this.buts = new Array();
this.func = null;//按钮点击回调函数
this.funh = null;//按钮hover回调函数
this.removebuts(){
this.buts = new Array();
}
this.setback = function(src,fun){
//设置背景图片会根据背景图片自动设置宽高
this.backimg = new Image();
this.backimg.src = src;
var c = this.c;
var buts = this.buts;
this.backimg.onload = function(){
c['canvas'].width = this.width;
c['canvas'].height = this.height;
c['canvas'].style.background = 'url('+this.src+') no-repeat 0 0';
c['canvas'].style.backgroundSize = '100% 100%';
draw(c,buts);
if(fun){
fun();
}
};
}
this.setwh = function(w,h){
this.c['canvas'].width = w;
this.c['canvas'].height = h;
}
this.addbuts = function(data,s){
var buts = this.buts;
var func = this.func;
var funh = this.funh;
for(var i in data){
var imgt = new Image();
imgt.src = data[i][0];
imgt.xy = [data[i][1],data[i][2]];
imgt.ishidden = false;
imgt.isactive = i==s;
imgt.titles = data[i][3];
imgt.onload = imgtok(this.buts,imgt,this.c);
function imgtok(but,img,c){
but.push(img);
draw(c,but);
}
}
this.c['canvas'].onmouseout = function(){
for(var i=0;i<buts.length;i++){
buts[i].ishidden = false;
}
draw(this.getContext('2d'),buts);
}
this.c['canvas'].onclick = function(event){
isclick(event,this);
};
this.c['canvas'].onmousemove = function(event){
ismousemove(event,this);
}
function ismousemove(e,t){
e = e|| arguments.callee.caller.arguments[0] || window.event ;
var objTop = getOffsetTop(t);//对象x位置
var objLeft = getOffsetLeft(t);//对象y位置
var mouseX = ( e.clientX || e.pageX)+document.body.scrollLeft;//鼠标x位置
var mouseY = ( e.clientY || e.pageY)+document.body.scrollTop;//鼠标y位置
//计算点击的相对位置
var xy = mousePos(e);
var objX = (xy['x']-objLeft)*(t.width/t.offsetWidth);
var objY = (xy['y']-objTop)*(t.height/t.offsetHeight);
//for in
//buts
var c = t.getContext('2d');
var i =0;
for(;i<buts.length;i++){
if(isin(buts[i],objX,objY)){
buts[i].ishidden = true;
if(funh!=null&&typeof funh=='function'){
funh(buts[i].titles);
}
break ;
}else{
buts[i].ishidden = false;
}
}
i++;
for(;i<buts.length;i++){
buts[i].ishidden = false;
}
draw(c,buts);
}
function isclick(e,t){
e = e|| arguments.callee.caller.arguments[0] || window.event ;
var objTop = getOffsetTop(t);//对象x位置
var objLeft = getOffsetLeft(t);//对象y位置
var mouseX =( e.clientX || e.pageX)+document.body.scrollLeft;//鼠标x位置
var mouseY =( e.clientY || e.pageY)+document.body.scrollTop;//鼠标y位置
//计算点击的相对位置
var xy = mousePos(e);
var objX = (xy['x']-objLeft)*(t.width/t.offsetWidth);
var objY = (xy['y']-objTop)*(t.height/t.offsetHeight);
var c = t.getContext('2d');
var i =0;
var tindex = null;
for(;i<buts.length;i++){
if(isin(buts[i],objX,objY)){
buts[i].isactive = true;
if(func!=null&&typeof func=='function'){
func(buts[i].titles);
}
if(tindex!=null){
buts[tindex].isactive = false;
}
break ;
}else if(buts[i].isactive){
tindex = i;
}
}
i++;
for(;i<buts.length;i++){
buts[i].isactive = false;
}
draw(c,buts);
}
}
}