@pro100blich

JavaScript: HTML5 Canvas (масштаб под окно)?

Всем привет нужна помощь Ваша, дорогие коллеги. Имеется программа Бабочку Хофштадтера, при масштабирования она не изменяется по ширине и длине, не знаю как исправить это. Если посмотреть на border: black то будет понятнее.

Если меняем размер окна, то правый бар идет отлично, но до определенного момента пока не создастся конфликт полей.

HTML

<!DOCTYPE html>
<html>

<head>
    <title>Бабочку Хофштадтера</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
    <script src="script.js"></script>
</head>

<body>
    <div class="main">
        <canvas id="theCanvas" height="500" width="500"></canvas>
        <div id="rightBar">
            <h1>Бабочку Хофштадтера</h1>
            <form>
                <div class="Buttons">
                    <button id="startButton" onclick="start();" type="button">Старт</button>
                    <button id="stopButton" onclick="stop();" type="button">Стоп</button>
                </div>
                <div class="values">
                    <label for="qValue">
                        <p>q:</p>
                    </label>
                    <span id="qValue">0</span>
                </div>
            </form>
        </div>
    </div>
</body>

</html>

CSS

* {
    margin: 0;
    padding: 0;
}

body {
    max-width: 100%;
    background-color: #d4d4d4;
}

.main {
    width: 58vw;
    display: flex;
    margin: 1vw auto;
     border: 5px solid black; 
}

canvas {
    margin: ;
    /*    border: 2px solid red;*/
}

#rightBar {
    width: 20vw;
    background-color: #a6c5ff;
    /*    border: 1px solid blue;*/
}

h1 {
    font-size: 1.5vw;
    text-align: center;
}

.Buttons {
    width: 15vw;
    display: flex;
    margin: 1vw auto;
    text-align: center;
}

#startButton {
    margin-right: 3vw;
    border: 0 solid red;
    width: 6vw;
    display: flex;
    color: #fff;
    text-decoration: none;
    text-transform: uppercase;
    font-size: 1vw;
    background: #6530ff;
    padding: 0.2vw 0.1vw 0.1vw 1.4vw;
    transition: .3s cubic-bezier(0.2, 0, 1, 1);
}

#startButton:hover {
    background: #B69EFC;
    padding: 0.2vw 0.1vw 0.1vw 1.4vw;
    border-radius: 1vw;
    font-size: 1vw;
}

#stopButton {
    border: 0 solid red;
    width: 6vw;
    display: flex;
    color: #fff;
    text-decoration: none;
    text-transform: uppercase;
    font-size: 1vw;
    background: #6530ff;
    padding: 0.2vw 0.1vw 0.1vw 1.6vw;
    transition: .3s cubic-bezier(0.2, 0, 1, 1);
}

#stopButton:hover {
    background: #B69EFC;
    padding: 0.2vw 0.1vw 0.1vw 1.6vw;
    border-radius: 1vw;
    font-size: 1vw;
}

.values {
    display: flex;
    font-size: 1.5vw;
    width: 3vw;
    margin: 0 auto;
}

JS

var keepRunning = true;
var canvas, ctx, w, h;
var q = 4,
    qmax = 280;
var MAXX, MAXY;

// flip x, y
function drawPoint(x, y) {
    // console.log('drawPoint(', x, y, ')');
    ctx.beginPath();
    ctx.fillRect(y, x, 1, 1);
    ctx.stroke();
}

