简体   繁体   English

画布旋转-JavaScript

[英]Canvas rotation - JavaScript

If someone has the answer could you help me, please? 如果有人有答案,可以帮我吗? I have 2 images - background similar to arc and arrow. 我有2张图片-背景类似于弧形和箭头。 And i need to move arrow image over background image like this is a clock ticker arrow. 我需要将箭头图像移到背景图像上,像这样是时钟行情自动收录器箭头。 So i need : 所以我需要:

  1. Rotate arrow to make it parallel to current tick on the arc 旋转箭头使其平行于圆弧上的当前刻度
  2. Move arrow to the next point 将箭头移至下一点

For this i need to use Canvas object in JavaScript and its method transform - this will allow to move arrow and rotate it. 为此,我需要在JavaScript中使用Canvas对象及其方法转换-这将允许移动箭头并旋转它。

The question is : how to use canvas.transform method to rotate (and desirable move) arrow around the arc? 问题是:如何使用canvas.transform方法围绕弧线旋转(以及所需的移动)箭头? And which values and what relation between them should be in this case : 在这种情况下,应该确定哪些值以及它们之间的关系:

contextData.clearRect (0, 0, contextData.canvas.width, contextData.canvas.height);
contextData.save ();
contextData.translate(indicatorData.width () / 2, indicatorData.height () / 2);
contextData.transform(1, 0, 0, 1, x, y);  // the question is HERE
contextData.drawImage(rotationArrow, -rotationArrow.width / 2, -rotationArrow.height / 2);
contextData.restore ();

Thanks in advance. 提前致谢。

Instead of fooling around with a transformation matrix, use the helper function .rotate 与其使用转换矩阵来代替,不如使用辅助函数.rotate

Doing this will let you rotate an object about its center 这样做可以使对象绕其中心旋转

contextData.save()
contextData.translate(indicatorData.width() / 2, indicatorData.height() / 2) // ASSUMING this  is the object you want to rotate around the center of and that it is being drawn at 0,0
contextData.rotate(1.57) // 1.57 radians = about 90 degrees
contextData.drawImage(rotationArrow, -rotationArrow.width / 2, -rotationArrow.height / 2);
contextData.restore()

Almost forgot ... i found the answer, it works and this is the final code. 差点忘了...我找到了答案,它起作用了,这是最终代码。 To make it worked in IE you should add excanvas library from Google and to fix some IE8 issues you need to add compatibility meta tag : 为了使其在IE中起作用,您应该从Google添加excanvas库,并修复一些IE8问题,您需要添加兼容性meta标签:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
   <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
   <title>Canvas</title>
   <script type="text/javascript" src="jquery.min.js"></script>
   <script type="text/javascript" src="excanvas.js"></script>
</head>
<body>

<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>

<script type="text/javascript">

