プロが教えるわが家の防犯対策術!

こんにちは、現在ホームページを作ろうと思っていて
1点javascriptによる実装を考えております。

http://www.flashmo.com/preview/flashmo_098_3d_cu …
がイメージに近いのですが、これだとflashなので、
これに似たjavascriptを探しております。
(・ドラッグとかでスピードが変わらなくてもよく、
  単にゆっくり回転している物を探しております。
 ・単に画像ギャラリーのsliderを少し円形(3D)にしたものを
  探しております。)

なにか情報がございましたら
どんな情報でも良いので、ご相談させてくださいませ。

失礼致します。

A 回答 (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 で、うごかしてみました。 そこそこ速くうごきますよ!
    • good
    • 0

おはようございます。

あそんでいたら、あさになりました。
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);
 }
 
//つづく
    • good
    • 0

#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; // 追加してます
 }


初期表示の位置だけなので、あまり問題にはならないけれど、
他にもいろいろあるかも。
    • good
    • 0

// つづき



 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>
    • good
    • 0

#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;
 }

// つづく
    • good
    • 0

>No.3


なるほど、CSSで描く時は、transform: matrix3d()を使えばいけるかもしれません。
(私自身、matrix3d()の使い方がわかっていませんので、、、)

http://jsfiddle.net/vEWEL/11/
http://jsfiddle.net/paulsidebottom/jbfSj/
via: http://stackoverflow.com/questions/8861739/css-m …
    • good
    • 0

#1です。



ちょっと探してみたら、canvasを利用して画像を変形する方法を紹介しているものがありました。
http://jsfiddle.net/fQk4h/

この方法を応用して円筒曲面からの投影を行なえば、それなりに綺麗にできると思いますが、計算量が多くなりそうなのでアニメーションに耐えられるかどうかは不明です。
    • good
    • 0

軸移動(No.1参照サイトのような移動)を表現するのはwidth、heightを小さくするだけです。


軸回転が組合わさる場合はCSS3のtransformが必要です。


{
transform-style: preserve-3d;
perspective: 500;
transform: rotateY(60deg);
}

このような書き方で軸回転します。


※すみません、両方とも「軸回転」というのが正式な呼び方かもしれませんが、
非常にわかりづらいと思いますので、個人的に「軸移動」「軸回転」と使い分けています。


CSSでは台形に変形させる方法はなかったと思います(skewという平行四辺形に変形させるものはあります。)
ので、heightを調整して擬似的に見せかける程度では無いでしょうか。

ご参考まで。
    • good
    • 0

「carousel」、「3D」などをキーに検索してみればいろいろと見つかると思います。




原理的にはこんな感じでしょうか?
(ご質問にあわせるには、近景部分を非表示するなどが必要ですが…)
http://www.professorcloud.com/mainsite/carousel. …
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!