画布旋转-JavaScript

画布旋转-JavaScript,javascript,canvas,transform,Javascript,Canvas,Transform,如果有人知道答案,你能帮我吗? 我有两个图像-背景类似于弧和箭头。我需要在背景图像上移动箭头图像,就像这是一个时钟指针箭头。因此,我需要: 旋转箭头使其与圆弧上的当前记号平行 将箭头移动到下一点 为此,我需要在JavaScript中使用Canvas对象及其方法转换——这将允许移动箭头并旋转它 问题是:如何使用canvas.transform方法围绕圆弧旋转(并移动)箭头?在这种情况下,哪些值以及它们之间应该是什么关系: contextData.clearRect (0, 0, contextDa

如果有人知道答案,你能帮我吗? 我有两个图像-背景类似于弧和箭头。我需要在背景图像上移动箭头图像,就像这是一个时钟指针箭头。因此,我需要:

  • 旋转箭头使其与圆弧上的当前记号平行
  • 将箭头移动到下一点
  • 为此,我需要在JavaScript中使用Canvas对象及其方法转换——这将允许移动箭头并旋转它

    问题是:如何使用canvas.transform方法围绕圆弧旋转(并移动)箭头?在这种情况下,哪些值以及它们之间应该是什么关系:

    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 ();
    

    提前感谢。

    使用helper函数,而不是玩弄变换矩阵。旋转

    这样做可以使对象围绕其中心旋转

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

    使用helper函数,而不是摆弄变换矩阵

    这样做可以使对象围绕其中心旋转

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

    差点忘了。。。我找到了答案,它是有效的,这是最终的代码。要使其在IE中工作,您应该从Google添加excanvas库,并修复一些IE8问题,您需要添加兼容性元标记:

    <!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>
    
    
    帆布
    变量指示符类={
    timerHandle:0,
    时间显示:10,
    旋转增量:1,
    旋转步骤:0,
    旋转步数:50,
    旋转半径:35,
    电流:5,
    三角洲:150,
    方向顺时针:正确,
    画布指示器:空,
    画布指针:空,
    canvasContext:null,
    GetRadiangAngle:函数(degreeValue){
    返回degreeValue*Math.PI/180;
    },
    initCanvas:函数(选项列表){
    试一试{
    var canvasData=$('.indicator#canvas').get(0);
    如果($.browser.msie){
    canvasData=document.createElement('canvas');
    $(拉票数据)
    .attr('width',120)
    .attr('height',120)
    .attr('id','canvas')
    .appendTo(“.indicator”);
    canvasData=G_vmlcavasmanager.initElement(canvasData);
    /*
    var metaCompatible=document.createElement('meta');
    $(元可计算)
    .attr('http-equiv','X-UA-Compatible')
    .attr('content','IE=EmulateIE7')
    .prependTo(“头”);
    */
    //$('head')。前置('');
    //警报($('head').html());
    }
    indicatorClass.canvasIndicator=$('.indicator');
    indicatorClass.canvasPointer=$('.indicator.pointer').get(0);
    indicatorClass.canvasContext=canvasData.getContext(“2d”);
    $.extend(指示符类、选项列表);
    var angleMax=指示器Class.angleCurrent+指示器Class.angleDelta;
    指示器等级设置旋转角度(510);
    indicatorClass.timerHandle=setInterval(函数(){
    如果(指示灯Class.angleCurrent>angleMax){
    clearInterval(指示器Class.timerHandle);
    }
    指示灯总成角度电流+=指示灯总成旋转增量;
    indicatorClass.rotationStep+=indicatorClass.rotationIncrement;
    indicatorClass.setRotation();
    },指示器类别。时间显示);
    }捕获(数据除外){
    警报(“指示器未加载”);
    }
    },
    getCircleCoords:函数(步骤索引){
    var centerX=indicatorClass.canvasIndicator.width()/2;
    var centerY=indicatorClass.canvasIndicator.height()/2;
    var coordValues={
    currentX:(centerX+指示器类旋转半径*Math.cos(2*Math.PI*stepIndex/indicatorClass.rotationSteps)),
    当前:(中心+指示器类旋转半径*Math.sin(2*Math.PI*stepIndex/指示器类旋转步长))
    }
    返回坐标值;
    },
    设置旋转角度:函数(角度值){
    indicatorClass.canvasContext.translate(indicatorClass.canvasIndicator.width()/2,indicatorClass.canvasIndicator.height()/2);
    用于(var currentAngle=90;currentAngle angleValue){
    indicatorClass.canvasContext.transform(cos,deltaY,deltaX,cos,0,0);
    返回false;
    }
    }
    },
    setTransform:函数(){
    var sin=数学sin(indicatorClass.rotationStep*Math.PI/indicatorClass.rotationSteps);
    var cos=数学.cos(indicatorClass.rotationStep*Math.PI/indicatorClass.rotationSteps);
    var deltaX=指示器类别方向顺时针?-sin:sin;
    var deltaY=指示器类别方向顺时针?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:函数(){
    var currentAngle=指示器Class.Direction顺时针?指示器Class.Angle电流:-indicatorClass.Angle电流;
    indicatorClass.canvasContext.save();
    indicatorClass.canvasContext.rotate(indicatorClass.GetRadiangAngle(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();
    }
    }
    赢