jquery实现拖拽调整Div大小,html5版canvas自由拼图实
分类:前端技术

SVG 创立 Material Design 波纹效果按键

2017/10/16 · HTML5 · SVG

原来的小说出处: Dennis Gaebel   译文出处:码农网 – 小峰   

乘胜谷歌(Google卡塔尔国 Material Design的现身,生龙活虎种恒心跨平台和道具成立统生机勃勃体验的视觉语言因此盛气凌人。Google通过“Material Guidelines”动漫部分叙述的事例是这么地拟真,引致于许多少人将那几个相互影响视为谷歌(Google卡塔尔品牌的大器晚成有个别。

在本教程中,我们将向大家彰显什么在谷歌 Material Design标准的Radial Action下创设波纹效果,并结合SVG和GreenSock成效。

图片 1

在线演示  源码下载

html5版canvas自由拼图实例,html5canvas拼图

那篇作品主要为大家介绍了html5版canvas自由拼图实例,较为详细的描述了该意义的共同体兑现进度,具备自然的参照他事他说加以考察学习价值,必要的爱侣能够参见下

正文实例陈述了html5版canvas自由拼图的落到实处格局。共享给大家供大家仿效。具体方法如下:

代码运营效果如下图所示:

图片 2 

canvasElement.js代码如下:

代码如下:

define('canvasElement', [ '../multi_upload/core' ], function(S) {
var Canvas = window.Canvas || {};
(function () {
Canvas.Element = function() {};
Canvas.Element.prototype.fillBackground = true;
Canvas.Element.prototype.showcorners = false;
Canvas.Element.prototype.photoborder = true;
Canvas.Element.prototype.polaroid = false;
Canvas.Element.prototype._backgroundImg = null;
Canvas.Element.prototype._groupSelector = null;
Canvas.Element.prototype._aImages = null;
Canvas.Element.prototype._oContext = null;
Canvas.Element.prototype._oElement = null;
Canvas.Element.prototype._oConfig = null;
Canvas.Element.prototype._currentTransform = null;
Canvas.Element.prototype._prevTransform = null;
Canvas.Element.prototype.curAngle = null;
Canvas.Element.prototype.init = function(el, oConfig) {
if (el == '') {
return;
}
this._initElement(el);
this._initConfig(oConfig);
this._createCanvasBackground();
this._createContainer();
this._initEvents();
this._initCustomEvents();
};
Canvas.Element.prototype._initElement = function(el) {
this._oElement = document.getElementById(el);
this._oContextTop = this._oElement.getContext('2d');
};
Canvas.Element.prototype._initCustomEvents = function() {
this.onRotateStart = new Canvas.CustomEvent('onRotateStart');
this.onRotateMove = new Canvas.CustomEvent('onRotateMove');
this.onRotateComplete = new Canvas.CustomEvent('onRotateComplete');
this.onDragStart = new Canvas.CustomEvent('onDragStart');
this.onDragMove = new Canvas.CustomEvent('onDragMove');
this.onDragComplete = new Canvas.CustomEvent('onDragComplete');
};
Canvas.Element.prototype._initConfig = function(oConfig) {
this._oConfig = oConfig;
this._oElement.width = this._oConfig.width;
this._oElement.height = this._oConfig.height;
this._oElement.style.width = this._oConfig.width 'px';
this._oElement.style.height = this._oConfig.height 'px';
};
Canvas.Element.prototype._initEvents = function() {
var _this=this;
S(this._oElement).on('mousedown',function(e){
_this.onMouseDown(e);
});
S(this._oElement).on( 'mouseup', function(e){
_this.onMouseUp(e);
});
S(this._oElement).on('mousemove', function(e){
_this.onMouseMove(e);
});
};
Canvas.Element.prototype._createContainer = function() {
var canvasEl = document.createElement('canvas');
canvasEl.id = this._oElement.id '-canvas-container';
var oContainer = this._oElement.parentNode.insertBefore(canvasEl, this._oElement);
oContainer.width = this._oConfig.width;
oContainer.height = this._oConfig.height;
oContainer.style.width = this._oConfig.width 'px';
oContainer.style.height = this._oConfig.height 'px';
this._oContextContainer = oContainer.getContext('2d');
};
Canvas.Element.prototype._createCanvasBackground = function() {
var canvasEl = document.createElement('canvas');
canvasEl.id = this._oElement.id '-canvas-background';
var oBackground = this._oElement.parentNode.insertBefore(canvasEl, this._oElement);
oBackground.width = this._oConfig.width;
oBackground.height = this._oConfig.height;
oBackground.style.width = this._oConfig.width 'px';
oBackground.style.height = this._oConfig.height 'px';
this._oContextBackground = oBackground.getContext('2d');
};
Canvas.Element.prototype.setCanvasBackground = function(oImg) {
this._backgroundImg = oImg;
var originalImgSize = oImg.getOriginalSize();
this._oContextBackground.drawImage(oImg._oElement, 0, 0, originalImgSize.width, originalImgSize.height);
};
Canvas.Element.prototype.onMouseUp = function(e) {
if (this._aImages == null) {
return;
}
if (this._currentTransform) {
this._currentTransform.target.setImageCoords();
}
if (this._currentTransform != null && this._currentTransform.action == "rotate") {
this.onRotateComplete.fire(e);
} else if (this._currentTransform != null && this._currentTransform.action == "drag") {
this.onDragComplete.fire(e);
}
this._currentTransform = null;
this._groupSelector = null;
this.renderTop();
};
Canvas.Element.prototype.onMouseDown = function(e) {
var mp = this.findMousePosition(e);
if (this._currentTransform != null || this._aImages == null) {
return;
}
var oImg = this.findTargetImage(mp, false);
if (!oImg) {
this._groupSelector = { ex: mp.ex, ey: mp.ey,
top: 0, left: 0 };
}
else {
var action = (!this.findTargetCorner(mp, oImg)) ? 'drag' : 'rotate';
if (action == "rotate") {
this.onRotateMove.fire(e);
} else if (action == "drag") {
this.onDragMove.fire(e);
}
this._prevTransform=this._currentTransform = {
target: oImg,
action: action,
scalex: oImg.scalex,
offsetX: mp.ex - oImg.left,
offsetY: mp.ey - oImg.top,
ex: mp.ex, ey: mp.ey,
left: oImg.left, top: oImg.top,
theta: oImg.theta
};
$('canvas_menu').style.transform='rotate(' oImg.theta*180/3.14 'deg)';
$('canvas_menu').style.left=oImg.left "px";
$('canvas_menu').style.top=oImg.top "px";
$('canvas_menu').style.display="block";
this.renderAll(false,false);
}
};
Canvas.Element.prototype.onMouseMove = function(e) {
var mp = this.findMousePosition(e);
if (this._aImages == null) {
return;
}
if (this._groupSelector != null) {
this._groupSelector.left = mp.ex - this._groupSelector.ex;
this._groupSelector.top = mp.ey - this._groupSelector.ey;
this.renderTop();
}
else if (this._currentTransform == null) {
var targetImg = this.findTargetImage(mp, true);
this.setCursor(mp, targetImg);
}
else {
if (this._currentTransform.action == 'rotate') {
this.rotateImage(mp);
this.scaleImage(mp);
this.onRotateMove.fire(e);
}
else {
this.translateImage(mp);
this.onDragMove.fire(e);
}
this.renderTop();
}
};
Canvas.Element.prototype.translateImage = function(mp) {
this._currentTransform.target.left = mp.ex - this._currentTransform.offsetX;
this._currentTransform.target.top = mp.ey - this._currentTransform.offsetY;
$('canvas_menu').style.left=this._currentTransform.target.left "px";
$('canvas_menu').style.top=this._currentTransform.target.top "px";
};
Canvas.Element.prototype.scaleImage = function(mp) {
var lastLen =
Math.sqrt(Math.pow(this._currentTransform.ey - this._currentTransform.top, 2)
Math.pow(this._currentTransform.ex - this._currentTransform.left, 2));
var curLen =
Math.sqrt(Math.pow(mp.ey - this._currentTransform.top, 2)
Math.pow(mp.ex - this._currentTransform.left, 2));
var curScalex= this._currentTransform.scalex * (curLen / lastLen);
var curScaley=this._currentTransform.target.scalex;
if(curScalex>0.7&&curScaley>0.7){
this._currentTransform.target.scalex =curScalex;
this._currentTransform.target.scaley = curScaley;
}
};
Canvas.Element.prototype.rotateImage = function(mp) {
var lastAngle = Math.atan2(
this._currentTransform.ey - this._currentTransform.top,
this._currentTransform.ex - this._currentTransform.left
);

var curAngle = Math.atan2(
mp.ey - this._currentTransform.top,
mp.ex - this._currentTransform.left
);
this._currentTransform.target.theta = (curAngle - lastAngle) this._currentTransform.theta;
this.curAngle=this._currentTransform.target.theta*180/3.14;
$('canvas_menu').style.transform='rotate(' this.curAngle 'deg)';
};
Canvas.Element.prototype.setCursor = function(mp, targetImg) {
if (!targetImg) {
this._oElement.style.cursor = 'default';
}
else {
var corner = this.findTargetCorner(mp, targetImg);
if (!corner)
{
this._oElement.style.cursor = 'default';
}
else
{
if(corner == 'tr') {
this._oElement.style.cursor = 'ne-resize';
}
else if(corner == 'br') {
this._oElement.style.cursor = 'se-resize';
}
else if(corner == 'bl') {
this._oElement.style.cursor = 'sw-resize';
}
else if(corner == 'tl') {
this._oElement.style.cursor = 'nw-resize';
}
else {
this._oElement.style.cursor = 'default';
}
}
}
};
Canvas.Element.prototype.addImage = function(oImg) {
if(S.isEmptyObject(this._aImages)) {
this._aImages = [];
}
this._aImages.push(oImg);
this.renderAll(false,true);</p> <p> };
Canvas.Element.prototype.renderAll = function(allOnTop,allowCorners) {
var containerCanvas = (allOnTop) ? this._oContextTop : this._oContextContainer;
this._oContextTop.clearRect(0,0,parseInt(this._oConfig.width), parseInt(this._oConfig.height));
containerCanvas.clearRect(0,0,parseInt(this._oConfig.width), parseInt(this._oConfig.height));
if (allOnTop) {
var originalImgSize = this._backgroundImg.getOriginalSize();
this._oContextTop.drawImage(this._backgroundImg._oElement, 0, 0, originalImgSize.width, originalImgSize.height);
}
for (var i = 0, l = this._aImages.length-1; i < l; i = 1) {
this.drawImageElement(containerCanvas, this._aImages[i],allowCorners);
}
this.drawImageElement(this._oContextTop, this._aImages[this._aImages.length-1],allowCorners);
};
Canvas.Element.prototype.renderTop = function() {
this._oContextTop.clearRect(0,0,parseInt(this._oConfig.width), parseInt(this._oConfig.height));
this.drawImageElement(this._oContextTop, this._aImages[this._aImages.length-1],true);
if (this._groupSelector != null) {
this._oContextTop.fillStyle = "rgba(0, 0, 200, 0.5)";
this._oContextTop.fillRect(
this._groupSelector.ex - ((this._groupSelector.left > 0) ?
0 : - this._groupSelector.left),
this._groupSelector.ey - ((this._groupSelector.top > 0) ?
0 : - this._groupSelector.top),
Math.abs(this._groupSelector.left),
Math.abs(this._groupSelector.top)
);
this._oContextTop.strokeRect(
this._groupSelector.ex - ((this._groupSelector.left > 0) ?
0 : Math.abs(this._groupSelector.left)),
this._groupSelector.ey - ((this._groupSelector.top > 0) ?
0 : Math.abs(this._groupSelector.top)),
Math.abs(this._groupSelector.left),
Math.abs(this._groupSelector.top)
);
}
};
Canvas.Element.prototype.drawImageElement = function(context, oImg,allowCorners) {
oImg.cornervisibility=allowCorners;
var offsetY = oImg.height / 2;
var offsetX = oImg.width / 2;
context.save();
context.translate(oImg.left, oImg.top);
context.rotate(oImg.theta);
context.scale(oImg.scalex, oImg.scaley);
this.drawBorder(context, oImg, offsetX, offsetY);
var originalImgSize = oImg.getOriginalSize();
var polaroidHeight = ((oImg.height - originalImgSize.height) - (oImg.width - originalImgSize.width))/2;
context.drawImage(
oImg._oElement,

  • originalImgSize.width/2,
    ((- originalImgSize.height)/2 - polaroidHeight),
    originalImgSize.width,
    originalImgSize.height
    );
    if (oImg.cornervisibility) {
    this.drawCorners(context, oImg, offsetX, offsetY);
    }
    context.restore();
    };
    Canvas.Element.prototype._getImageLines = function(oCoords) {
    return {
    topline: {
    o: oCoords.tl,
    d: oCoords.tr
    },
    rightline: {
    o: oCoords.tr,
    d: oCoords.br
    },
    bottomline: {
    o: oCoords.br,
    d: oCoords.bl
    },
    leftline: {
    o: oCoords.bl,
    d: oCoords.tl
    }
    };
    };
    Canvas.Element.prototype.findTargetImage = function(mp, hovering) {
    for (var i = this._aImages.length-1; i >= 0; i -= 1) {
    var iLines = this._getImageLines(this._aImages[i].oCoords);
    var xpoints = this._findCrossPoints(mp, iLines);
    if (xpoints % 2 == 1 && xpoints != 0) {
    var target = this._aImages[i];
    if (!hovering) {
    this._aImages.splice(i, 1);
    this._aImages.push(target);
    }
    return target;
    }
    }
    return false;
    };
    Canvas.Element.prototype._findCrossPoints = function(mp, oCoords) {
    var b1, b2, a1, a2, xi, yi;
    var xcount = 0;
    var iLine = null;
    for (lineKey in oCoords) {
    iLine = oCoords[lineKey];
    if ((iLine.o.y < mp.ey) && (iLine.d.y < mp.ey)) {
    continue;
    }
    if ((iLine.o.y >= mp.ey) && (iLine.d.y >= mp.ey)) {
    continue;
    }
    if ((iLine.o.x == iLine.d.x) && (iLine.o.x >= mp.ex)) {
    xi = iLine.o.x;
    yi = mp.ey;
    }
    else {
    b1 = 0;
    b2 = (iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);
    a1 = mp.ey-b1*mp.ex;
    a2 = iLine.o.y-b2*iLine.o.x;
    xi = - (a1-a2)/(b1-b2);
    yi = a1 b1*xi;
    }
    if (xi >= mp.ex) {
    xcount = 1;
    }
    if (xcount == 2) {
    break;
    }
    }
    return xcount;
    };
    Canvas.Element.prototype.findTargetCorner = function(mp, oImg) {
    var xpoints = null;
    var corners = ['tl','tr','br','bl'];
    for (var i in oImg.oCoords) {
    xpoints = this._findCrossPoints(mp, this._getImageLines(oImg.oCoords[i].corner));
    if (xpoints % 2 == 1 && xpoints != 0) {
    return i;
    }
    }
    return false;
    };
    Canvas.Element.prototype.findMousePosition = function(e) {
    var parentNode = (e.srcElement) ? e.srcElement.parentNode : e.target.parentNode;
    var isSafari2 = !S.support.ie&&!S.support.firefox;
    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var safariOffsetLeft = (isSafari2) ? e.target.ownerDocument.body.offsetLeft scrollLeft : 0;
    var safariOffsetTop = (isSafari2) ? e.target.ownerDocument.body.offsetTop scrollTop : 0;
    return {
    ex: e.clientX scrollLeft - parentNode.offsetLeft - safariOffsetLeft,
    ey: e.clientY scrollTop - parentNode.offsetTop - safariOffsetTop,
    screenX: e.screenX,
    screenY: e.screenY
    };
    };
    Canvas.Element.prototype.drawBorder = function(context, oImg, offsetX, offsetY) {
    var outlinewidth = 2;
    context.fillStyle = 'rgba(0, 0, 0, .3)';
    context.fillRect(-2 - offsetX, -2 - offsetY, oImg.width (2 * outlinewidth), oImg.height (2 * outlinewidth));
    context.fillStyle = '#fff';
    context.fillRect(-offsetX, -offsetY, oImg.width, oImg.height);
    };
    Canvas.Element.prototype.drawCorners = function(context, oImg, offsetX, offsetY) {
    context.fillStyle = "rgba(0, 200, 50, 0.5)";
    context.fillRect(-offsetX, -offsetY, oImg.cornersize, oImg.cornersize);
    context.fillRect(oImg.width - offsetX - oImg.cornersize, -offsetY, oImg.cornersize, oImg.cornersize);
    context.fillRect(-offsetX, oImg.height - offsetY - oImg.cornersize, oImg.cornersize, oImg.cornersize);
    context.fillRect(oImg.width - offsetX - oImg.cornersize, oImg.height - offsetY - oImg.cornersize, oImg.cornersize, oImg.cornersize);
    };
    Canvas.Element.prototype.clearCorners = function(context, oImg, offsetX, offsetY) {
    context.clearRect(-offsetX, -offsetY, oImg.cornersize, oImg.cornersize);
    context.clearRect(oImg.width - offsetX - oImg.cornersize, -offsetY, oImg.cornersize, oImg.cornersize);
    context.clearRect(-offsetX, oImg.height - offsetY - oImg.cornersize, oImg.cornersize, oImg.cornersize);
    context.clearRect(oImg.width - offsetX - oImg.cornersize, oImg.height - offsetY - oImg.cornersize, oImg.cornersize, oImg.cornersize);
    context.restore();
    };
    Canvas.Element.prototype.canvasTo = function(format) {
    this.renderAll(true,false);
    var containerCanvas =this._oContextTop;
    for (var i = 0, l = this._aImages.length; i < l; i = 1) {
    var offsetY = this._aImages[i].height / 2;
    var offsetX = this._aImages[i].width / 2;
    this.clearCorners(containerCanvas, this._aImages[i], offsetX, offsetY);
    }
    if (format == 'jpeg' || format == 'png') {
    return this._oElement.toDataURL('image/' format);
    }
    };
    Canvas.CustomEvent = function(type) {
    this.type = type;
    this.scope = null;
    this.handler = null;
    var self = this;
    this.fire = function(e) {
    if(this.handler != null) {
    self.handler.call(self.scope, e);
    }
    };
    };
    }());
    return Canvas;
    });

canvasImg.js代码如下:

代码如下:

define('canvasImg', [ '../multi_upload/core' ], function(S) {
var Canvas = window.Canvas || {};
(function () {
Canvas.Img = function(el, oConfig) {
this._initElement(el);
this._initConfig(oConfig);
this.setImageCoords();
};
Canvas.Img.CSS_CANVAS = "canvas-img";
var DEFAULT_CONFIG = {
"TOP": {
key: "top",
value: 10
},
"LEFT": {
key: "left",
value: 10
},
"ANGLE": {
key: "angle",
value: 0
},
"THETA": {
key: "theta",
value: 0
},
"SCALE-X": {
key: "scalex",
value: 1
},
"SCALE-Y": {
key: "scaley",
value: 1
},
"CORNERSIZE": {
key: "cornersize",
value:10
},
"BORDERWIDTH": {
key: "borderwidth",
value: 10
},
"POLAROIDHEIGHT": {
key: "polaroidheight",
value: 40
},
"RANDOMPOSITION": {
key: "randomposition",
value: true
}
};
Canvas.Img.prototype._oElement = null;
Canvas.Img.prototype.top = null;
Canvas.Img.prototype.left = null;
Canvas.Img.prototype.maxwidth = null;
Canvas.Img.prototype.maxheight = null;
Canvas.Img.prototype.oCoords = null;
Canvas.Img.prototype.angle = null;
Canvas.Img.prototype.theta = null;
Canvas.Img.prototype.scalex = null;
Canvas.Img.prototype.scaley = null;
Canvas.Img.prototype.cornersize = null;
Canvas.Img.prototype.polaroidheight = null;
Canvas.Img.prototype.randomposition = null;
Canvas.Img.prototype.selected = false;
Canvas.Img.prototype.bordervisibility = false;
Canvas.Img.prototype.cornervisibility = false;
Canvas.Img.prototype._initElement = function(el) {
this._oElement = el;
};
Canvas.Img.prototype._initConfig = function(oConfig) {
var sKey;
for (sKey in DEFAULT_CONFIG) {
var defaultKey = DEFAULT_CONFIG[sKey].key;
if (!oConfig.hasOwnProperty(defaultKey)) { // = !(defaultKey in oConfig)
this[defaultKey] = DEFAULT_CONFIG[sKey].value;
}
else {
this[defaultKey] = oConfig[defaultKey];
}
}
if (this.bordervisibility) {
this.currentBorder = this.borderwidth;
}
else {
this.currentBorder = 0;
}
var normalizedSize = this.getNormalizedSize(this._oElement, parseInt(oConfig.maxwidth), parseInt(oConfig.maxheight));
this._oElement.width = normalizedSize.width;
this._oElement.height = normalizedSize.height;
this.width = normalizedSize.width (2 * this.currentBorder);
this.height = normalizedSize.height (2 * this.currentBorder);
if (this.randomposition) {
this._setRandomProperties(oConfig);
}
this.theta = this.angle * (Math.PI/180);
};
Canvas.Img.prototype.getNormalizedSize = function(oImg, maxwidth, maxheight) {
if (maxheight && maxwidth && (oImg.width > oImg.height && (oImg.width / oImg.height) < (maxwidth / maxheight))) {
normalizedWidth = Math.floor((oImg.width * maxheight) / oImg.height);
normalizedHeight = maxheight;
}
else if (maxheight && ((oImg.height == oImg.width) || (oImg.height > oImg.width) || (oImg.height > maxheight))) {
normalizedWidth = Math.floor((oImg.width * maxheight) / oImg.height);
normalizedHeight = maxheight;
}
else if (maxwidth && (maxwidth < oImg.width)){
normalizedHeight = Math.floor((oImg.height * maxwidth) / oImg.width);
normalizedWidth = maxwidth;
}
else {
normalizedWidth = oImg.width;
normalizedHeight = oImg.height;
}
return { width: normalizedWidth, height: normalizedHeight }
},
Canvas.Img.prototype.getOriginalSize = function() {
return { width: this._oElement.width, height: this._oElement.height }
};
Canvas.Img.prototype._setRandomProperties = function(oConfig) {
if (oConfig.angle == null) {
this.angle = (Math.random() * 90);
}
if (oConfig.top == null) {
this.top = this.height / 2 Math.random() * 450;
}
if (oConfig.left == null) {
this.left = this.width / 2 Math.random() * 600;
}
};
Canvas.Img.prototype.setCornersVisibility = function(visible) {
this.cornervisibility = visible;
};
Canvas.Img.prototype.setImageCoords = function() {
this.left = parseInt(this.left);
this.top = parseInt(this.top);
this.currentWidth = parseInt(this.width) * this.scalex;
this.currentHeight = parseInt(this.height) * this.scalex;
this._hypotenuse = Math.sqrt(Math.pow(this.currentWidth / 2, 2) Math.pow(this.currentHeight / 2, 2));
this._angle = Math.atan(this.currentHeight / this.currentWidth);
var offsetX = Math.cos(this._angle this.theta) * this._hypotenuse;
var offsetY = Math.sin(this._angle this.theta) * this._hypotenuse;
var theta = this.theta;
var sinTh = Math.sin(theta);
var cosTh = Math.cos(theta);
var tl = {
x: this.left - offsetX,
y: this.top - offsetY
};
var tr = {
x: tl.x (this.currentWidth * cosTh),
y: tl.y (this.currentWidth * sinTh)
};
var br = {
x: tr.x - (this.currentHeight * sinTh),
y: tr.y (this.currentHeight * cosTh)
};
var bl = {
x: tl.x - (this.currentHeight * sinTh),
y: tl.y (this.currentHeight * cosTh)
};
this.oCoords = { tl: tl, tr: tr, br: br, bl: bl };
this.setCornerCoords();
};
Canvas.Img.prototype.setCornerCoords = function() {
var coords = this.oCoords;
var theta = this.theta;
var cosOffset = this.cornersize * this.scalex * Math.cos(theta);
var sinOffset = this.cornersize * this.scalex * Math.sin(theta);
coords.tl.corner = {
tl: {
x: coords.tl.x,
y: coords.tl.y
},
tr: {
x: coords.tl.x cosOffset,
y: coords.tl.y sinOffset
},
bl: {
x: coords.tl.x - sinOffset,
y: coords.tl.y cosOffset
}
};
coords.tl.corner.br = {
x: coords.tl.corner.tr.x - sinOffset,
y: coords.tl.corner.tr.y cosOffset
};

coords.tr.corner = {
tl: {
x: coords.tr.x - cosOffset,
y: coords.tr.y - sinOffset
},
tr: {
x: coords.tr.x,
y: coords.tr.y
},
br: {
x: coords.tr.x - sinOffset,
y: coords.tr.y cosOffset
}
};
coords.tr.corner.bl = {
x: coords.tr.corner.tl.x - sinOffset,
y: coords.tr.corner.tl.y cosOffset
};

coords.bl.corner = {
tl: {
x: coords.bl.x sinOffset,
y: coords.bl.y - cosOffset
},
bl: {
x: coords.bl.x,
y: coords.bl.y
},
br: {
x: coords.bl.x cosOffset,
y: coords.bl.y sinOffset
}
};
coords.bl.corner.tr = {
x: coords.bl.corner.br.x sinOffset,
y: coords.bl.corner.br.y - cosOffset
};

coords.br.corner = {
tr: {
x: coords.br.x sinOffset,
y: coords.br.y - cosOffset
},
bl: {
x: coords.br.x - cosOffset,
y: coords.br.y - sinOffset
},
br: {
x: coords.br.x,
y: coords.br.y
}
};
coords.br.corner.tl = {
x: coords.br.corner.bl.x sinOffset,
y: coords.br.corner.bl.y - cosOffset
};
};
}());
return Canvas;
});

puzzle.html代码如下:

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link type="text/css" href="html5_puzzle.css" rel="stylesheet" />
<script type="text/javascript" src="../multi_upload/seed.js"></script>
<script type="text/javascript" src='html5_puzzle.js'></script>
</head>
<body>
<div id='html5_puzzle'>
<div id='puzzle_left'>
<div class='puzzle_column'>
<ul>
<li><img src='small_img/1.jpg' data-index='1' /></li>
<li><img src='small_img/2.jpg' data-index='2' /></li>
<li><img src='small_img/3.jpg' data-index='3' /></li>
<li><img src='small_img/4.jpg' data-index='4' /></li>
<li><img src='small_img/5.jpg' data-index='5' /></li>
</ul>
</div>
<div class='puzzle_column'>
<ul>
<li><img src='small_img/6.jpg' data-index='6' /></li>
<li><img src='small_img/7.jpg' data-index='7' /></li>
<li><img src='small_img/8.jpg' data-index='8' /></li>
<li><img src='small_img/9.jpg' data-index='9' /></li>
<li><img src='small_img/10.jpg' data-index='10' /></li>
</ul>
</div>
</div>
<div id='puzzle_right'>
<div id='puzzle_canvas'>
<canvas id="canvid1"></canvas>
<div id='canvas_menu'>
<a href='javascript:void(0)' id='photo_delete'>删除</a> <a
href='javascript:void(0)' id='photo_update'>更正图片</a>
</div>
</div>
<img id="bg" src="big_img/1.jpg" width='600' height='450' />
</div>
<div id='puzzle_bottom'>
<a href='javascript:void(0)' id='add_img'><span>加多图片</span><input
type="file" multiple="" id='fileImage'> </a> <a
href='javascript:void(0)' id='upload_btn'>上传</a> <a>点击图片能够旋转,拖拽,
缩放哦!</a>
</div>
</div>
<input type="file" id='test'>
<canvas id='test_canvas'></canvas>
</body>
</html>

html5_puzzle.css代码如下:

代码如下:

@CHARSET "UTF-8";</p> <p>#html5_puzzle {
font-size: 0;
}</p> <p>canvas {
background-color: transparent;
left: 0;
position: absolute;
top: 0;
}</p> <p>.puzzle_column,#puzzle_left,#puzzle_right,#add_img {
display: inline-block;
}</p> <p>.puzzle_column li {
display: block;
margin: 5px;
border: 1px solid #ffffff;
}</p> <p>.puzzle_column li:hover {
border: 1px solid #3B5998;
cursor: pointer;
}</p> <p>.puzzle_column {
font-size: 0;
}</p> <p>#puzzle_left,#puzzle_right {
border: 1px solid #3B5998;
}</p> <p>#puzzle_right,#puzzle_bottom a {
font-size: 14px;
margin: 10px 0 0 10px;
}</p> <p>#puzzle_bottom {
margin: 5px 0;
}</p> <p>#puzzle_canvas img {

}</p> <p>#puzzle_canvas {
overflow: hidden;
width: 600px;
height: 450px;
position: relative;
}</p> <p>#add_img input {
position: absolute;
font-size: 100px;
right: 0;
top: 0;
opacity: 0;
}</p> <p>#add_img {
position: relative;
display: inline-block;
background: #3B5998;
border-radius: 4px;
padding: 4px 12px;
overflow: hidden;
color: #ffffff;
}</p> <p>#bg,#show_list {
display: none;
}</p> <p>#canvas_menu {
border: 1px solid red;
position: absolute;
z-index: 5;
top: 0;
left: 0;
display: none;
}</p> <p>#canvas_menu a {
display: inline-block;
}</p> <p>#test_canvas {
top: 700px;
}

html5_puzzle.js代码如下:

代码如下:

require([ 'img_upload', '../puzzle/canvasImg', '../puzzle/canvasElement' ], function(
S, canvasImg, canvasElement) {
var img=[];
var canvas = new canvasElement.Element();
canvas.init('canvid1', {
width : 600,
height : 450
});
S('.puzzle_column img').on('click',function(e){
var index=this.getAttribute('data-index');
$('bg').onload = function() {
var ctx=$('canvid1-canvas-background').getContext('2d');
ctx.clearRect(0, 0,600,450);
img[0]=new canvasImg.Img($('bg'), {});
canvas.setCanvasBackground(img[0]);
};
$('bg').setAttribute('src','medium_img/' index '.jpg');
e.stopPropagation();
});
var CanvasDemo = function() {
return {
init : function() {
var img_list=dom.query('#puzzle_canvas img');
img[0]=new canvasImg.Img($('bg'), {});
S.each(img_list,function(i,el){
el.setAttribute('data-index',i);
img.push(new canvasImg.Img(el, {}));
canvas.addImage(img[i 1]);
});
canvas.setCanvasBackground(img[0]);
this.cornersvisible = (this.cornersvisible) ? false : true;
this.modifyImages(function(image) {
image.setCornersVisibility(this.cornersvisible);
});
},
modifyImages : function(fn) {
for ( var i =0, l = canvas._aImages.length; i < l; i = 1) {
fn.call(this, canvas._aImages[i]);
}
canvas.renderAll(false,false);
S('#puzzle_canvas img').remove();
img = [];
}
};
}();
function getCurImg(){
var oImg=canvas._prevTransform.target;
for(var i=0;i<canvas._aImages.length;i ){
if(canvas._aImages[i]._oElement.src==oImg._oElement.src){
return i;
}
}
}
S('#photo_delete').on('click',function(e){
var i=getCurImg();
canvas._aImages.splice(i,1);
canvas.renderAll(true,true);
$('canvas_menu').style.display="none";
});
S('#photo_update').on('click',function(e){
$('test').click();
});
S('#test').on('change',function(e){
var files = e.target.files || e.dataTransfer.files;
var reader = new FileReader();
reader.onload = (function() {
return function(e) {
var dataURL = e.target.result, canvas1 = document.querySelector('#test_canvas'), ctx = canvas1.getContext('2d'), img = new Image();
img.onload = function(e) {
if(img.width>200||img.height>200){
var prop=Math.min(200/img.width,200/img.height);
img.width=img.width*prop;
img.height=img.height*prop;
}
canvas1.width=img.width;
canvas1.height=img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
S('#canvid1').html(S('#canvid1').html() "<img src='" canvas1.toDataURL("image/jpeg") "'/>");
var t = window.setTimeout(function() {
var i=getCurImg(),target=canvas._prevTransform.target;
console.log(target);
canvas._aImages[i]=new canvasImg.Img(dom.query('#canvid1 img')[0], {
top:target.top,
left:target.left,
scalex:target.scalex,
scaley:target.scaley,
angle:canvas.curAngle
});
canvas.renderTop();
clearTimeout(t);
S('#canvid1 img').remove();
},1000);
};
img.src = dataURL;
};
})();
reader.readAsDataURL(files[0]);
});
S('#upload_btn').on('click',function(){
var imgData = canvas.canvasTo('jpeg');
var imgValue = imgData.substr(22);
S.ajax({
url : '',
type : 'POST',
data : {
imgData : imgValue,
file_name :'mix_img.jpeg'
},
dataType : 'text',
success : function(data) {
alert("s");
}
});
});
});

