Skip to content

Instantly share code, notes, and snippets.

@edom18
Created January 30, 2013 01:29
Show Gist options
  • Save edom18/4669810 to your computer and use it in GitHub Desktop.
Save edom18/4669810 to your computer and use it in GitHub Desktop.
forked: 画像を三角分割でユラユラ
* {
padding: 0;
margin: 0;
}
canvas {
}
#wrapper {
width: 500px;
text-align: center;
}
p#switch {
text-align: center;
}
p#switch a {
font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
font-size: 16px;
font-weight: bold;
display: inline-block;
padding: 8px 10px;
line-height: 1;
border-radius: 4px;
background: -webkit-gradient(linear, left top, left bottom, color-stop(1.00, #ff7400), color-stop(0.00, #ffa443));
background: -webkit-linear-gradient(top, #ffa443 0%, #ff7400 100%);
background: -moz-linear-gradient(top, #ffa443 0%, #ff7400 100%);
background: -o-linear-gradient(top, #ffa443 0%, #ff7400 100%);
background: -ms-linear-gradient(top, #ffa443 0%, #ff7400 100%);
background: linear-gradient(top, #ffa443 0%, #ff7400 100%);
text-decoration: none;
color: white;
text-shadow: 0 -1px 0px rgba(0,0,0,.4);
-webkit-font-smoothing: antialiased;
}
<div id="wrapper">
<canvas id="canvas" width="300" height="300"></canvas>
<p id="switch"><a href="javascript:void(0);">メッシュ表示</a></p>
</div>
// forked from hidetaro7's "画像を三角分割でユラユラ" http://jsdo.it/hidetaro7/triangle01
// 三角形分割による、独学テクスチャMapping
// by Hidetaro7
// これの元となった、シンプル三角形分割の考え方はブログに上げてます。
// http://akibahideki.com/blog/html5-canvas-1/canvas.html
// 独学のため、もっと効率のよい方法があればぜひお教えください。(数学はとても苦手です,JSも苦手ですが…)
var ctx, canvas, img;
var w = 0, h = 0, seg = 10, meshToggle = false;
var cn = new Coordinates();
jQuery(function ($){
canvas = $("canvas#canvas");
ctx = $(canvas).get(0).getContext("2d");
img = new Image();
img.src = "http://jsdo.it/img/common/side/bnr_html5_01.png";
img.onload = function (){
w = img.width / seg;
h = img.height / seg;
cn.setOrigin(40, 40);
cn.init();
wave();
}
$("p#switch a").click(function (){
if(meshToggle) {
meshToggle = false;
$(this).text("メッシュ表示");
}else{
meshToggle = true;
$(this).text("メッシュ非表示");
}
});
}); //ready
function wave () {
var mesh = cn.getMesh(),
deg = 0,
step = Math.floor(360/seg);
ctx.strokeStyle = "green";
var enterframe = setInterval(function () {
var l=cn.getMesh().length-1;
while(l>0) {
var i = 0;
l-=seg;
deg++;
while(i<seg) {
i++;
mesh[l+i].x = mesh[l+i].pivotX + Math.floor(Math.cos((deg*step)* Math.PI / 180)*10);
}
}
if (deg%180 == 0) deg = 0;
cn.drawMesh();
}, 1000/10);
}
function Mesh (_x, _y, _corner) { //個別管理用
this.x = _x;
this.y = _y;
this.corner = _corner;
this.pivotX = _x;
this.pivotY = _y;
}
function Coordinates() { // 全体管理用
var pivot = {x: 0, y: 0};
var _this = this;
var getVertices = function (){
var results = [];
for (var i=0, l=_this.meshes.length; i<l; i++) {
results.push({"x":_this.meshes[i].x, "y":_this.meshes[i].y})
}
return results;
}
this.getMesh = function (){
return _this.meshes;
}
this.init = function () {
var len = Math.pow( seg, 2 ) + seg*2 + 1;
var _x = _y = 0;
for (var i=0; i<len; i++) {
var mx = Math.floor(_x*w), my = Math.floor(_y*h), corner = false;
if(my >= img.height) {corner = true;}
if(mx >= img.width) { _x = 0; _y++; corner = true; } else { _x++; }
cn.addPoint(mx, my, corner);
}
cn.drawMesh();
}
this.geometry = [];
this.addPoint = function (_x, _y, corner) {
ctx.beginPath();
ctx.fillRect((_x+pivot.x)-this.pointSize*.5, (_y+pivot.y)-this.pointSize*.5, this.pointSize, this.pointSize);
ctx.closePath();
var p = new Mesh((_x+pivot.x), (_y+pivot.y) , corner);
this.meshes.push(p);
}
this.setOrigin = function (_x, _y) {
pivot.x = _x;
pivot.y = _y;
}
this.getOrigin = function () {
return {"x":pivot.x, "y":pivot.y}
}
this.drawMesh = function (){
ctx.clearRect(0,0, canvas.width(), canvas.height());
var l = this.meshes.length;
v = this.meshes;
for( var i=0; i<l; i++ ) {
if(!v[i].corner) {
//segment1
ctx.save();
ctx.beginPath();
ctx.moveTo(v[i].x, v[i].y);
ctx.lineTo(v[i+1].x, v[i+1].y);
ctx.lineTo(v[i+seg+2].x, v[i+seg+1].y); //追加
ctx.lineTo(v[i+seg+1].x, v[i+seg+1].y);
ctx.closePath();
ctx.clip();
var t1 = (v[i+1].x - v[i].x)/w;
var t2 = (v[i+1].y - v[i].y)/w;
var t3 = (v[i+seg+1].x - v[i].x)/h;
var t4 = (v[i+seg+1].y - v[i].y)/h;
ctx.setTransform(t1,t2,t3,t4, v[i].x, v[i].y);
ctx.drawImage(img, v[i].pivotX-_this.getOrigin().x, v[i].pivotY-_this.getOrigin().y ,w, h, 0, 0 ,w, h);
ctx.restore();
if (meshToggle) ctx.stroke();
//segment2
ctx.save();
ctx.beginPath();
ctx.lineTo(v[i+1].x, v[i+1].y);
ctx.lineTo(v[i+seg+1].x, v[i+seg+1].y);
ctx.lineTo(v[i+seg+2].x+10, v[i+seg+2].y+10);
ctx.closePath();
t1 = (v[i+seg+2].x - v[i+seg+1].x)/w;
t2 = (v[i+seg+2].y - v[i+seg+1].y)/w;
t3 = (v[i+seg+2].x - v[i+1].x)/h;
t4 = (v[i+seg+2].y - v[i+1].y)/h;
ctx.setTransform(t1,t2,t3,t4, v[i+seg+1].x, v[i+seg+1].y);
if(!v[i+1].corner) {
//端っこ以外
ctx.clip();
ctx.drawImage(img, v[i].pivotX-_this.getOrigin().x, v[i].pivotY-_this.getOrigin().y ,w+10, h, 0, -h ,w+10, h);
}else{
ctx.clip();
ctx.drawImage(img, v[i].pivotX-_this.getOrigin().x, v[i].pivotY-_this.getOrigin().y ,w, h, 0, -h ,w, h);
}
ctx.restore();
if (meshToggle) ctx.stroke();
}
}
}
}
Coordinates.prototype.meshes = [];
Coordinates.prototype.pointSize = 10;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment