html5版canvas自由拼图实例,波纹效果按钮

SVG 创制 Material Design 波纹效果按钮

2017/10/16 · HTML5 ·
SVG

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

小峰   

趁着谷歌 Material
Design的出现,一种意志跨平台和配备创立统一体验的视觉语言因而横空出世。谷歌(Google)通过“Material
Guidelines”动画部分讲述的事例是那样地拟真,以致于许五人将那些互动视为谷歌品牌的一部分。

在本教程中,大家将向我们来得什么在谷歌 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._html5版canvas自由拼图实例,波纹效果按钮。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.

谷歌分外精晓地发表了输入反馈应从原点出发,向外扩散。例如,若是用户直接在基本点击按钮,则纹波将从伊始接触点向外扩大。那正是大家怎么着建议触摸爆发的地址和岁月的章程,以便向用户确认接收到的输入。

① 、点透是何等

您或者碰到过在列表页面上创办三个弹出层,弹出层有个闭馆的按钮,你点了这一个按钮关闭弹出层后后,这几个按钮正下方的剧情也会实行点击事件(或打开链接)。这几个被定义为那是三个“点透”现象。
在头里的花色中相见了如下图的难点:在点击弹出来的挑选组件的右上角完结后会让完毕后边的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拼图的下1个某个是拉长大家打算动画化为波纹的造型。那是放入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

上海体育场合中间这么些例子,其属性创立了3个半径为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”
;除了艾德ge,因为它还未曾测试过。那是发源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"/>

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

大家定义了大气的变量,所以让大家二个1个地研讨那几个变量所承受的始末。

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;

事件偏移量是1个只读属性,它将鼠标指针的偏移值报告给目的节点的填充边。在这么些事例中,即是我们的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的3个拖拽到钦点区域内的机能
  • jquery拖拽排序简单实现格局(效果增强版)
  • 依据jquery完成的鼠标拖拽成分复制并写入效果
  • jQuery完成的大约拖拽功效示例【测试可用】

相关文章

发表评论

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

网站地图xml地图