波纹效果按钮,jquery完毕拖拽调整Div大小

SVG 创建 Material Design 波纹效果按钮

2017/10/16 · HTML5 ·
SVG

原稿出处: Dennis
Gaebel   译文出处:码农网

小峰   

乘机谷歌 Material
Design的产出,一种意志跨平台和配备创立统一体验的视觉语言由此横空出世。谷歌通过“Material
Guidelines”动画部分讲述的例证是那般地拟真,以致于许几人将这么些互动视为谷歌(Google)品牌的一有的。

在本教程中,我们将向大家体现如何在谷歌(Google) Material Design规范的Radial
Action下打造波纹效果,并组成SVG和格林Sock功能。

澳门葡京 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) {
    波纹效果按钮,jquery完毕拖拽调整Div大小。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.

谷歌十一分明白地表明了输入反馈应从原点出发,向外扩散。例如,假设用户直接在基本点击按钮,则纹波将从初始接触点向外扩展。那就是大家如何提出触摸发生的地址和岁月的点子,以便向用户确认接收到的输入。

① 、点透是什么

您可能蒙受过在列表页面上创造二个弹出层,弹出层有个闭馆的按钮,你点了那个按钮关闭弹出层后后,这几个按钮正下方的情节也会履行点击事件(或打开链接)。这些被定义为那是壹个“点透”现象。
在头里的品类中相遇了如下图的题材:在点击弹出来的采纳组件的右上角完结后会让已毕后边的input输入框聚焦,弹出输入键盘,约等于点透了

澳门葡京 3

技能分享

可以兑现对div举行拖拽来调整大小的听从。

SVG中的径向动作

有广大开发人员创作纹波技术,紧要采纳CSS技术,如@keyframes,transitions,transforms伪技巧,border-radius以及甚至额外的记号,如span或div。不行使CSS,让大家来看望哪些通过格林Sock的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>

对此使用SVG天使图标的用户,你会小心到的采用。symbol成分允许在单个symbol实例中匹配相关的XML,并进而实例化它们,只怕换句话说——就像是盖章一样在方方面面应用程序中利用它们。逐个盖章的实例与其唯一的创小编相同:它所在的symbol。

symbol元素接受诸如viewBox和preserveAspectRatio之类的性质,那么些属性可以在引用use成分定义的矩形视口中提供符合缩放比例的力量。SaraSoueidan写了一篇精粹的篇章,并确立了一个交互式工具,以扶助你打探view博克斯坐标序列。不难地说就是,定义伊始的x和y坐标值(0,0),然后定义SVG画布的增幅和惊人(100,100)。

这几个XML拼图的下2个局地是丰富我们打算动画化为波纹的模样。那是放入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

上图中间那么些例子,其属性创设了2个半径为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。那样可以预防在渲染时占用页面中的空间。

在文章本文时,SVG天使包涵symbol块引用它本身的渐变定义——正如您在示范准将看到的——通过ID找不到渐变和不利地渲染;使用visibility
属性代替display的原因:none在Firefox和其他大多数浏览器上作为一切渐变都会失利。

富有IE直到IE11都急需运用focusable=”false”
;除了Edge,因为它还没有测试过。那是根源SVG
1.2正式的1个提案,描述了键盘核心控制应该如何是好事。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

编排标记

让大家写2个语义的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"/>

为了动画化波纹,大家将应用格林Sock的TweenMax库,因为它是利用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();

此变量成立动画系列的时日轴实例以及有着时间轴在TweenMax中实例化的主意。

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的二遍方为152881。前边45的三回方等于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完结的简约拖拽功用示例【测试可用】

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website