以下是 jquery svg图像生成器插件js特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<html>
<head>
<meta charset="utf-8">
<title>jquery svg图像生成器插件</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="container">
<div class="options">
<h1>Triangloid</h1>
<h2>选项</h2>
<label for="cell-size-input">尺寸:</label>
<input value="30" id="cell-size-input" />
<div class="bottom-align">
<div class="btn-container">
<div class="btn trianglify-btn">生成图像</div>
<div class="btn download-btn">下载svg图像格式</div>
</div>
</div>
</div><div class="main">
<label for="imageInput">
<div id="drop-zone" class="hover">
<div class="drop-label">拖动图片或点击这里上传</div>
</div>
</label>
</div>
</div>
<input type="file" id="imageInput" />
<script src="d3.min.js"></script>
<script src="jquery.min.js"></script>
<script src="triangloid.js"></script>
<script>
var cellsize =30;
var image, imageHeight, imageWidth, backgroundSize, svg;
function getImagePixelData(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0, 0, img.width, img.height);
var mappedData = [];
for (var i = 0; i < imageData.data.length; i += 4) {
mappedData.push([imageData.data[i], imageData.data[i + 1], imageData.data[i + 2]]);
}
return mappedData;
}
var dropZone = document.getElementById('drop-zone');
dropZone.ondragover = function() {
this.className = 'hover';
return false;
};
dropZone.ondragleave = function() {
dropZone.className = "";
}
dropZone.ondragend = function() {
dropZone.className = "";
return false;
};
dropZone.ondrop = processInput;
document.getElementById("imageInput").onchange = processInput;
$("#cell-size-input").keyup(function() {
cellsize = parseInt($(this).val());
});
$(".trianglify-btn").click(function() {
draw(image);
$(".download-btn").addClass("visible");
});
$(".download-btn").click(function() {
document.location.href = svg.replace("image/svg+xml", "image/octet-stream");
});
function processInput(e) {
dropZone.className = "";
e.preventDefault();
if (e.target.files) {
var file = e.target.files[0];
} else {
var file = e.dataTransfer.files[0];
}
var reader = new FileReader();
reader.onload = function(event) {
image = new Image();
image.onload = function() {
var dropZoneWidth = $(dropZone).width();
var dropZoneHeight = $(dropZone).height();
var dropZoneRatio = dropZoneWidth / dropZoneHeight;
var imageRatio = image.width / image.height;
backgroundSize = "";
if (image.width > dropZoneWidth) { //Could be expressed in smaller chunks...
if (image.height > dropZoneHeight) {
if (imageRatio > dropZoneRatio) {
backgroundSize += dropZoneWidth + "px";
backgroundSize += " ";
backgroundSize += dropZoneWidth / imageRatio + "px";
} else {
backgroundSize += dropZoneHeight * imageRatio + "px";
backgroundSize += " ";
backgroundSize += dropZoneHeight + "px";
}
} else {
backgroundSize += dropZoneWidth + "px";
backgroundSize += " ";
backgroundSize += dropZoneWidth / imageRatio + "px";
}
} else if (image.height > dropZoneHeight) {
backgroundSize += dropZoneHeight * imageRatio + "px";
backgroundSize += " ";
backgroundSize += dropZoneHeight + "px";
} else {
backgroundSize = image.width + "px " + image.height + "px";
}
dropZone.style.background = 'url(' + imageData + ') no-repeat center';
dropZone.style.backgroundSize = backgroundSize;
console.log(dropZone.style.backgroundSize);
$(".trianglify-btn").addClass("visible");
$(".download-btn").removeClass("visible");
}
image.src = imageData = event.target.result;
};
reader.readAsDataURL(file);
return false;
}
function draw(img) {
var imageData = getImagePixelData(img);
var triangloid = new Triangloid({
cellsize: cellsize
});
var trianglifiedImage = triangloid.trianglifyImage(imageData, img.width, img.height);
svg = trianglifiedImage.getSVG();
dropZone.style.background = 'url(' + svg + ') no-repeat center';
dropZone.style.backgroundSize = backgroundSize;
}
</script>
</body>
</html>
JS代码(triangloid.js):
var Triangloid;
(function(){
//Private:function defaults(opt,def){
return (typeof opt !== 'undefined') ? opt:def;
}
//Public:Triangloid = function(options){
if (typeof options === 'undefined'){
options ={
}
;
}
this.options ={
cellsize:defaults(options.cellsize,150),bleed:defaults(options.cellsize,150),cellpadding:defaults(options.cellpadding,0.1 * options.cellsize || 15)}
;
}
Triangloid.prototype.trianglifyImage = function(imageData,imageWidth,imageHeight){
return new Triangloid.TrianglifiedImage(this.options,imageData,imageWidth,imageHeight);
}
Triangloid.TrianglifiedImage = function(options,data,width,height){
this.rawData = data;
this.options = options;
this.width = width;
this.height = height;
this.pattern = new Triangloid.TrianglifiedImage.Pattern(this.options,width,height);
}
Triangloid.TrianglifiedImage.prototype.getSVG = function(){
//Serializes,wraps and returns SVG as base64 data URI code this.svg = this.generateSVG();
var s = new XMLSerializer();
this.svgString = s.serializeToString(this.svg);
this.base64 = btoa(this.svgString);
this.dataUri = 'data:image/svg+xml;
base64,' + this.base64;
//Wraps base64 code with appropriate metadata this.dataUrl = 'url(' + this.dataUri + ')';
return this.dataUri;
}
Triangloid.TrianglifiedImage.prototype.generateSVG = function(){
//Generates and populates an SVG with triangles with appropriate color and returns SVG as a node string,meant to be executed internally,by TrianglifyImage.prototype.getSVG var options = this.options;
var data = this.rawData;
var width = this.width;
var height = this.height;
var elem = document.createElementNS("http://www.w3.org/2000/svg","svg");
var svg = d3.select(elem);
svg.attr("width",this.width);
svg.attr("height",this.height);
svg.attr('xmlns','http://www.w3.org/2000/svg');
var group = svg.append("g");
this.pattern.polygons.forEach(function(d){
var x = Math.round((d[0][0] + d[1][0] + d[2][0]) / 3);
//Finds central(mean) point of the triangle corners var y = Math.round((d[0][1] + d[1][1] + d[2][1]) / 3);
if (x < 0){
//If the point is outside the image boundary,set it just on the edge to get a color x = 0;
}
else if (x >= width){
x = width - 1;
}
if (y < 0){
y = 0;
}
else if (y >= height){
y = height - 1;
}
var pixelIndex = x + (y * width);
var c = "rgb(" + data[pixelIndex].join(",") + ")";
//Sets color of the triangle to the color of the median point var g = group.append("path").attr("d","M" + d.join("L") + "Z").attr({
fill:c,stroke:c}
);
}
);
console.log(svg.node());
return svg.node();
}
Triangloid.TrianglifiedImage.Pattern = function(options,width,height){
this.options = options;
this.width = width;
this.height = height;
this.polygons = this.generatePolygons();
}
Triangloid.TrianglifiedImage.Pattern.prototype.generatePolygons = function(){
var options = this.options;
var cellsX = Math.ceil((this.width + options.bleed * 2) / options.cellsize);
var cellsY = Math.ceil((this.height + options.bleed * 2) / options.cellsize);
var vertices = d3.range(cellsX * cellsY).map(function(d){
var col = d % cellsX;
var row = Math.floor(d / cellsX);
var x = Math.round(-options.bleed + col * options.cellsize + Math.random() * (options.cellsize - options.cellpadding * 2) + options.cellpadding);
var y = Math.round(-options.bleed + row * options.cellsize + Math.random() * (options.cellsize - options.cellpadding * 2) + options.cellpadding);
return [x,y];
}
);
return d3.geom.voronoi().triangles(vertices);
}
}
)();
CSS代码(style.css):
body{margin:0px;padding:0px;font-family:"Raleway",arial;text-transform:uppercase;color:#fff;}
h1,h2{font-weight:300;}
a{text-decoration:none;}
.container{width:100%;min-height:550px;height:100%;background-color:#ecf0f1;}
#drop-zone{height:500px;background-color:#ecf0f1;cursor:pointer;}
.drop-label{text-align:center;margin:150px auto;width:250px;display:block;transition:0.5s opacity;-webkit-transition:0.5s opacity;-ms-transition:0.5s opacity;background-color:#3498db;padding:10px;opacity:0;}
.hover .drop-label,#drop-zone:hover .drop-label{opacity:1;}
.btn-container{width:100%;text-align:center;}
.btn{margin-bottom:5px;text-align:center;display:inline-block;transition:0.5s all;-webkit-transition:0.5s all;-ms-transition:0.5s all;background-color:#3498db;padding:10px;display:none;cursor:default;color:#fff;}
.btn:hover{background-color:#2980b9;}
.btn.visible{cursor:pointer;display:inline-block;}
.options{position:relative;vertical-align:top;width:25%;display:inline-block;background-color:#fff;color:#333;height:100%;}
.options input{padding:5px;font-family:"Raleway",arial;width:40px;margin-left:10px;font-size:15px;outline:none;transition:0.25s all;-webkit-transition:0.25s all;-ms-transition:0.25s all;border:1px solid #999;}
.options input:focus{border-color:#3498db;}
.options label,.options h2,.options h1,.options a{margin-left:10px;}
input[type="file"]{display:none;}
.main{display:inline-block;width:75%;}
.main h2{vertical-align:top;margin-left:10px;margin-bottom:0px;margin-top:10px;display:inline-block;}
.bottom-align{position:absolute;bottom:100px;width:100%;}
.social{display:inline-block;float:right;}
.social img{height:50px;}