为什么javascript使用ajax创建虚假图像?

为什么javascript使用ajax创建虚假图像?,javascript,html,django,Javascript,Html,Django,首先,我必须为这个问题的代码长度道歉。它是基于Django和javascript的,我已经尽可能地剥离了它,给出了一个工作示例 挑战是使用随机数目的车创建一个合成图像-顶行的所有黑色车和底行的所有红色车 这在第一次加载页面时非常有效,但是如果我单击New Board按钮,那么顶部的行中可能会随机出现红色的rooks,底部的行中可能会出现黑色的rooks (图像是从下载的) [Edit]如果我在javascript函数displayPieceImage中添加跟踪,它会报告绘制的图像的正确数量[

首先,我必须为这个问题的代码长度道歉。它是基于Django和javascript的,我已经尽可能地剥离了它,给出了一个工作示例

挑战是使用随机数目的车创建一个合成图像-顶行的所有黑色车和底行的所有红色车

这在第一次加载页面时非常有效,但是如果我单击New Board按钮,那么顶部的行中可能会随机出现红色的rooks,底部的行中可能会出现黑色的rooks

(图像是从下载的)

[Edit]如果我在javascript函数displayPieceImage中添加跟踪,它会报告绘制的图像的正确数量[/Edit}

html

<!--  pages/home.html -->
{% load static %}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">

    <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>

</head>
<body>
    {% block content %}
        <div style="display:none;" id="pieceImages"></div>
        <p>Red:<span id="red-count"></span> Black:<span id="black-count"></span></p>
        <canvas id="top-image" style="background-color:#ffff00;"></canvas>
        <p><button id="new-board">New Board</button>
    {% endblock content %}

    <script type="text/javascript" src="{% static 'js/test.js' %}"></script>
    
</body>
</html>
视图.py

#pages/urls.py

from django.urls import path

from .views import HomePageView, NewBoard

urlpatterns = [
    path('', HomePageView.as_view()),
    path('new-board', NewBoard.as_view(), name= 'new-board'), 
]
# pages/views.py

import os
import io
import random
import base64
from PIL import Image as PilImage

from django.views.generic import View
from django.shortcuts import render
from django.http import JsonResponse
from django.conf import settings

PIECE_NAMES = ['red_rook', 'black_rook']
IMAGE_EXTENSION = 'png'

class HomePageView(View):
    template = 'pages/home.html'

    def get(self, request):
        context = {}
        return render(request, self.template, context)

class NewBoard(View):
    template = 'pages/home.html'

    def get(self, request):
        pieces = []
        red_count = random.randint(1, 5)
        black_count = random.randint(1, 5)
        for index in range(red_count):
            pieces.append('red_rook')
        for index in range(black_count):
            pieces.append('black_rook')
        context = {
            'pieces': pieces,
            'colour_length': {'red': red_count, 'black': black_count},
            'max_colour_length': max(red_count, black_count),
            'piece_images': piece_images,
        }
        return JsonResponse(context, safe=False)

def encode_image(image):
    """Return image encoded to base64 from a PIL.Image.Image."""
    io_buffer = io.BytesIO()
    image.save(io_buffer, format='PNG')
    saved_image = io_buffer.getvalue()
    encoded_image = ''.join(['data:image/jpg;base64,', base64.b64encode(saved_image).decode()])
    return encoded_image

def _get_piece_images():
    """Return a dict of encoded piece images."""
    images = {}
    piece_directory = os.sep.join([settings.STATICFILES_DIRS[0], 'images'])
    for piece in PIECE_NAMES:
        image_path = os.path.join(piece_directory, f'{piece}.{IMAGE_EXTENSION}')
        image = PilImage.open(image_path)
        piece_image = encode_image(image)
        images[piece] = piece_image
    return images

# piece_images is a dict that contains all the valid pieces
piece_images = _get_piece_images()
test.js

// static/js/test.js

// 'Constants' to define image cropping
var RAW_WIDTH = 552
var RAW_HEIGHT = 640
var SCALE = 0.1
var PIECE_WIDTH = RAW_WIDTH * SCALE
var PIECE_HEIGHT = RAW_HEIGHT * SCALE
var CANVAS_HEIGHT = 3 * PIECE_HEIGHT;

// Initialise global variables
var last_colour = '';
var colour_row = 0;
var colour_column = 0;

$(document).ready(function () {   
    var new_board_link = document.getElementById('new-board');
    new_board_link.onclick = function(){getNewBoard()};
    getNewBoard();
});

function getNewBoard() {
    $.ajax(
        {
            type: "GET",
            url: 'new-board',
            cache: false,
            success: function (context) {
                displayPieces(context);
            }
        }
    );
}

function displayPieces(context) {
    // Display all of the pieces for a given position 
    var red_count = document.getElementById('red-count');
    var black_count = document.getElementById('black-count');
    red_count.innerText = context.colour_length['red']
    black_count.innerText = context.colour_length['black']

    var max_colour_length = context.max_colour_length;
    var position_id = 'top-image'  // used to identify the position
    var ctx =  prepareCanvas(position_id, max_colour_length)
    var piece_index = 0;
    context.pieces.forEach(piece_name => {
        createModelImage (position_id, piece_index) 
        displayPieceImage (context, ctx, position_id, piece_name, piece_index)
        piece_index ++;
        }
    )
}

function prepareCanvas(position_id, max_colour_length) {
    // Create a canvas and return the canvas context (ctx) for a given position 
    canvas = document.getElementById(position_id);
    canvas.width = max_colour_length * PIECE_WIDTH;
    canvas.height = CANVAS_HEIGHT;
    var ctx = canvas.getContext('2d');
    return ctx
}

function displayPieceImage (context, ctx, position_id, piece_name, piece_index) {
    // Draw a piece and its object.
    var image_id = 'source'+position_id+piece_index
    var image = document.getElementById(image_id);
    var position = piecePosition(piece_name)
    var pos_x = position['pos_x']
    var pos_y = position['pos_y']
    image.src = context.piece_images[piece_name];
    image.addEventListener('load', e => {    
        ctx.drawImage(image, 0, 0, RAW_WIDTH, RAW_HEIGHT, pos_x, pos_y, PIECE_WIDTH, PIECE_HEIGHT);
    });
}

function piecePosition(piece_name) {
    // Return the position of the piece relative to the canvas.
    var piece_colour = piece_name.substring(0, 1);
    if (last_colour != piece_colour) {
        last_colour = piece_colour;
        colour_column = -1;
    }
    colour_row = 'br'.indexOf(piece_colour.substr(0, 1));
    colour_column ++;
    position = {'pos_x': colour_column * PIECE_WIDTH, 'pos_y': colour_row * PIECE_HEIGHT}
    return position
}

function createModelImage (position_id, index) {
    // Add a piece image to the hidden element 'pieceImages'
    var pieceImages = document.getElementById('pieceImages');
    var img = document.createElement('img');
    img.id = 'source'+position_id+index;
    pieceImages.appendChild(img);
}

问题很简单。在函数
createModelImage
中,您使用id
PieceMages
将图像添加到div。在创建新板时,您永远不会从div中删除这些图像。因此,会使用带有id的旧图像,而不是应该使用的图像标记。相反,您应该删除这些旧ima制作新电路板时的ge标签:

function displayPieces(context) {
    document.getElementById('pieceImages').innerHTML = '';
    // Your original code here
}