function next() {
    $('#qValue').text(q);
    // puffer=createImage(getSize().width,getSize().height);
    // puffer=createImage(600,500);
    // pufferG=puffer.getGraphics();
    // Increase qmax for greater detail, at the expense of more time.
    var p, i, j, ie, n, nalt = 0,
        m, neu;
    var sigma, e, polyalt, poly, polyneu;
    var doubleCosSigma, doubleCosSigmaQ_2, invQ = 1.0 / q;

    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    // pufferG.setColor(Color.black);
    // for q=2 the points (eigenvalues) are explicitly drawn

    for (p = 1; p < q; p += 2) {
        if (gcd(p, q) > 1) continue;
        sigma = 2.0 * Math.PI * p * invQ;
        // optimize by caching 1/q, cos(sigma), etc.
        // Is there a trig identity that will help us optimize cos(sigma * m)?
        // I don't think so, except where m=2.
        doubleCosSigma = 2.0 * Math.cos(sigma);
        doubleCosSigmaQ_2 = 2.0 * Math.cos(sigma * q * 0.5);
        nalt = 0;
        for (ie = 0; ie < MAXY + 2; ie++) {
            e = 8.0 * ie / MAXY - 4.0 - 4.0 / MAXY;
            n = 0;
            /* odd wavefunctions  */
            polyalt = 1.0;
            poly = doubleCosSigma - e;
            if (polyalt * poly < 0.0) n++;
            for (m = 2; m < q / 2; m++) {
                polyneu = (2.0 * Math.cos(sigma * m) - e) * poly - polyalt;
                if (poly * polyneu < 0.0) n++;
                polyalt = poly;
                poly = polyneu;
            }
            polyalt = 1.0;
            poly = 2.0 - e;
            if (polyalt * poly < 0.0) n++;
            polyneu = (doubleCosSigma - e) * poly - 2.0 * polyalt;
            if (poly * polyneu < 0.0) n++;
            polyalt = poly;
            poly = polyneu;
            for (m = 2; m < q / 2; m++) {
                polyneu = (2.0 * Math.cos(sigma * m) - e) * poly - polyalt;
                if (poly * polyneu < 0.0) n++;
                polyalt = poly;
                poly = polyneu;
            }
            polyneu = (doubleCosSigmaQ_2 - e) * poly - 2.0 * polyalt;
            if (poly * polyneu < 0.0) n++;
            /* even wavefunctions  */
            polyalt = 1.0;
            poly = 2.0 - e;
            if (polyalt * poly < 0.0) n++;
            polyneu = (doubleCosSigma - e) * poly - 2.0 * polyalt;
            if (poly * polyneu < 0.0) n++;
            polyalt = poly;
            poly = polyneu;
            for (m = 2; m < q / 2; m++) {
                polyneu = (2.0 * Math.cos(sigma * m) - e) * poly - polyalt;
                if (poly * polyneu < 0.0) n++;
                polyalt = poly;
                poly = polyneu;
            }
            polyneu = (doubleCosSigmaQ_2 - e) * poly - 2.0 * polyalt;
            if (poly * polyneu < 0.0) n++;

            if (n > nalt) {
                // if(neu==1) {g.drawImage(puffer,0,0,this);neu=0;}
                drawPoint(MAXX * p * invQ, MAXY - ie);
                // pufferG.drawLine(MAXX*p/q,MAXY-ie,MAXX*p/q,MAXY-ie);
            }
            nalt = n;
        }
    }
    // TODO: drawString("q= " + q);

    q += 2;
    if (keepRunning && q <= qmax) {
        // stop and give UI a chance to catch up, between iterations of q
        window.setTimeout(next, 1);
    }
}

function start() {
    canvas = document.getElementById('theCanvas');
    ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    w = canvas.scrollWidth;
    h = canvas.scrollHeight;
    MAXX = w;
    MAXY = h;

    drawPoint(MAXX / 2, MAXY * (1 - (4 + Math.sqrt(8)) / 8));
    drawPoint(MAXX / 2, MAXY * (1 - (4 - Math.sqrt(8)) / 8));

    q = 4;
    keepRunning = true;
    window.setTimeout(next, 2);
}

function stop() {
    keepRunning = false;
}

function gcd(a, b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

  • Вопрос задан
  • 72 просмотра
Пригласить эксперта
Ответы на вопрос 1
l3ftoverz
@l3ftoverz Куратор тега JavaScript
Люблю Финский металкор
window.addEventListener('resize', () => {
  // ...
});


Или сделать размер канваса в каких-то резиновых величинах.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы