cvmachine.com - 申博开户网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:canvas自定义头像功能实现代码示例分析

canvas自定义头像功能实现代码示例分析

2017-11-14 11:41:11 来源:www.cvmachine.com 【

canvas自定义头像功能实现代码示例分析

写在最前:

前两天老大跟我说老虎官网上那个自定义头像的功能是flash实现的,没有安装过的还得手动去“允许”falsh的运行。所以让我用canvas实现一个一样的功能,嘿嘿,刚好最近也在研究canvas,所以欣然答应(其实,你没研究过难道就不答应么,哈哈哈哈哈~)

成果展示:

canvas自定义头像功能实现代码示例分析

Git地址:https://github.com/ry928330/portraitDIY

功能说明:

  • 拖拽左侧小方框,或者是鼠标放在小方框右下角,点击拉伸方框,方框覆盖部分的图片被自动截取下来,然后再在右侧的多个容器里面重绘。
  • 输入宽高,自定义你需要订制的头像大小,目前只支持宽高相同的头像图片。

实现细节:

因为你要对图片所在的区域进行截图,所以你得制作一张canvas,盖在图片所在的区域。这里,我们给出了一个函数,根据传入的DOM里面元素的类名创建相同位置的canvas,盖在原来的DOM元素上面:

function createCanvasByClassName(tag) {
  var canvasInitialWidth = $('.' + tag).width();
  var canvasInitialHeight = $('.' + tag).height();
  var left = $('.' + tag).offset().left - $('.' + tag).parent('.portraitContainer').offset().left + 1;
  var top = $('.' + tag).offset().top - $('.' + tag).parent('.portraitContainer').offset().top + 1;
  //var left = $('.' + tag).offset().left + 1;
  //var top = $('.' + tag).offset().top + 1;
  clearCanvasObj.left = $('.' + tag).offset().left + 1;
  clearCanvasObj.top = $('.' + tag).offset().top + 1;
  // clearCanvasObj.left = left;
  // clearCanvasObj.top = top;
  var canvasElement = $('<canvas></canvas>');
  var randomNum = Math.floor(getRandom(0, 10000));
  clearCanvasObj.canvasId = randomNum;
  canvasElement.attr({
    id: 'canvas',
    width: canvasInitialWidth,
    height: canvasInitialHeight
  });
  canvasElement.css({
    position: 'absolute',
    top: top, 
    left: left
  });
  //$('body').append(canvasElement);
  var appendEle = $('.portraitContainer').append(canvasElement);
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  //ctx.fillStyle = "rgba(211,211,216,0.5)";
  ctx.clearRect(0, 0, canvasInitialWidth, canvasInitialHeight);
  ctx.fillStyle = "rgba(0,0,0, 0.4)";
  ctx.fillRect(0, 0, canvasInitialWidth, canvasInitialHeight);
  return canvas;
}

有了这张canvas你就可以在你图片所在区域肆意的操作了。首先,降整个区域画上一个浅黑色的阴影,然后再擦除初始小方框区域里面的颜色。然后给整个页面添加mousedown,mousemove,mouseup事件,他们所做的功能就跟你在页面中实现一个拖拽的功能类似,这里重点说下mousemove里面做的操作,代码如下:

function mousemoveFunc(event) {
  /* Act on the event */
  var nowMouseX = event.clientX - clearCanvasObj.left;
  var nowMouseY = event.clientY - clearCanvasObj.top;
  if (nowMouseX >= clearCanvasObj.xStart && nowMouseX <= clearCanvasObj.xStart + clearCanvasObj.width && nowMouseY >= clearCanvasObj.yStart && nowMouseY <= clearCanvasObj.yStart + clearCanvasObj.height) {
    clearCanvasObj.isCanvasArea = true;
    //clearCanvasObj.isRightCorner = false;
    imgContainerCanvas.style.cursor = 'move';
  } else if ((nowMouseX >= clearCanvasObj.xStart + clearCanvasObj.width - 10) && (nowMouseX <= clearCanvasObj.xStart+ clearCanvasObj.width + 10) 
    && (nowMouseY >= clearCanvasObj.yStart + clearCanvasObj.height - 10) && (nowMouseY <= clearCanvasObj.yStart + clearCanvasObj.height + 10)) {
    clearCanvasObj.isCanvasArea = true;
    //clearCanvasObj.beginDraw = false;

    imgContainerCanvas.style.cursor = 'se-resize';
  } 
  else {
    clearCanvasObj.isCanvasArea = false;
    //clearCanvasObj.isRightCorner = false;
    imgContainerCanvas.style.cursor = 'default';
  }
  var outerDomWidth = $(".imgContainer").width();
  var outerDomHeight = $(".imgContainer").height();
  var xDistance = event.clientX - clearCanvasObj.mouseX;
  var yDistance = event.clientY - clearCanvasObj.mouseY;
  //var outerCTX = canvas.getContext('2d');
  //移动小方框
  if (clearCanvasObj.beginDraw && clearCanvasObj.isCanvasArea && !clearCanvasObj.isRightCorner) {
    ry_CTX.fillStyle = clearCanvasObj.color;
    // console.log('1', clearCanvasObj.xStart, clearCanvasObj.yStart)
    ry_CTX.fillRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
    //outerCTX.fillRect(0, 0, canvas.width, canvas.height);
    clearCanvasObj.xStart += xDistance;
    clearCanvasObj.yStart += yDistance;

    //判断方框是否达到边界
    if (clearCanvasObj.xStart <= 0) {
      clearCanvasObj.xStart = 0;
    }
    if (clearCanvasObj.yStart <= 0) {
      clearCanvasObj.yStart = 0;
    }
    if ((clearCanvasObj.xStart + clearCanvasObj.width) >= outerDomWidth) {
      clearCanvasObj.xStart = outerDomWidth - clearCanvasObj.width;
    }
    if ((clearCanvasObj.yStart + clearCanvasObj.height) >= outerDomHeight) {
      clearCanvasObj.yStart = outerDomHeight - clearCanvasObj.height;
    }
    // console.log('2', clearCanvasObj.xStart, clearCanvasObj.yStart)
    ry_CTX.clearRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
    produceSmallPic(clearCanvasObj.xStart+clearCanvasObj.left, clearCanvasObj.yStart+clearCanvasObj.top, clearCanvasObj.width, clearCanvasObj.height, imageURL)
    clearCanvasObj.mouseX = event.clientX;
    clearCanvasObj.mouseY = event.clientY;
  }
  //拖拽小方框
  if (clearCanvasObj.isRightCorner) {
    ry_CTX.fillStyle = clearCanvasObj.color;
    ry_CTX.fillRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
    var realDistance = Math.min(xDistance, yDistance)
    clearCanvasObj.width += realDistance;
    clearCanvasObj.height += realDistance;
    //拖动时边界条件的判断
    if (clearCanvasObj.xStart + clearCanvasObj.width >= outerDomWidth) {
      clearCanvasObj.width = outerDomWidth - clearCanvasObj.xStart;
      clearCanvasObj.height = outerDomWidth - clearCanvasObj.xStart;
    }
    if (clearCanvasObj.yStart + clearCanvasObj.height >= outerDomHeight) {
      clearCanvasObj.width = outerDomHeight - clearCanvasObj.yStart;
      clearCanvasObj.height = outerDomHeight - clearCanvasObj.yStart;
    }
    if (clearCanvasObj.width <= 10) {
      clearCanvasObj.width = 10;
    }
    if (clearCanvasObj.height <= 10) {
      clearCanvasObj.height = 10;
    }
    ry_CTX.clearRect(clearCanvasObj.xStart, clearCanvasObj.yStart, clearCanvasObj.width, clearCanvasObj.height);
    produceSmallPic(clearCanvasObj.xStart+clearCanvasObj.left, clearCanvasObj.yStart+clearCanvasObj.top, clearCanvasObj.width, clearCanvasObj.height, imageURL);
    clearCanvasObj.mouseX = event.clientX;
    clearCanvasObj.mouseY = event.clientY;
  }              
}

函数里面,你需要注意拖拽的边界条件,一个是方框不能拖到图片所在DOM外的边界;另外一个就是当你鼠标放在小方框所在的区域改变鼠标的样式。方框在拖动的过程中,我们不断重绘方框移动的区域(也就是不断的画上阴影),然后在新的位置调用clearRect函数,重新擦出一个小方框出来。在拖拽或是拉伸的过程中,我们会不断调用produceSmallPic函数,在右边的容器(每个容器都是一个canvas)里面不断根据容器大小重绘出所需的头像。代码如下:

function produceSmallPic(imageURL,left, top, width, height) {
  var img = new Image();
  img.src = imageURL;
  var targetCtx = new Array();
  var targetCanvas = null;
  img.onload = function() {
    portraitGroupsArr.forEach(function(item, index) {
      targetCanvas = document.getElementById(item.class);
      targetCtx.push(targetCanvas.getContext('2d'));
      targetCtx[index].clearRect(0,0, item.width, item.height);
      targetCtx[index].drawImage(img, left - clearCanvasObj.left, top - clearCanvasObj.top, width, height, 0, 0 , item.width, item.height);
    })
  }
}

我们说下这个函数的作用,这里我们要注意一个参数imageURL,这个URL是由图片所在的DOM转化来的。因为你要把DOM所在的区域变成一张图片,这样你才能在利用drawImage函数截取你所需要的区域。所以我们先利用html2canvas库函数讲图片所在的DOM转化为canvas,这张canvas的内容是包含你所要截取的图片的,然后把这张canvas转化为图片取得图片地址imageURL,代码如下:

html2canvas(document.getElementById('imgContainer'), {
    onrendered: function(canvas) {
      var imageURL = canvasTransToImage(canavs);
      ...
    }

})
function canvasTransToImage(canvas) {
  var imageURL = canvas.toDataURL('image/png');
  return imageURL;
}

接着,你就可以便利右侧的canvas容器,讲图片重回到里面了,整个过程就这样结束,回头看来是不是很简单。

相关依赖:

 


复制代码 代码如下:

<script src="<a href="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script">https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script</a>>

 

写在最后:

canvas的操作,要多多注意那些边界条件,什么时候该重绘什么时候该清除,这些是比较重要的。逻辑清晰了,canvas本身的API也就那么几个,操作起来也就没那么麻烦了,最后,谢谢大家查阅,写的不是很清楚,有不懂的可以一起讨论~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持申博开户。


本文地址:http://www.cvmachine.com/a/question/93774.html
Tags: 实现 canvas 功能
编辑:申博开户网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部
m88.com m88 vwin 188bet uedbet 威廉希尔 vwin 明升 bwin 明升88 bodog bwin 明升m88.com m88 18luck 188bet 博狗 澳门金沙 澳门彩票 unibet unibet Ladbrokes Ladbrokes 12bet 真钱的棋牌游戏 皇冠娱乐 casino casino m88明升 明升88 明升 明升 明升 明升 m88.com m88.com