var indicatorClass = {

   timerHandle : 0,
   timerDelay : 10,

   rotationIncrement : 1,
   rotationStep : 0,
   rotationSteps : 50,
   rotationRadius : 35,

   angleCurrent : 5,
   angleDelta : 150,

   directionClockwise : true,

   canvasIndicator : null,
   canvasPointer : null,
   canvasContext : null,

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

   initCanvas : function (optionList) {

      try {

         var canvasData = $ ('.indicator #canvas').get (0);

         if ($.browser.msie) {
            canvasData = document.createElement('canvas');
            $ (canvasData)
               .attr ('width', 120)
               .attr ('height', 120)
               .attr ('id', 'canvas')
               .appendTo('.indicator');
            canvasData = G_vmlCanvasManager.initElement(canvasData);
            /*
            var metaCompatible = document.createElement('meta');
            $ (metaCompatible)
               .attr ('http-equiv', 'X-UA-Compatible')
               .attr ('content', 'IE=EmulateIE7')
               .prependTo('head');
            */
            //$ ('head').prepend ('<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />');
//alert ($ ('head').html ());
         }

         indicatorClass.canvasIndicator = $ ('.indicator');
         indicatorClass.canvasPointer = $ ('.indicator .pointer').get (0);
         indicatorClass.canvasContext = canvasData.getContext ("2d");

         $.extend (indicatorClass, optionList);

         var angleMax = indicatorClass.angleCurrent + indicatorClass.angleDelta;
         indicatorClass.setRotationAngle (510);

         indicatorClass.timerHandle = setInterval(function () { 
            if (indicatorClass.angleCurrent > angleMax) {
               clearInterval (indicatorClass.timerHandle);
            }
            indicatorClass.angleCurrent += indicatorClass.rotationIncrement;
            indicatorClass.rotationStep += indicatorClass.rotationIncrement;
            indicatorClass.setRotation (); 
         }, indicatorClass.timerDelay);

      } catch (exceptionData) {
         alert ('Indicator is not loaded');
      }
   },

   getCircleCoords : function (stepIndex) {

      var centerX = indicatorClass.canvasIndicator.width () / 2;
      var centerY = indicatorClass.canvasIndicator.height () / 2;
      var coordValues = {
         currentX : (centerX + indicatorClass.rotationRadius * Math.cos (2 * Math.PI * stepIndex / indicatorClass.rotationSteps)),
         currentY : (centerY + indicatorClass.rotationRadius * Math.sin (2 * Math.PI * stepIndex / indicatorClass.rotationSteps))
      }

      return coordValues;
   },

   setRotationAngle : function (angleValue) {

      indicatorClass.canvasContext.translate(indicatorClass.canvasIndicator.width () / 2, indicatorClass.canvasIndicator.height () / 2);

      for (var currentAngle = 90; currentAngle <= 720; currentAngle++) {

         var sin = Math.sin(currentAngle * Math.PI / 360);  
         var cos = Math.cos(currentAngle * Math.PI / 360);
         var deltaX = indicatorClass.directionClockwise ? -sin : sin;
         var deltaY = indicatorClass.directionClockwise ? sin : -sin;

         if (currentAngle > angleValue) {
            indicatorClass.canvasContext.transform(cos, deltaY, deltaX, cos, 0, 0);
            return false;
         }
      }
   },

   setTransform : function () {

      var sin = Math.sin(indicatorClass.rotationStep * Math.PI / indicatorClass.rotationSteps);  
      var cos = Math.cos(indicatorClass.rotationStep * Math.PI / indicatorClass.rotationSteps);
      var deltaX = indicatorClass.directionClockwise ? -sin : sin;
      var deltaY = indicatorClass.directionClockwise ? sin : -sin;

      //indicatorClass.canvasContext.clearRect (0, 0, indicatorClass.canvasContext.canvas.width, indicatorClass.canvasContext.canvas.height);
      indicatorClass.canvasContext.save ();
      //indicatorClass.canvasContext.translate(indicatorClass.canvasIndicator.width () / 2, indicatorClass.canvasIndicator.height () / 2);
      indicatorClass.canvasContext.transform(cos, deltaY, deltaX, cos, 0, 0);
      indicatorClass.canvasContext.clearRect (-screen.width, -screen.height, screen.width, screen.height);
      indicatorClass.canvasContext.drawImage(indicatorClass.canvasPointer, -indicatorClass.canvasPointer.width / 2, -indicatorClass.canvasPointer.height - indicatorClass.rotationRadius);
      indicatorClass.canvasContext.restore ();
   },

   setRotation : function () {

      var currentAngle = indicatorClass.directionClockwise ? indicatorClass.angleCurrent : -indicatorClass.angleCurrent;

      indicatorClass.canvasContext.save ();
      indicatorClass.canvasContext.rotate(indicatorClass.getRadianAngle (currentAngle));
      indicatorClass.canvasContext.clearRect (-screen.width, -screen.height, screen.width, screen.height);
      indicatorClass.canvasContext.drawImage(indicatorClass.canvasPointer, -indicatorClass.canvasPointer.width / 2, -indicatorClass.canvasPointer.height - indicatorClass.rotationRadius);
      indicatorClass.canvasContext.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>

</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM