我可以在课堂上修改我的DOM吗?

时间:2016-03-28 15:07:58

标签: javascript dom

这非常简单,但我似乎无法弄清楚如何做到这一点。我得到" Uncaught TypeError:this.resizeCanvas不是函数"来自Chrome中的控制台。该代码用于调整绘制模拟时钟的画布的大小。

<编辑> 粘贴整个代码,而不仅仅是让我头痛的问题 < /编辑>

JAVASCRIPT

function Hands(canvas)
{
    this.angle = 0;
    this.beginX = canvas.width / 2;
    this.beginY = canvas.height / 2;
    this.endX = 0;
    this.endY = 0;
    this.radius = 0;
    this.length = 0;
    this.modLength = 0;
    this.color = '';
    this.lineCap = '';
    this.lineWidth = 0;
    this.rotation = ( Math.PI * 2 ) / 4;

    this.draw = function(ctx)
    {
        this.length = this.radius - this.modLength;

        this.endX = this.beginX + Math.cos( this.angle - this.rotation ) * this.length;
        this.endY = this.beginY + Math.sin( this.angle - this.rotation ) * this.length;

        ctx.beginPath();
        ctx.moveTo( this.beginX, this.beginY );
        ctx.lineWidth = this.lineWidth;
        ctx.strokeStyle = this.color;
        ctx.lineCap = this.lineCap;
        ctx.lineTo( this.endX, this.endY );
        ctx.stroke();
    };
}

function AnalogClock()
{
    this.canvas = document.getElementById( "clockface" );
    this.context = this.canvas.getContext('2d');

    this.margin = 30;
    this.rotation = (Math.PI * 2) / 4; // Rotate 0 rad to be at top of circle
    this.centerX = this.canvas.width / 2;
    this.centerY = this.canvas.height / 2;

    this.secondHand = new Hands(this.canvas);
    this.secondHand.lineWidth = 3;
    this.secondHand.modLength = 100;
    this.secondHand.beginX = this.centerX;
    this.secondHand.beginY = this.centerY;
    this.secondHand.color = '#ff0000';
    this.secondHand.radius = this.canvas.height / 2.031;

    this.minuteHand = new Hands(this.canvas);
    this.minuteHand.lineWidth = 10;
    this.minuteHand.modLength = 100;
    this.minuteHand.beginX = this.centerX;
    this.minuteHand.beginY = this.centerY;
    this.minuteHand.color = '#101010';
    this.minuteHand.radius = this.canvas.height / 2.031;

    this.hourHand = new Hands(this.canvas);
    this.hourHand.lineWidth = 16;
    this.hourHand.modLength = 175;
    this.hourHand.beginX = this.centerX;
    this.hourHand.beginY = this.centerY;
    this.hourHand.color = '#101010';
    this.hourHand.radius = this.canvas.height / 2.031;

    this.drawSecondHand = function( s )
    {
        this.secondHand.angle = ( Math.PI * 2 ) * ( s / 60 );
        this.secondHand.draw( this.context );
    };

    this.drawMinuteHand = function( m )
    {
        this.minuteHand.angle = ( Math.PI * 2 ) * ( m / 60 );
        this.minuteHand.draw( this.context );
    };

    this.drawHourHand = function( h )
    {
        this.hourHand.angle = ( Math.PI * 2 ) * ( h / 12 );
        this.hourHand.draw( this.context );
    };

    this.drawDot = function( x, y, radius, radians, color )
    {
        this.context.beginPath();
        this.context.arc( x, y, radius, 0, Math.PI * 2, false );
        this.context.fillStyle = color;
        this.context.fill();
    };

    this.drawClockFace = function()
    {
        var distance = this.centerY - 80;

        for( i = 0; i < 60; i++ )
        {
            var targetX = this.centerX + Math.cos( ( ( Math.PI * 2 ) * ( i / 60 ) ) - this.rotation ) * distance;
            var targetY = this.centerY + Math.sin( ( ( Math.PI * 2 ) * ( i / 60 ) ) - this.rotation ) * distance;

            this.drawDot( targetX, targetY, 3, this.minuteHand.color);
        }

        for( i = 0; i < 12; i++ )
        {
            var targetX = this.centerX + Math.cos( ( ( Math.PI * 2 ) * ( i / 12 ) ) - this.rotation ) * distance;
            var targetY = this.centerY + Math.sin( ( ( Math.PI * 2 ) * ( i / 12 ) ) - this.rotation ) * distance;

            this.drawDot( targetX, targetY, 8, this.hourHand.color );
        }
    };

    this.resizeCanvas = function()
    {
        this.canvas.width  = window.innerWidth  - this.margin;
        this.canvas.height = window.innerHeight - this.margin;
    };

    this.draw = function() 
    {
        var now = new Date();

        this.resizeCanvas();
        this.drawClockFace();
        this.drawHourHand( now.getHours() );
        this.drawMinuteHand( now.getMinutes() );
        this.drawSecondHand( now.getSeconds() );

        this.drawDot( this.centerX, this.centerY, 10, this.secondHand.color ); // Center dot
    };
}


/******** 
LOAD APP
*********/

// ctx.translate(0.5, 0.5); // Anti-aliasing

var analogClock = new AnalogClock();

function tick()
{
    setInterval( analogClock.draw, 1000 );
    analogClock.draw();
}

document.addEventListener("DOMContentLoaded", function(){ tick(); });

HTML

<!DOCTYPE html>
<html>
    <head>
        <style>
            body {
                background: #fefefe;
            }

            canvas {
                background: #fefefe;
            }
        </style>
    </head>
    <body id="root">
        <canvas id="clockface"></canvas>
        <script src="clock.js"></script>
    </body>
</html>

3 个答案:

答案 0 :(得分:2)

你需要更像这样的代码...

function tick() {
    analogClock.draw();
    //setInterval(tick, 1000); - WRONG
    setTimeout(tick, 1000); // Or preferably use requestAnimationFrame.
}

window.addEventListener("load", function() {
    tick();
});

然而,当我这样做时,它在Firefox中运行得非常糟糕。也许requestAnimationFrame可以更好地工作,但是有一些东西会锁定它,我无法完全指责。但是,这确实解决了当前问题的resizeCanvas以未定义的形式返回。当你删除勾选并只是调用resizeCanvas或直接绘制时,它们工作正常。一旦滴答正确循环,它也可以正常工作。

我怀疑性能问题是由每次调用时调用画布的大小调整引起的。你可能不想那样做。如果窗口调整大小,您只需要调用它。

结果时钟倒置BTW。在Hands对象中,这可以纠正它......

this.rotation = -Math.PI / 2;

答案 1 :(得分:1)

问题的根源是setTimeoutsetInterval调用的函数始终具有当前this的{​​{1}}对象。在对象的方法上使用这些函数中的任何一个时,您必须使用包装函数或使用window

apply()

//wrapper
setTimeout(function(){analogClock.draw();}, 1000);

相反,你应该写:

//apply
setTimeout(function(){analogClock.draw.apply(analogClock), 1000);

function tick()
{
    analogClock.draw();
}

document.addEventListener("DOMContentLoaded", function(){ setInterval(tick, 1000); })

答案 2 :(得分:0)

clock.resize()更改为myClock.resize()