写在最前:
前两天老大跟我说老虎官网上那个自定义头像的功能是flash实现的,没有安装过的还得手动去“允许”falsh的运行。所以让我用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="/UploadFiles/2021-03-30/<a href=">
写在最后:
canvas的操作,要多多注意那些边界条件,什么时候该重绘什么时候该清除,这些是比较重要的。逻辑清晰了,canvas本身的API也就那么几个,操作起来也就没那么麻烦了,最后,谢谢大家查阅,写的不是很清楚,有不懂的可以一起讨论~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
