Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Вращение с вложением в canvas.transform :) (https://javascript.ru/forum/project/12825-vrashhenie-s-vlozheniem-v-canvas-transform.html)

artemiusgreat 04.11.2010 13:58

Вращение с вложением в canvas.transform :)
 
Вложений: 2
Привет всем,

Возник вопрос, если кто знает решение, плиз, отзовитесь.
Есть картинка-фон, типа часы, есть стрелка.
НО важно то, что стрелка это маленькая продолговатая картинка, которая начинается отнюдь не в центре циферблата. У меня получается вращать ее вокруг своей оси, но как вращать вокруг цетра часов пока понять не могу, нужна формула, которой я похоже не знаю.

Собственно вопрос : как вращать картинку вокруг точки, находящейся за пределами картинки, при этом так как картинка продолговатая, вращаться она должна и вокруг своей оси чтобы указывать и быть параллельной текущему делению на циферблате.
Или хотя бы обьясните как соотносятся друг с другом параметры метода transform и координаты в пространстве.

Спасибо за любые ответы и ссылки.

Вот кусочек кода :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
   <title>Canvas :: Sample #1</title>
   <script type="text/javascript" src="jquery.min.js"></script>
   <script type="text/javascript" src="excanvas.js"></script>
</head>
<body>

<script type="text/javascript">

var indicatorClass = {

   rotationIncrement : 10,
   rotationRadius : 40,
   rotationAngle : -105,

   getRadianAngle : function (degreeValue) {
      return degreeValue * Math.PI / 180;
   },

   initCanvas : function () {

      var indicatorData = $ ('.indicator'),
          pointerImage = indicatorData.find ('.pointer');
       
      var canvasData = $ ('#canvas').get (0),
          contextData = canvasData.getContext ("2d"),
          rotationArrow = pointerImage.get (0);
          
      setInterval(function () { 
         indicatorClass.rotationAngle += 10;
         indicatorClass.rotationIncrement++;
         indicatorClass.setTransform (contextData, indicatorData, rotationArrow); 
      }, 100);
      
   },

   setTransform : function (contextData, indicatorData, rotationArrow) {
   
      var sin = Math.sin(indicatorClass.rotationIncrement * Math.PI / 6);  
      var cos = Math.cos(indicatorClass.rotationIncrement * Math.PI / 6);
   
      contextData.clearRect (0, 0, contextData.canvas.width, contextData.canvas.height);
      contextData.save ();
      contextData.translate(indicatorData.width () / 2, indicatorData.height () / 2);
      contextData.transform(cos, sin, -sin, cos, 0, 0);
      contextData.drawImage(rotationArrow, -rotationArrow.width / 2, -rotationArrow.height / 2);
      contextData.restore ();
   
   },

   setRotation : function (contextData, indicatorData, rotationArrow) {
   
      contextData.clearRect (0, 0, contextData.canvas.width, contextData.canvas.height);
      contextData.save ();
      contextData.translate(indicatorData.width () / 2, indicatorData.height () / 2);
      contextData.rotate(indicatorClass.getRadianAngle (indicatorClass.rotationAngle));
      contextData.drawImage(rotationArrow, -rotationArrow.width / 2, -rotationArrow.height / 2);
      contextData.restore ();
   }

}

window.onload = function () {
   indicatorClass.initCanvas ();
}

</script>

<style type="text/css">
.indicator {
   width:120px;
   height:120px;
   border:1px solid #ccc;
   text-align:center;
   position:relative;
}
.indicator .pointer {
   visibility:hidden;
}
.indicator #canvas {
   z-index:10000;
   position:absolute;
   top:0;
   left:0;
   width:100%;
   height:100%;
}
</style>

<div class="indicator">
   <img class="image" src="usage_icon_electro.png" alt="" />
   <img class="pointer" src="usage_electro_pointer.png" alt="" />
   <canvas width="120" height="120" id="canvas"></canvas>
</div>

</body>
</html>

monolithed 04.11.2010 14:33

недопьяный он у вас какой-то, лучше так или так :D

если серьезно то наверное это нужно?

artemiusgreat 04.11.2010 15:02

Ooo, точно вот что надо менять, вы почти угадали, надо было только стрелку выше расположить, вот так.
Спасибо большое!!!
http://www.jsfiddle.net/RTq5N/21/

П.С. пьяный вариант мне тоже понравился :)
так тоже интересно выглядит :
var sin = Math.sin(indicatorClass.rotationIncrement * Math.PI / 6) + 1;

monolithed 04.11.2010 15:12

Цитата:

Сообщение от artemiusgreat
http://www.jsfiddle.net/RTq5N/21/

я там чуть подправил
contextData.transform(cos, sin, -sin, cos, -6, 0);

artemiusgreat 04.11.2010 15:32

Спасибо, но сама стрелка и должна быть посередине, это бекграунд сдвинулся, у меня это исправляется стилями.

mycoding 13.11.2010 21:29

А что это за сайт http://www.jsfiddle.net?

Какой то интересный сервис для разработки на js?

monolithed 14.11.2010 00:01

Цитата:

Сообщение от mycoding
А что это за сайт http://www.jsfiddle.net?

Тестовая площадка.

Цитата:

Сообщение от mycoding
Какой то интересный сервис для разработки на js?

Очень удобно когда работаешь с несколькими библиотеками или когда нужно сделать небольшой скрипт, а создавать новый документ лень.
Можно сохранять все что сделал и пр.

Лично я им пользуюсь ежеминутно))

mycoding 14.11.2010 09:35

А ещё что нибудь эдакое Вы знаете? :)

monolithed 14.11.2010 16:01

в каком смысле?

mycoding 14.11.2010 16:21

Ну http://www.jsfiddle.net - это в моём понимание "эдакое" )))
У Вас есть ещё что нибудь эдакое?

Ну не знаю, может Вы знаете какой нибудь ещё framework вроде
Raphael или ещё что?

monolithed 14.11.2010 16:45

Цитата:

Сообщение от mycoding
Ну не знаю, может Вы знаете какой нибудь ещё framework вроде Raphael или ещё что?

Raphael знаю:) Но это совсем другая история)))

Я не придаю особое значение подобным вещам, потому что пользуюсь ими по необходимости, может еще что-то есть но так сказать не могу. Об этом лучше на хабре искать информацию.


Часовой пояс GMT +3, время: 07:52.