至于用html5 input读取图片,那比较轻易就不贴出来了。

希望本文所述对我们的HTML5程序设计有所协理。

zepto的tap事件点透难题解析:

前几天写了一天那些jquery插件:

响应式动作

Google使用Radial Action定义Responsive Interaction如下:

Radial action is the visual ripple of ink spreading outward from the point of input.
The connection between an input event and on-screen action should be visually represented to tie them together. For touch or mouse, this occurs at the point of contact. A touch ripple indicates where and when a touch occurs and acknowledges that the touch input was received.
Transitions, or actions triggered by input events, should visually connect to input events. Ripple reactions near the epicenter occur sooner than reactions further away.

Google特别明白地发挥了输入反馈应从原点出发,向外扩散。举例,假设客商直接在基本点击按键,则纹波将从开首接触点向外扩展。那便是我们怎样建议触摸发生的地址和时间的主意,以便向客商确认采取到的输入。

大器晚成、点透是怎么样

您可能遇到过在列表页面上创办一个弹出层,弹出层有个闭馆的开关,你点了那个按键关闭弹出层后后,这么些开关正下方的剧情也会执行点击事件(或展开链接卡塔尔。那些被定义为那是二个“点透”现象。
在前方的项目中相见了如下图的主题素材:在点击弹出来的挑肥拣瘦组件的右上角达成后会让实现前面包车型地铁input输入框集中,弹出输入键盘,也正是点透了

图片 3

技能分享

能够兑现对div实行拖拽来调动大小的法力。

SVG中的径向动作

有成都百货上千开辟职员创作纹波技巧,重要运用CSS本领,如@keyframes,transitions,transforms伪手艺,border-radius甚至以至额外的号子,如span或div。不采纳CSS,让大家来走访怎么着通过GreenSock的Tween马克斯库用SVG来成立那个通往动作。

二、为啥会不由自主点透?

咱俩来探访zepto源码里面看关于tap的达成方式:

(http://upload-images.jianshu.io/upload_images/1782900-f64f9813022596c6.gif?imageMogr2/auto-orient/strip) 1 $(document).ready(function(){ 2 var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType 3 4 if (‘MSGesture‘ in window) { 5 gesture = new MSGesture() 6 gesture.target = document.body 7 } 8 9 $(document) 10 .bind(‘MSGestureEnd‘, function(e){ 11 var swipeDirectionFromVelocity = 12 e.velocityX > 1 ? ‘Right‘ : e.velocityX < -1 ? ‘Left‘ : e.velocityY > 1 ? ‘Down‘ : e.velocityY < -1 ? ‘Up‘ : null; 13 if (swipeDirectionFromVelocity) { 14 touch.el.trigger(‘swipe‘) 15 touch.el.trigger(‘swipe‘ swipeDirectionFromVelocity) 16 } 17 }) 18 .on(‘touchstart MSPointerDown pointerdown‘, function(e){ 19 if((_isPointerType = isPointerEventType(e, ‘down‘)) && 20 !isPrimaryTouch(e)) return 21 firstTouch = _isPointerType ? e : e.touches[0] 22 if (e.touches && e.touches.length === 1 && touch.x2) { 23 // Clear out touch movement data if we have it sticking around 24 // This can occur if touchcancel doesn‘t fire due to preventDefault, etc. 25 touch.x2 = undefined 26 touch.y2 = undefined 27 } 28 now = Date.now() 29 delta = now - (touch.last || now) 30 touch.el = $(‘tagName‘ in firstTouch.target ? 31 firstTouch.target : firstTouch.target.parentNode) 32 touchTimeout && clearTimeout(touchTimeout) 33 touch.x1 = firstTouch.pageX 34 touch.y1 = firstTouch.pageY 35 if (delta > 0 && delta <= 250) touch.isDoubleTap = true 36 touch.last = now 37 longTapTimeout = setTimeout(longTap, longTapDelay) 38 // adds the current touch contact for IE gesture recognition 39 if (gesture && _isPointerType) gesture.addPointer(e.pointerId); 40 }) 41 .on(‘touchmove MSPointerMove pointermove‘, function(e){ 42 if((_isPointerType = isPointerEventType(e, ‘move‘)) && 43 !isPrimaryTouch(e)) return 44 firstTouch = _isPointerType ? e : e.touches[0] 45 cancelLongTap() 46 touch.x2 = firstTouch.pageX 47 touch.y2 = firstTouch.pageY 48 49 deltaX = Math.abs(touch.x1 - touch.x2) 50 deltaY = Math.abs(touch.y1

  • touch.y2) 51 }) 52 .on(‘touchend MSPointerUp pointerup‘, function(e){ 53 if((_isPointerType = isPointerEventType(e, ‘up‘)) && 54 !isPrimaryTouch(e)) return 55 cancelLongTap() 56 57 // swipe 58 if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || 59 (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) 60 61 swipeTimeout = setTimeout(function() { 62 touch.el.trigger(‘swipe‘) 63 touch.el.trigger(‘swipe‘ (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))) 64 touch = {} 65 }, 0) 66 67 // normal tap 68 else if (‘last‘ in touch) 69 // don‘t fire tap when delta position changed by more than 30 pixels, 70 // for instance when moving to a point and back to origin 71 if (deltaX < 30 && deltaY < 30) { 72 // delay by one tick so we can cancel the ‘tap‘ event if ‘scroll‘ fires 73 // (‘tap‘ fires before ‘scroll‘) 74 tapTimeout = setTimeout(function() { 75 76 // trigger universal ‘tap‘ with the option to cancelTouch() 77 // (cancelTouch cancels processing of single vs double taps for faster ‘tap‘ response) 78 var event = $.Event(‘tap‘) 79 event.cancelTouch = cancelAll 80 touch.el.trigger(event) 81 82 // trigger double tap immediately 83 if (touch.isDoubleTap) { 84 if (touch.el) touch.el.trigger(‘doubleTap‘) 85 touch = {} 86 } 87 88 // trigger single tap after 250ms of inactivity 89 else { 90 touchTimeout = setTimeout(function(){ 91 touchTimeout = null 92 if (touch.el) touch.el.trigger(‘singleTap‘) 93 touch = {} 94 }, 250) 95 } 96 }, 0) 97 } else { 98 touch = {} 99 }100 deltaX = deltaY = 0101 102 })103 // when the browser window loses focus,104 // for example when a modal dialog is shown,105 // cancel all ongoing events106 .on(‘touchcancel MSPointerCancel pointercancel‘, cancelAll)107 108 // scrolling the window indicates intention of the user109 // to scroll, not tap or swipe, so cancel all ongoing events110 $(window).on(‘scroll‘, cancelAll)111 })112 113 ;[‘swipe‘, ‘swipeLeft‘, ‘swipeRight‘, ‘swipeUp‘, ‘swipeDown‘,114 ‘doubleTap‘, ‘tap‘, ‘singleTap‘, ‘longTap‘].forEach(function(eventName){115 $.fn[eventName] = function(callback){ return this.on(eventName, callback) }116 })

能够见见zepto的tap通过兼听绑定在document上的touch事件来成功tap事件的效仿的,及tap事件是冒泡到document上接触的。
再点击达成时的tap事件(touchstart、touchend卡塔 尔(阿拉伯语:قطر‎需求冒泡到document上才会接触,而在冒泡到document在此以前,客商手的触发荧屏(touchstart卡塔 尔(阿拉伯语:قطر‎和离开显示屏(touchend卡塔 尔(阿拉伯语:قطر‎是会触发click事件的,因为click事件有延迟触发(那正是干吗移动端不用click而用tap的缘由。大致是300ms,为了落实safari的双击事件的设计),所以在试行完tap事件未来,弹出来的选择组件立时就隐蔽了,这时click事件还在延迟的300ms之中,当300ms到来的时候,click到的骨子里不是水到渠成而是隐蔽之后的江湖的元素,如若正下方的因素绑定的有click事件那时便会接触,若无绑定click事件的话就当没click,不过正下方的是input输入框(只怕select接纳框大概单选复选框),点击私下认可聚焦而弹出输入键盘,也就涌出了上边的点透现象。

复制代码 代码如下:

创建SVG

任凭您信不相信,其实大家并无需如Adobe Illustrator或以至Sketch那样花哨的应用程序来撰写那一个效应。SVG的符号能够动用大家也许早就熟知并用到办事中的几个XML标签来编排。

<svg version="1.1" xmlns="" xmlns:xlink="; <symbol viewbox="0 0 100 100"/> </svg>

1
2
3
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol viewbox="0 0 100 100"/>
</svg>

对此利用SVGSmartLogo的顾客,你会静心到的行使。symbol成分允许在单个symbol实例中格外相关的XML,并随着实例化它们,大概换句话说——有如盖章肖似在整整应用程序中应用它们。每种盖章的实例与其唯风华正茂的创建人相似:它所在的symbol。

symbol成分接收诸如viewBox和preserveAspectRatio之类的属性,这一个属性可以在援用use成分定义的矩形视口中提供切合缩放比例的力量。SaraSoueidan写了风流洒脱篇美丽的文章,并树立了贰个交互作用式工具,以帮扶您询问viewBox坐标类别。轻松地说正是,定义开端的x和y坐标值(0,0卡塔尔国,然后定义SVG画布的宽度和可观(100,100)。

以此XML拼图的下二个局地是加上大家构思动漫化为波纹的样子。那是放入circle成分的地点。

<svg version="1.1" xmlns="" xmlns:xlink="; <symbol viewbox="0 0 100 100"> <circle/> </symbol> </svg>

1
2
3
4
5
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol viewbox="0 0 100 100">
    <circle/>
  </symbol>
</svg>

circle要求部分越多的新闻,然后它技巧在SVG的viewBox内不易地展现。

<circle cx="1" cy="1" r="1"/>

1
<circle cx="1" cy="1" r="1"/>

品质cx和cy是相对于SVG viewBox的坐标地方;大家的事例中正是symbol。为了使点击的时候感到更自然,我们须要保险在接收到输入时触发点间接放在客商手指下方。

图片 4

上海体育地方中间那多少个例子,其属性创设了叁个半径为1px分寸为2px × 2px的圆。这将保证我们的圆不会像最后特别示例中所见到的那么裁剪。

<div style="height: 0; width: 0; position: absolute; visibility: hidden;" aria-hidden="true"> <svg version="1.1" xmlns="" xmlns:xlink="" focusable="false"><symbol id="ripply-scott" viewbox="0 0 100 100"><circle id="ripple-shape" cx="1" cy="1" r="1"/></symbol></svg></div>

1
2
<div style="height: 0; width: 0; position: absolute; visibility: hidden;" aria-hidden="true">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" focusable="false"><symbol id="ripply-scott" viewbox="0 0 100 100"><circle id="ripple-shape" cx="1" cy="1" r="1"/></symbol></svg></div>

对此最终的动手,大家将用包含内联CSS的div来包装它,以简单地蒙蔽sprite。那样能够幸免在渲染时占用页面中的空间。

在编著本文时,SVGSmart包罗symbol块援引它本身的渐变定义——正如您在演示准将看见的——通过ID找不到渐变和科学地渲染;使用visibility 属性代替display的缘由:none在Firefox和其它大部分浏览器上作为任何渐变都会倒闭。

有着IE直到IE11都急需使用focusable=”false” ;除了Edge,因为它还从未测量检验过。那是根源SVG 1.2正式的一个议事原案,描述了键盘主旨调整应该怎么着工作。IE落成了那一点,其余的浏览器则特别。为了与HTML生机勃勃致,并且为了越来越好的主宰,SVG 2将转而使用tabindex。

三、点透的化解方法:

  • 方案一:引入fastclick
    github链接:https://github.com/ftlabs/fastclick
    引进fastclick.js,因为fastclick源码不借助其余库,所以你能够在原生的js前一向抬高
window.addEventListener( "load", function() {
  FastClick.attach(document.body);
}, false );

恐怕有zepto也许jqm的js里面增加

$(function() {
  FastClick.attach(document.body);
});
  • 方案二:用touchend替代tap事件,并堵住touchend暗许行为preventDefault()
$("#cbFinish").on("touchend", function (event) { // 很多处理比如隐藏什么的
  event.preventDefault();
});
  • 方案三:延迟一定的年华(300ms )来处监护人件
$("#cbFinish").on("tap", function (event) {
  setTimeout(function(){
    //一些处理
  },320);
});

这种方式其实很好,能够和fadeInIn/fadeOut等卡通组成使用,能够做出过分效果。

(function ($) {
    $.fn.dragDivResize = function () {
        var deltaX, deltaY, _startX, _startY;
        var resizeW, resizeH;
        var size = 20;
        var minSize = 10;
        var scroll = getScrollOffsets();
        var _this = this;
        for (var i = 0; i < _this.length; i ) {
            var target = this[i];
            $(target).on("mouseover mousemove", overHandler);
        }
        function outHandler() {
            for (var i = 0; i < _this.length; i ) {
                target.style.outline = "none";
            }
            document.body.style.cursor = "default";
        }
        function overHandler(event) {
            target = event.target || event.srcElement;
            var startX = event.clientX scroll.x;
            var startY = event.clientY scroll.y;
            var w = $(target).width();
            var h = $(target).height();
            _startX = parseInt(startX);
            _startY = parseInt(startY);
            if ((0 < target.offsetLeft w - _startX && target.offsetLeft w - _startX < size) || (0 < target.offsetTop

编排标志

让大家写一个语义的button元素作为我们的对象,以显示此波纹。

JavaScript

<button>Click for Ripple</button>

1
<button>Click for Ripple</button>

好些个大家熟识的button的符号结构是干净俐落的,包含一些填写文本。

JavaScript

<button> Click for Ripple <svg> <use xlink:href="#ripply-scott"></use> </svg> </button>

1
2
3
4
5
6
<button>
  Click for Ripple
  <svg>
    <use xlink:href="#ripply-scott"></use>
  </svg>
</button>

为了利用先前开立的symbol成分,大家必要艺术来引用它,通过使用按键的SVG中的use成分来援引符号的ID属性值。

JavaScript

<button id="js-ripple-btn" class="button styl-material"> Click for Ripple <svg class="ripple-obj" id="js-ripple"> <use width="100" height="100" xlink:href="#ripply-scott" class="js-ripple"></use> </svg> </button>

1
2
3
4
5
6
<button id="js-ripple-btn" class="button styl-material">
  Click for Ripple
  <svg class="ripple-obj" id="js-ripple">
    <use width="100" height="100" xlink:href="#ripply-scott" class="js-ripple"></use>
  </svg>
</button>

最终标识具有了CSS和JavaScript hooks的叠合属性。以“js-”伊始的属性值表示仅设有于JavaScript中的值,因而删除它们将阻止人机联作,但不会潜濡默化样式。那有扶植区分CSS选用器和JavaScript hooks,以免止在后日急需删除或更新时相互作用混淆。

use成分必得有定义的增加率和惊人,不然将不会对查看者可知。你也得以在CSS中定义,若是你直接在要素自己上调节不要的话。

  • h - _startY && target.offsetTop h - _startY < size)) {
                    target.style.outline = "2px dashed #333";
                    if ((0 > target.offsetLeft w - _startX || target.offsetLeft w - _startX > size) && 0 < target.offsetTop h - _startY && target.offsetTop h - _startY < size) {
                        resizeW = false;
                        resizeH = true;
                        document.body.style.cursor = "s-resize";
                    }
                    if (0 < target.offsetLeft w - _startX && target.offsetLeft w - _startX < size && (0 > target.offsetTop h - _startY || target.offsetTop h - _startY > size)) {
                        resizeW = true;
                        resizeH = false;
                        document.body.style.cursor = "w-resize";
                    }
                    if (0 < target.offsetLeft w - _startX && target.offsetLeft w - _startX < size && 0 < target.offsetTop h - _startY && target.offsetTop h - _startY < size) {
                        resizeW = true;
                        resizeH = true;
                        document.body.style.cursor = "se-resize";
                    }
                    $(target).on('mousedown', downHandler);
                } else {
                    resizeW = false;
                    resizeH = false;
                    $(target).off('mousedown', downHandler);
                }
            }
            function downHandler(event) {
                target = event.target || event.srcElement;
                var startX = event.clientX scroll.x;
                var startY = event.clientY scroll.y;
                _startX = parseInt(startX);
                _startY = parseInt(startY);
                if (document.addEventListener) {
                    document.addEventListener("mousemove", moveHandler, true);
                    document.addEventListener("mouseup", upHandler, true);
                } else if (document.attachEvent) {
                    target.setCapture();
                    target.attachEvent("onlosecapeture", upHandler);
                    target.attachEvent("onmouseup", upHandler);
                    target.attachEvent("onmousemove", moveHandler);
                }
                if (event.stopPropagation) {
                    event.stopPropagation();
                } else {
                    event.cancelBubble = true;
                }
                if (event.preventDefault) {
                    event.preventDefault();
                } else {
                    event.returnValue = false;
                }
            }
            function moveHandler(e) {
                if (!e) e = window.event;
                var w, h;
                var startX = parseInt(e.clientX scroll.x);
                var startY = parseInt(e.clientY scroll.y);
                target = target || e.target || e.srcElement;
                if (target == document.body) {
                    return;
                }
                if (resizeW) {
                    deltaX = startX - _startX;
                    w = $(target).width() deltaX < minSize ? minSize : $(target).width() deltaX;
                    target.style.width = w "px";
                    _startX = startX;
                }
                if (resizeH) {
                    deltaY = startY - _startY;
                    h = $(target).height() deltaY < minSize ? minSize : $(target).height() deltaY;
                    target.style.height = h "px";
                    _startY = startY;
                }
                if (e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    e.cancelBubble = true;
                }
            }
            function upHandler(e) {
                if (!e) {
                    e = window.event;
                }
                resizeW = false;
                resizeH = false;
                target = e.target || e.srcElement;
                $(target).on("mouseout", outHandler);
                if (document.removeEventListener) {
                    document.removeEventListener("mousemove", moveHandler, true);
                    document.removeEventListener("mouseup", upHandler, true);
                } else if (document.detachEvent) {
                    target.detachEvent("onlosecapeture", upHandler);
                    target.detachEvent("onmouseup", upHandler);
                    target.detachEvent("onmousemove", moveHandler);
                    target.releaseCapture();
                }
                if (e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    e.cancelBubble = true;
                }
            }
            function getScrollOffsets(w) {
                w = w || window;
                if (w.pageXOffset != null) {
                    return { x: w.pageXOffset, y: w.pageYOffset };
                }
                var d = w.document;
                if (document.compatMode == "CSS1Compat") {
                    return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
                }
                return { x: d.body.scrollLeft, y: d.body.scrollTop };
            }
        }
    }(jQuery));
    jQuery("div").dragDivResize();

联结点样式

当编辑CSS的时候,要实现预期的效果你所要做的并十分少。

.ripple-obj { height: 100%; pointer-events: none; position: absolute; top: 0; left: 0; width: 100%; z-index: 0; fill: #0c7cd5; } .ripple-obj use { opacity: 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.ripple-obj {
  height: 100%;
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 0;
  fill: #0c7cd5;
}
 
.ripple-obj use {
  opacity: 0;
}

这就是在剔除用于日常样式的扬言时,还预先流出的开始和结果。pointer-events的选择息灭了SVG纹波成为鼠标事件的对象,因为大家只要求父对象反应:button成分。

纹波最早必需是不可以看到的,由此要将不反射率值设置为零。我们还将波纹对象定位在button的左上方。我们能够使波纹形状居中,可是出于那一件事件是依附客商人机联作而发生的,所以挂念地点并未有趣。

 记录一下前几日的劳动成果,也许会有大多不成熟的地点,接待我们来指正,谢谢!

加之它活力

付与生机就是这几个相互作用全数的含义。

<script src="; <script src="js/ripple.js"/>

1
2
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"/>
<script src="js/ripple.js"/>

为了动漫化波纹,大家将选取GreenSock的Tween马克斯库,因为它是使用JavaScript对指标进行动漫管理的最好库之大器晚成;极其是事关与动漫SVG跨浏览器有关的主题材料。

var ripplyScott = (function() {} return { init: function() {} }; })();

1
2
3
4
5
var ripplyScott = (function() {}
  return {
    init: function() {}
  };
})();

我们将在利用的情势是所谓的模块情势,因为它推向掩盖和维护全局命名空间。

var ripplyScott = (function() {} var circle = document.getElementById('js-ripple'), ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing) {…} })();

1
2
3
4
5
6
var ripplyScott = (function() {}
  var circle = document.getElementById('js-ripple'),
      ripple = document.querySelectorAll('.js-ripple');
 
  function rippleAnimation(event, timing) {…}
})();

为了消除难点,大家将抓取一些成分并将它们存款和储蓄在变量中;特别是use成分,它含有button内的svg。整个动漫逻辑将驻留在rippleAnimation函数中。该函数将选用动漫种类和事件音讯的时序参数。

var ripplyScott = (function() {} var circle = document.getElementById('js-ripple'), ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing) { var tl = new TimelineMax(); x = event.offsetX, y = event.offsetY, w = event.target.offsetWidth, h = event.target.offsetHeight, offsetX = Math.abs( (w / 2) - x ), offsetY = Math.abs( (h / 2) - y ), deltaX = (w / 2) offsetX, deltaY = (h / 2) offsetY, scale_ratio = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2)); } })();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var ripplyScott = (function() {}
  var circle = document.getElementById('js-ripple'),
      ripple = document.querySelectorAll('.js-ripple');
 
  function rippleAnimation(event, timing) {
    var tl           = new TimelineMax();
        x            = event.offsetX,
        y            = event.offsetY,
        w            = event.target.offsetWidth,
        h            = event.target.offsetHeight,
        offsetX      = Math.abs( (w / 2) - x ),
        offsetY      = Math.abs( (h / 2) - y ),
        deltaX       = (w / 2) offsetX,
        deltaY       = (h / 2) offsetY,
        scale_ratio  = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2));
  }
})();

大家定义了大气的变量,所以让咱们三个三个地钻探那么些变量所担任的源委。

var tl = new TimelineMax();

1
var tl = new TimelineMax();

此变量创建动漫种类的日子轴实例以致独具时间轴在Tween马克斯中实例化的主意。

var x = event.offsetX; var y = event.offsetY;

1
2
var x = event.offsetX;
var y = event.offsetY;

事件偏移量是叁个只读属性,它将鼠标指针的偏移值报告给目的节点的填充边。在这里个例子中,正是大家的button。x的平地风波偏移量从左到右总括,y的事件偏移量从上到下总结;都从零最初。

var w = event.target.offsetWidth; var h = event.target.offsetHeight;

1
2
var w = event.target.offsetWidth;
var h = event.target.offsetHeight;

这几个变量将回来按键的肥瘦和惊人。最后计算结果将囊括成分边框和填充的大大小小。我们必要以此值工夫理解大家的因素有多大,那样大家才得以将波纹传播到最远的边缘。

var offsetX = Math.abs( (w / 2) - x ); var offsetY = Math.abs( (h / 2) - y );

1
2
var offsetX = Math.abs( (w / 2) - x );
var offsetY = Math.abs( (h / 2) - y );

偏移值是点击间隔成分基本的摇晃距离。为了填满目的的整整区域,波纹必得丰裕大,能够从接触点覆盖到最远的犄角。使用早先x和y坐标将不会再一次将其从零初阶,对于x,是从左到右的值,对于y,是从上到下的值。这种格局让大家利用这几个值的时候无论目的的主干点点击在哪生龙活虎端,都会检查评定间距。

图片 5

瞩目圆将什么覆盖全部因素的经过,无论输入的起首点什么地方产生。依照初叶点的彼此来覆盖任何外界,大家要求做一些数学。

以下是我们什么样使用464 x 82用作宽和高,391和45当作x和y坐标来计算偏移量的经过:

var offsetX = (464 / 2) - 391 = -159 var offsetY = (82 / 2) - 45 = -4

1
2
var offsetX = (464 / 2) - 391 = -159
var offsetY = (82 / 2) - 45 = -4

透过将小幅和可观除以2来找到着力,然后减去由x和y坐标检查实验到的报告值。

Math.abs()方法重回数字的相对值。使用方面包车型客车算术得到值159和4。

var deltaX = 232 159 = 391; var deltaY = 41 4 = 45;

1
2
var deltaX  = 232 159 = 391;
var deltaY  = 41 4 = 45;

三角形总括点击的全部间隔,实际不是间隔大旨的离开。接受三角的缘故是x和y总是从零开端从左到右,所以当相反方向(从右到左卡塔 尔(阿拉伯语:قطر‎点击的时候,咱们必要艺术来检查实验点击。

图片 6

学过底蕴数学课程的小友人应该都知晓勾股定理。公式为:高(a卡塔尔国的平方加底(b卡塔尔国的平方,获得斜边(c卡塔 尔(阿拉伯语:قطر‎的平方。

a2 b2 = c2

var scale_ratio = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2));

1
var scale_ratio = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2));

利用那些公式让大家来看一下测算:

var scale_ratio = Math.sqrt(Math.pow(391, 2) Math.pow(45, 2));

1
var scale_ratio = Math.sqrt(Math.pow(391, 2) Math.pow(45, 2));

Math.pow()方法再次来到第八个参数的幂;在此个事例中加进了大器晚成倍。391的2次方为152881。前边45的2次方等于2025。将那五个值相加并取结果的平方根将留下393.58099547615353,那便是我们须要的波纹比例。

var ripplyScott = (function() { var circle = document.getElementById('js-ripple'), ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing) { var tl = new TimelineMax(); x = event.offsetX, y = event.offsetY, w = event.target.offsetWidth, h = event.target.offsetHeight, offsetX = Math.abs( (w / 2) - x ), offsetY = Math.abs( (h / 2) - y ), deltaX = (w / 2) offsetX, deltaY = (h / 2) offsetY, scale_ratio = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2)); tl.fromTo(ripple, timing, { x: x, y: y, transformOrigin: '50% 50%', scale: 0, opacity: 1, ease: Linear.easeIn },{ scale: scale_ratio, opacity: 0 }); return tl; } })();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var ripplyScott = (function() {
  var circle = document.getElementById('js-ripple'),
      ripple = document.querySelectorAll('.js-ripple');
 
  function rippleAnimation(event, timing) {
    var tl           = new TimelineMax();
        x            = event.offsetX,
        y            = event.offsetY,
        w            = event.target.offsetWidth,
        h            = event.target.offsetHeight,
        offsetX      = Math.abs( (w / 2) - x ),
        offsetY      = Math.abs( (h / 2) - y ),
        deltaX       = (w / 2) offsetX,
        deltaY       = (h / 2) offsetY,
        scale_ratio  = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2));
 
    tl.fromTo(ripple, timing, {
      x: x,
      y: y,
      transformOrigin: '50% 50%',
      scale: 0,
      opacity: 1,
      ease: Linear.easeIn
    },{
      scale: scale_ratio,
      opacity: 0
    });
 
    return tl;
  }
})();

