首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于html中的重置按钮,我有一个小问题

关于html中的重置按钮,我有一个小问题
EN

Stack Overflow用户
提问于 2022-11-05 17:59:17
回答 1查看 25关注 0票数 -1
代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>

<style>
* {
    box-sizing: border-box;
}

/* Create three unequal columns that floats next to each other */
.column {
    float: left;
    padding: 10px;
    height: 501px;
}

.left, .right {
    text-align: center;
    margin-top: 10px;
    width: 270px;
    border: 5px solid brown;
    background-color: #bbb;
    overflow-y: scroll;
    overflow-x: hidden;
    
}

.middle {
    width: 620px;
}

canvas {
    border: 1px solid black;
}
</style>

<script type="text/javascript">
function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    var dragId = ev.target.id;
    ev.dataTransfer.setData("dragId", dragId);
    wearables.forEach(wearable => {if(wearable.id === ev.target.id){
        target = wearable;
    }})

    /*alternatives syntax for reference.
    wearables.forEach(function(wearable){
        if (wearable.id === ev.target.id) {
            target = wearable;
        }
    })*/

    hintSpan.innerHTML = "Drop me onto the " +  target['dropId'] + " of the girl.";

}

function drop(ev) {
    id = ev.target.id;
    //id = ev.dataTransfer.getData("id");
    wearables.forEach(function(wearable){
        if(wearable.id === id){
        target = wearable;
    }}) 
    /* alternatives syntax for reference.
        wearables.forEach(wearable =>{if(wearable.id === id){
        target = wearable;
    }})
    */
    const mousePos = {
        x: ev.clientX - canvas.offsetLeft,
        y: ev.clientY - canvas.offsetTop
      };
    const pixel = hitCtx.getImageData(mousePos.x, mousePos.y, 1, 1).data;
      const color = `rgb(${pixel[0]},${pixel[1]},${pixel[2]})`;
      const shape = colorsHash[color];
    if(shape.id === target.dropId){
        shape['dropped'] = target.id;
    }
    redraw(false);
}
</script>
</head>

<body>

<div class="row">
  <div class="column left" id="leftDiv">
  </div>
  <div class="column middle" id="midDiv">
    <canvas id="canvas" width="600" height="500" ondrop="drop(event)" ondragover="allowDrop(event)">
        Your browser does not support canvas.
    </canvas>
    <button id="reset">Reset</button>
    &nbsp; Canvas coordinate: (<span id="xPos">x</span>, <span id="yPos">y</span>)
    &nbsp; &nbsp; <span id="hint"></span>
  </div>
  <div class="column right" id="rightDiv">
  </div>
</div>

<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const hitCanvas = document.createElement('canvas');
hitCanvas.width = 600;
hitCanvas.height = 500;
const hitCtx = hitCanvas.getContext('2d');


// uncomment this if you want to see the hidden canvas for testing or debugging
//document.getElementById('midDiv').appendChild(hitCanvas); 


const colorsHash = {};

// a function that generates a random color
function getRandomColor() {
    const r = Math.round(Math.random() * 255);
    const g = Math.round(Math.random() * 255);
    const b = Math.round(Math.random() * 255);
    return `rgb(${r},${g},${b})`;
}

// the sequence of drawing the wearables depends on the sequence of the elements listed here
const dropAreas = [
    {id: 'feet', positions: [ [250, 400], [350, 400], [350, 460], [250, 460] ], dropped: null},
    {id: 'hip',  positions: [ [240, 295], [360, 295], [360, 360], [240, 360] ], dropped: null},
    {id: 'body', positions: [ [205, 216], [400, 216], [400, 317], [205, 317] ], dropped: null},
    {id: 'head', positions: [ [210, 144], [220,  77], [300,  30], [374,  77], [390, 144] ], dropped: null},
];

// for each shape of droppable area, assign a unique random color
dropAreas.forEach(shape => {
    while (true) {
        const colorKey = getRandomColor();
        if (!colorsHash[colorKey]) {
            shape.colorKey = colorKey;
            console.log(colorKey);
            colorsHash[colorKey] = shape;
            return;
        }
    }
});

// the set of wearable items (dresses, shirts, pants, etc.)
const wearables = [
    {id: 'headwear1', pos: [222,  50], dropId: 'head', wardrobe: 'right', fPath: 'images/Headwear1.png'},
    {id: 'hat1',      pos: [179,   1], dropId: 'head', wardrobe: 'right', fPath: 'images/Hat1.png'},
    {id: 'hat2',      pos: [188,  12], dropId: 'head', wardrobe: 'right', fPath: 'images/Hat2.png'},
    {id: 'hat3',      pos: [205,   5], dropId: 'head', wardrobe: 'right', fPath: 'images/Hat3.png'},
    {id: 'dress1',    pos: [227, 210], dropId: 'body', wardrobe: 'left',  fPath: 'images/Dress1.png'},
    {id: 'dress2',    pos: [230, 215], dropId: 'body', wardrobe: 'left',  fPath: 'images/Dress2.png'},
    {id: 'shirt1',    pos: [220, 215], dropId: 'body', wardrobe: 'left',  fPath: 'images/Shirt1.png'},
    {id: 'shirt2',    pos: [246, 215], dropId: 'body', wardrobe: 'left',  fPath: 'images/Shirt2.png'},
    {id: 'pants1',    pos: [258, 300], dropId: 'hip',  wardrobe: 'right', fPath: 'images/Pants1.png'},
    {id: 'pants2',    pos: [258, 305], dropId: 'hip',  wardrobe: 'right', fPath: 'images/Pants2.png'},
    {id: 'shoe1',     pos: [251, 405], dropId: 'feet', wardrobe: 'right', fPath: 'images/Shoe1.png'},
];

const SCALE = 0.5;
var hintSpan = document.getElementById("hint");

// creates images of wearable items inside the left and right div's (representing the wardrobes)
wearables.forEach(wearable => {
    var img = new Image();
    img.id = wearable.id;
    img.src = wearable.fPath ;

    img.onload = function(){
        img.width = img.width * SCALE;
        img.draggable = true;
        img.ondragstart = drag;
        img.ondragend = function(){
            hintSpan.innerHTML ="";
            
        };
        var wardrobe = document.getElementById(wearable.wardrobe + "Div");
        var hr = document.createElement("hr");
        wardrobe.appendChild(img);
        wardrobe.appendChild(hr);
    }
});


function drawShape(context, shape) {
    context.beginPath();
    shape.positions.forEach(function(position,index){
    if (index === 0) {
        context.moveTo(position[0],position[1]);
    }
    else{
        context.lineTo(position[0],position[1]);
    }
    context.fillStyle = shape.colorKey;
    context.fill();
  });
}

// draw the shapes of droppable areas in the hidden canvas
dropAreas.forEach(shape => {
    drawShape(hitCtx, shape);
});

/* A test function which alerts a message when a mouse click is done within a droppable area on the visible canvas.
   A droppable area is predefined by drawing a colored shape in the hidden canvas.
   The width and height of the visible canvas and the hidden canvas are the same.
   We check the color of the pixel in the hidden canvas at the coordinates of the current mouse position.
   If the color can match to a shape via the colorsHash array, that means the click is upon a droppable area.
   This example is a helpful basis for you to learn how to implement the drop() function.
*/
canvas.addEventListener('click', (e) => {
    const mousePos = {
        x: e.clientX - canvas.offsetLeft,
        y: e.clientY - canvas.offsetTop
    };
    const pixel = hitCtx.getImageData(mousePos.x, mousePos.y, 1, 1).data;
    const color = `rgb(${pixel[0]},${pixel[1]},${pixel[2]})`;
    console.log(color);
    const shape = colorsHash[color];
    if (shape) {
        alert('click on shape: ' + shape.id);
    }
});


var xSpan = document.getElementById('xPos');
var ySpan = document.getElementById('yPos');

canvas.addEventListener('mousemove', (e) => {
    const mousePos = {
        x: e.clientX - canvas.offsetLeft,
        y: e.clientY - canvas.offsetTop
    };
  xSpan.innerHTML = mousePos.x;
  ySpan.innerHTML = mousePos.y;
});


// draw background

const BG_SCALE = 1.02;
var bg = new Image();
bg.onload = drawBackground;
bg.src = "images/background/4.jpg";

function drawBackground() {
    ctx.save();
    ctx.globalAlpha = 0.6;  // make the image semi-transparent
    ctx.drawImage(bg,0,0,bg.width,bg.height,canvas.width/2-bg.width*BG_SCALE/2,canvas.height/2-bg.height*BG_SCALE/2,bg.width*BG_SCALE,bg.height*BG_SCALE);
    ctx.restore();
};

// draw an image
var girl = new Image();
girl.src = "images/Girl.png";
girl.onload = drawForeground;

function drawForeground() {
    ctx.drawImage(girl,0,0,girl.width,girl.height,canvas.width/2-girl.width*SCALE/2,canvas.height/2-girl.height*SCALE/2,girl.width*SCALE,girl.height*SCALE);

    // for each droppable area, if a wearable has been dropped onto it, then draw the wearable image on canvas
    dropAreas.forEach(shape => {
        var w = shape.dropped;
        if (w) {
            //console.log(w)
            wearables.forEach(function (wearable){
            if(w === wearable.id){
                var wear = new Image();
                wear.src = wearable.fPath;
                ctx.drawImage(wear,wearable.pos[0], wearable.pos[1], wear.width*SCALE, wear.height*SCALE);
                }
            })
            }           
        });
    
}

// Implement the reset button; reset will remove all weared items on the girl
var resetButton = document.getElementById("reset");
resetButton.addEventListener('click', function(){
    redraw(true);
});


function redraw(clear) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (clear) {
    dropAreas.forEach(resetCanvas => {
         resetCanvas.dropped = null;
         console.log(resetCanvas)
        })
    /*
    for (var i = 0; i < dropAreas.length; i++) {
        if(dropAreas.dropped != null){
    dropAreas.dropped = null;
    console.log(dropAreas)
    }*/

}
    drawBackground();
    drawForeground();

}

</script>
</body>
</html>

这是我老师让我做的一个小游戏问题。我的问题是,在重绘(清除)函数中,为什么forEach函数可以工作,而不是for循环呢?

代码语言:javascript
复制
dropAreas.forEach(resetCanvas => {
         dropAreas.dropped = null;
         console.log(dropAreas.dropped)
        })

我也尝试过用这个代码来代替我目前的代码,它在我的控制台日志中显示了dropAreas.dropped的4个空值,但是没有删除女孩的图像。它在控制台中没有显示错误,但我很好奇为什么它不能工作?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-05 18:08:12

为什么forEach函数要工作,而不是for循环?

看看forEach做了什么:

代码语言:javascript
复制
dropAreas.forEach(resetCanvas => {
  resetCanvas.dropped = null;
  console.log(resetCanvas)
})

对于dropAreas数组中的每个对象,每次调用该对象resetCanvas,将该对象上的dropped属性设置为null。并将该对象记录到控制台。

然后看看您的代码做了什么:

代码语言:javascript
复制
for (var i = 0; i < dropAreas.length; i++) {
  if(dropAreas.dropped != null){
    dropAreas.dropped = null;
    console.log(dropAreas)
  }
}

对于dropAreas数组中的每个对象,将数组本身的dropped属性()设置为null。并将整个数组记录到控制台。

您第二次尝试forEach也会犯同样的错误。

您只是对该数组中的对象数组与该数组中的对象之间的区别感到困惑。对象本身有一个dropped属性,整个数组本身没有。

作为类比,把数组想象成一篮子苹果,把物体当作苹果。你不是想从苹果上咬一口,而是想从篮子里咬一口。

若要更正for循环,请使用数组上的i索引器引用单个元素:

代码语言:javascript
复制
for (var i = 0; i < dropAreas.length; i++) {
  if(dropAreas[i].dropped != null){
    dropAreas[i].dropped = null;
    console.log(dropAreas[i])
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74330201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档