- ベストアンサー
javascriptの円形画像ギャラリーのサンプルを探しています
- ホームページ作成において、javascriptを使用した円形画像ギャラリーのサンプルを探しています。
- フラッシュではなくjavascriptで実装された、ゆっくり回転している画像ギャラリーが希望です。
- ドラッグなどでスピードが変わらず、単に円形(3D)になっている画像スライダーを探しています。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
function sinIntDeg (n) { return bufSin [n % 360 |0]; } function cosIntDeg (n) { return bufCos [n % 360 |0]; } function aryToFixedString (ary) { return ary.map (function (a) { return a.toFixed (10); } ).join (','); } function Tile (image, distance, angle, scale, offsetHeight) { this.image = image; this.distance = distance; this.angle = angle; this.scale = scale; this.offsetHeight = offsetHeight; this.position = {}; this.rotate (); } function TileRotateY (stepAngle) { var a = this.angle += stepAngle || 0; var r = this.distance; this.position = { x: sinIntDeg (a) * r, y: this.offsetHeight, z: cosIntDeg (a) * r }; return this; } function TileCreate (image, distance, angle, scale, offsetHeight) { if (arguments.length < 2) throw new Error; return new Tile ( image, distance || 100, angle || 0, scale || 1, offsetHeight || 0 ); } Tile.prototype.rotate = TileRotateY; Tile.create = TileCreate; //________________________ function FloorMember (member, angle, step) { this.member = member; this.angle = angle; this.step = step; this.timerId = null; } function FloorMemberRotate () { this.angle += this.step; this.member.forEach (function (tile) { var p = tile.rotate (this.step).position; var sin = sinIntDeg (tile.angle); var cos = cosIntDeg (tile.angle); var ary = [ tile.scale * cos, 0, -sin, 0, 0, tile.scale, 0, 0, sin, 0, tile.scale * cos, 0, p.x, p.y, p.z, 1 ]; tile.image.style['-webkit-transform'] = 'matrix3d('+ aryToFixedString (ary)+')'; }, this); } function FloorMemberStart () { var that = this; var func = function () { that.rotate (); }; if (! this.timerId) { this.timerId = setInterval (func, 30); } } function FloorMemberCreate (images, radius, offsetFloor, step) { if (arguments.length < 2) throw new Error; var member = []; var imgs = Array.prototype.slice.call (images, 0); var len = imgs.length; var side = int (radius * 2 * Math.tan (Math.PI / len) + 0.5); var img; var aspectRatio = parseInt (imgs[0].height, 10) / parseInt (imgs[0].width, 10); var height = int (side * aspectRatio + 0.5); var offsetHeight = (offsetFloor || 0) * height; var n = 360 / len; for (var i = 0; i < len; i++) { img = imgs[i]; img.width = String (side); img.height = String (height); member.push (new Tile (img, radius, n * i, 1, offsetHeight)); } return new FloorMember (member, 0, step || 1); } FloorMember.prototype.start = FloorMemberStart; FloorMember.prototype.rotate = FloorMemberRotate; FloorMember.create = FloorMemberCreate; this.FloorMember = FloorMember; }) (); FloorMember.create (document.querySelectorAll ('#screen img[alt="f0"]'), 1000, 0, 1).start (); FloorMember.create (document.querySelectorAll ('#screen img[alt="f1"]'), 1000, 1, 2).start (); FloorMember.create (document.querySelectorAll ('#screen img[alt="f2"]'), 1000, 2, 3).start (); </script> ipad2 で、うごかしてみました。 そこそこ速くうごきますよ!
その他の回答 (8)
- babu_baboo
- ベストアンサー率51% (268/525)
おはようございます。あそんでいたら、あさになりました。 ipad なら、ごきぼうどおりにうごきます(?) ながいので、ぶんかつです。 fujillin さんに、しげきされ・・・ <!DOCTYPE html> <title>sample</title> <style> #screen { -webkit-perspective: 500px; -webkit-transform : transform-style('preserve-3d'); } #screen img { position : absolute; top : 100; } </style> <body> <div id="screen"> <img src="./img/photo0.jpg" alt="f0" width="400" height="100"> <img src="./img/photo1.jpg" alt="f0" width="400" height="100"> <img src="./img/photo0.jpg" alt="f0" width="400" height="100"> <img src="./img/photo1.jpg" alt="f0" width="400" height="100"> <img src="./img/photo0.jpg" alt="f0" width="400" height="100"> <img src="./img/photo1.jpg" alt="f0" width="400" height="100"> <img src="./img/photo0.jpg" alt="f0" width="400" height="100"> <img src="./img/photo1.jpg" alt="f0" width="400" height="100"> <img src="./img/photo0.jpg" alt="f1" width="400" height="100"> <img src="./img/photo1.jpg" alt="f1" width="400" height="100"> <img src="./img/photo0.jpg" alt="f1" width="400" height="100"> <img src="./img/photo1.jpg" alt="f1" width="400" height="100"> <img src="./img/photo0.jpg" alt="f1" width="400" height="100"> <img src="./img/photo1.jpg" alt="f1" width="400" height="100"> <img src="./img/photo0.jpg" alt="f1" width="400" height="100"> <img src="./img/photo1.jpg" alt="f1" width="400" height="100"> <img src="./img/photo0.jpg" alt="f2" width="400" height="100"> <img src="./img/photo1.jpg" alt="f2" width="400" height="100"> <img src="./img/photo0.jpg" alt="f2" width="400" height="100"> <img src="./img/photo1.jpg" alt="f2" width="400" height="100"> <img src="./img/photo0.jpg" alt="f2" width="400" height="100"> <img src="./img/photo1.jpg" alt="f2" width="400" height="100"> <img src="./img/photo0.jpg" alt="f2" width="400" height="100"> <img src="./img/photo1.jpg" alt="f2" width="400" height="100"> </div> <script> (function () { var sin = Math.sin; var cos = Math.cos; var int = Math.floor; var deg = Math.PI / 180; var tmp; var bufSin = []; var bufCos = []; for (var i = 0; i < 360; i++) { tmp = i * deg; bufSin[i] = sin (tmp); bufCos[i] = cos (tmp); } //つづく
- fujillin
- ベストアンサー率61% (1594/2576)
#5です。 初期位置が予定と違っているのに気が付きました。 計算ミスってましたので、訂正。 // var animationOffset = 0; 削除(使用していなかった) var setUnitData = function(){ var sylinder = getSylinderPos(); // imageOffsetX = sylinder(0).sx; 符号間違え imageOffsetX = -sylinder(0).sx; for(x = 0; x<screenW; x += unitW) units.push(sylinder(x)); unitN = units.length; imageOffsetX = 0; // 追加してます } 初期表示の位置だけなので、あまり問題にはならないけれど、 他にもいろいろあるかも。
- fujillin
- ベストアンサー率61% (1594/2576)
// つづき var setEvent = function(){ document.addEventListener("click", function(evt){ var t = evt.target; if(t.parentNode.id != "buttons") return; switch(t.value){ case "<": if(animate){ if(speed>-30) speed -= 2; if(speed==0) stop(); } else { speed = -1; start(); } break; case "□": speed = 0; stop(); break; case ">": if(animate){ if(speed<30) speed += 2; if(speed==0) stop(); } else { speed = 1; start(); } break; default: } }, false); } var init = function(id){ canvas = document.createElement("canvas"); var sc = document.getElementById(id); if(!canvas.getContext || !sc) return; screenW = sc.clientWidth; screenH = sc.clientHeight; sc.insertBefore(canvas, sc.firstChild); var img = sc.getElementsByTagName("img"); imageH = img[0].clientHeight; setCanvas(); setUnitData(); setSourceImage(img); setEvent(); draw(); } init(id); } //--> </script> </body> </html>
- fujillin
- ベストアンサー率61% (1594/2576)
#3です。 canvasを使ったことがないので、お勉強のために作ってみました。 なんとかアニメーションに耐えられそう。 立体の座標計算もよくわからないので、かなりいい加減です。(要領も悪い) それなのでとてもこのままでは使えませんが、とりあえず雰囲気は出ているので、サンプル代わりに… (<>のクリックで速度が変わります) (全角空白は半角に) <!DOCTYPE html> <head><title>sample</title> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <style type="text/css"> <!-- #screen{ width: 800px; height: 300px; position: relative; overflow: hidden; } #screen img{ width: 200px; height: 100px; border: 1ps solid red; } #buttons{ width: 800px; text-align: right; } #buttons input{ background-color: #fff; } //--> </style> </head> <body> <div id="screen"> <img src="img/photo01.jpg" alt="photo01"> <img src="img/photo02.jpg" alt="photo02"> <img src="img/photo03.jpg" alt="photo03"> <img src="img/photo04.jpg" alt="photo04"> <img src="img/photo05.jpg" alt="photo05"> </div> <div id="buttons"> <input type="button" value="<"> <input type="button" value="□"> <input type="button" value=">"> </div> <script type="text/javascript"> <!-- window.onload = function(){ var id = "screen"; // 対象要素のid var diameter = 350; // 円筒の径 var zOffset = 35; // 視点の高さ方向オフセット var unitWidth= 1; // 画像の計算幅(ピッチ) var speed = 0; // アニメーション速度 var interval = 40; // アニメーションインターバル var canvas; var ctx; var screenW; var screenH; var screenOffsetZ; var sourceImage; var imageW; var imageH; var imageOffsetX = 0; var unitW = unitWidth; var unitN; var units = []; var animate; var animationOffset = 0; var start = function(){ animate = setInterval(move, interval); } var stop = function(){ clearInterval(animate); animate = null; } var move = function(){ imageOffsetX += speed; if(imageOffsetX> imageW) imageOffsetX -= imageW; if(imageOffsetX<-imageW) imageOffsetX += imageW; draw(); } var draw = function(){ ctx.fillStyle = "#f0f0f0"; ctx.fillRect( 0 , 0 , screenW , screenH ); for(var i=0; i<unitN; i++){ var u = units[i]; var x = u.sx + imageOffsetX; while(x<0) x += imageW; while(x>imageW) x -= imageW; ctx.drawImage(sourceImage, x, u.sy, u.sw, u.sh, u.dx, u.dy, u.dw, u.dh); } } var setCanvas = function(){ ctx = canvas.getContext("2d"); diameter= Math.max(diameter, screenW * 0.3); ctx.globalCompositeOperation = "source-over"; canvas.setAttribute("width", screenW); canvas.setAttribute("height", screenH); canvas.style.position = "absolute"; var z = zOffset / Math.cos(Math.atan2(screenW, diameter)); screenOffsetZ = (screenH - z) * 0.5; } var setSourceImage = function(elms){ sourceImage = document.createElement("canvas"); var tmpC = sourceImage.getContext("2d"); var images = []; var w = 0; var h = imageH; var d = units[0].sw; var e; for(var i=0; e=elms[i++];){ images.push(e); w += e.clientWidth; } imageW = w; i = 0; while(d>0){ e = images[i++]; d -= e.clientWidth; w += e.clientWidth; images.push(e); } sourceImage.setAttribute("width", w); sourceImage.setAttribute("height", h); w = 0; for(i=0; e=images[i++];){ tmpC.drawImage(e, w, 0, e.clientWidth, imageH); w += e.clientWidth; } } var getSylinderPos = function(){ var ww = 0.5 * screenW; var dd = 0.5 * diameter; var hh = 0.5 * imageH; var offZ = screenOffsetZ - zOffset; var Matn = Math.atan2; var Mcos = Math.cos; return function(x){ var delta = unitW; if(x + delta > screenW) delta = screenW - x; var sx2 = Matn(x + delta - ww, dd) * diameter + imageOffsetX; var atn = Matn(x - ww, dd); var cos = 1 / Mcos(atn); var sx = atn * diameter + imageOffsetX; var sy = 0; var sy2 = imageH; var y = (zOffset - hh) * cos + offZ; var y2 = (zOffset + hh) * cos + offZ; return { sx:sx, sy:sy, sw:sx2-sx, sh:sy2-sy, dx:x, dy:y, dw:delta, dh:y2-y }; } } var setUnitData = function(){ var sylinder = getSylinderPos(); imageOffsetX = sylinder(0).sx; for(x = 0; x<screenW; x += unitW) units.push(sylinder(x)); unitN = units.length; } // つづく
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2280)
>No.3 なるほど、CSSで描く時は、transform: matrix3d()を使えばいけるかもしれません。 (私自身、matrix3d()の使い方がわかっていませんので、、、) http://jsfiddle.net/vEWEL/11/ http://jsfiddle.net/paulsidebottom/jbfSj/ via: http://stackoverflow.com/questions/8861739/css-matrix3d-transform
- fujillin
- ベストアンサー率61% (1594/2576)
#1です。 ちょっと探してみたら、canvasを利用して画像を変形する方法を紹介しているものがありました。 http://jsfiddle.net/fQk4h/ この方法を応用して円筒曲面からの投影を行なえば、それなりに綺麗にできると思いますが、計算量が多くなりそうなのでアニメーションに耐えられるかどうかは不明です。
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2280)
軸移動(No.1参照サイトのような移動)を表現するのはwidth、heightを小さくするだけです。 軸回転が組合わさる場合はCSS3のtransformが必要です。 { transform-style: preserve-3d; perspective: 500; transform: rotateY(60deg); } このような書き方で軸回転します。 ※すみません、両方とも「軸回転」というのが正式な呼び方かもしれませんが、 非常にわかりづらいと思いますので、個人的に「軸移動」「軸回転」と使い分けています。 CSSでは台形に変形させる方法はなかったと思います(skewという平行四辺形に変形させるものはあります。) ので、heightを調整して擬似的に見せかける程度では無いでしょうか。 ご参考まで。
- fujillin
- ベストアンサー率61% (1594/2576)
「carousel」、「3D」などをキーに検索してみればいろいろと見つかると思います。 原理的にはこんな感じでしょうか? (ご質問にあわせるには、近景部分を非表示するなどが必要ですが…) http://www.professorcloud.com/mainsite/carousel.htm