运用Tween马克斯中的fromTo方法,我们得以传递目的——波纹形状——并安装包罗全体运动系列方向的对象文字。鉴于我们想要从基本向外形成动漫,SVG必要将更动原点设置为中等地方。思考到我们想要之后要进行动漫管理,须求安装opacity 为1,由此缩放也急需调节到细微的职分。不亮堂你回看起了未有,从前咱们在CSS中装置了opacity为0的use成分以致大家从值1开始并回到到零的由来。最后有的是回届时间轴实例。

var ripplyScott = (function() { var circle = document.getElementById('js-ripple'), ripple = document.querySelectorAll('.js-ripple'); function rippleAnimation(event, timing) { var tl = new TimelineMax(); x = event.offsetX, y = event.offsetY, w = event.target.offsetWidth, h = event.target.offsetHeight, offsetX = Math.abs( (w / 2) - x ), offsetY = Math.abs( (h / 2) - y ), deltaX = (w / 2) offsetX, deltaY = (h / 2) offsetY, scale_ratio = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2)); tl.fromTo(ripple, timing, { x: x, y: y, transformOrigin: '50% 50%', scale: 0, opacity: 1, ease: Linear.easeIn },{ scale: scale_ratio, opacity: 0 }); return tl; } return { init: function(target, timing) { var button = document.getElementById(target); button.addEventListener('click', function(event) { rippleAnimation.call(this, event, timing); }); } }; })();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var ripplyScott = (function() {
  var circle = document.getElementById('js-ripple'),
      ripple = document.querySelectorAll('.js-ripple');
 
  function rippleAnimation(event, timing) {
    var tl           = new TimelineMax();
        x            = event.offsetX,
        y            = event.offsetY,
        w            = event.target.offsetWidth,
        h            = event.target.offsetHeight,
        offsetX      = Math.abs( (w / 2) - x ),
        offsetY      = Math.abs( (h / 2) - y ),
        deltaX       = (w / 2) offsetX,
        deltaY       = (h / 2) offsetY,
        scale_ratio  = Math.sqrt(Math.pow(deltaX, 2) Math.pow(deltaY, 2));
 
    tl.fromTo(ripple, timing, {
      x: x,
      y: y,
      transformOrigin: '50% 50%',
      scale: 0,
      opacity: 1,
      ease: Linear.easeIn
    },{
      scale: scale_ratio,
      opacity: 0
    });
 
    return tl;
  }
 
  return {
    init: function(target, timing) {
      var button = document.getElementById(target);
 
      button.addEventListener('click', function(event) {
        rippleAnimation.call(this, event, timing);
      });
    }
  };
})();

重回的目的字面值将调节我们的波纹,方法是因此将事件侦听器附加到所需的对象,调用rippleAnimation,以至最后传递我们就要下一步琢磨的参数。

ripplyScott.init('js-ripple-btn', 0.75);

1
ripplyScott.init('js-ripple-btn', 0.75);

末段通过动用模块并传递init函数来对按键举办调用,init函数字传送递按键和系列的时序。看,正是那样!

愿意您爱怜那篇文章,并从中受到启示!接待使用不一致的样子来检查演示,并查看源代码。不要紧尝试新的形态、新的图层形状,最要紧的是表述您的想象力,放飞你的新意。

专一:个中一些技艺是试错性的,只好在现世浏览器中运作。

浏览器帮衬:Chrome Firefox Internet Explorer Safari Opera

在Github上查看这几个体系

译文链接:
德文原稿:Creating Material Design Ripple Effects with SVG
翻译小编:码农网 – 小峰
[ 转发必需在正文中注脚并保留原来的小说链接、译文链接和翻译等新闻。]

1 赞 1 收藏 评论

图片 7

以上便是本文的全体内容了,希望大家能够赏识。

你恐怕感兴趣的篇章:

  • jQuery拖拽div达成思路
  • jQuery使用drag效果落到实处自由拖拽div
  • JQuery之拖拽插件落到实处代码
  • jQuery插件完毕公文上传功效(帮衬拖拽卡塔尔
  • jQuery完结的轻便拖拽效用示例
  • 依赖jquery的一个拖拽到钦定区域内的成效
  • jquery拖拽排序简单完成格局(效果巩固版)
  • 听他们说jquery完成的鼠标拖拽成分复制并写入效果
  • jQuery完毕的简短拖拽功能示例【测验可用】

本文由pc28.am发布于前端技术,转载请注明出处:jquery实现拖拽调整Div大小,html5版canvas自由拼图实

上一篇:遇见未知的,web开采连忙入门 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • 遇见未知的,web开采连忙入门
    遇见未知的,web开采连忙入门
    CSS 框架 Bulma 教程 2017/10/26 · CSS ·Bulma 原文出处:阮一峰    网页样式需要大量时间开发,最省事的方法就是使用 CSS 框架。 Bootstrap 是最著名的 CSS框架,
  • 追踪客户,读书笔记
    追踪客户,读书笔记
    使用 CSS 追踪用户 2018/01/20 · CSS · 1评论 ·追踪 原文出处:jbtronics   译文出处:枫上雾棋    除了使用 JS 追踪用户,现在有人提出了还可以使用 CSS 进行
  • pusle雷达动漫完结,推荐8款CSS3兑现的动态特效
    pusle雷达动漫完结,推荐8款CSS3兑现的动态特效
    CSS技巧:逐帧动漫抖动实施方案 2017/08/16 · CSS ·动画 原来的书文出处:坑坑洼洼实验室    我所在的前端共青团和少先队首要从事活动端的H5页面开荒,而
  • 跟随我在oracle学习php,HTML中form表单的用法
    跟随我在oracle学习php,HTML中form表单的用法
    表单元素之搭车系 2016/01/28 · HTML5 ·表单 原文出处:司徒正美(@司徒正美)    对于表单元素, 除了reset元素,只要有name与value都能提交 因为在我们印象
  • Codecademy为编程初学者新增HTML和CSS两门课程,可以
    Codecademy为编程初学者新增HTML和CSS两门课程,可以
    Codecademy为编制程序初读书人新添HTML和CSS两门学科 2012/04/03 · CSS · 来源:伯乐在线     ·CSS 葡萄牙语原来的文章:Mashable  编译:伯乐在线– 黄利民 乐