ย้าย HTML5 Canvas พร้อมภาพพื้นหลัง

ฉันต้องการเห็นภาพไดอะแกรมขนาดใหญ่ที่วาดบนผืนผ้าใบ HTML5 ตามที่อธิบายไว้ด้านล่าง ลองจินตนาการถึงแผนที่โลก เป็นไปไม่ได้ที่จะแสดงภาพทั้งหมดพร้อมๆ กันด้วยรายละเอียดที่ "เหมาะสม" ดังนั้น บนผืนผ้าใบของฉัน ฉันอยากจะเลื่อนเมาส์ไปเหนือมันเพื่อดูประเทศอื่นๆ ที่ไม่สามารถมองเห็นได้

ไม่มีใครรู้วิธีใช้การแพนแบบนี้บนผืนผ้าใบ HTML5 หรือไม่ คุณสมบัติอีกอย่างหนึ่งคือการซูมเข้าและออก

canvas diagramฉันได้เห็นตัวอย่างบางส่วนแล้ว แต่ฉันไม่สามารถทำให้มันทำงานได้หรือไม่ได้ตอบคำถามของฉัน .

ขอบคุณล่วงหน้า!


person Emanuel    schedule 05.08.2013    source แหล่งที่มา
comment
โดยพื้นฐานแล้วคุณต้องการที่จะย้าย (แพน) รูปภาพภายในวัตถุผ้าใบ HTML5 ซึ่งควบคุมด้วยเมาส์หรือไม่? ซูมเข้า/ออกด้วย   -  person Eric    schedule 05.08.2013
comment
อย่างแน่นอน! ฉันอยากจะลากภาพไปรอบๆ   -  person Emanuel    schedule 05.08.2013


คำตอบ (2)


เพื่อให้ได้ฟังก์ชันการแพนกล้องที่มีช่องมองภาพ คุณจะต้องดำเนินการวาดสองครั้ง การดำเนินการแบบเต็มและการตัดหนึ่งรายการ

เพื่อให้ได้ผลลัพธ์นี้ คุณสามารถทำสิ่งต่อไปนี้ (ดูโค้ดเต็มที่นี่):

ตั้งค่าตัวแปร:

var ctx = canvas.getContext('2d'),

    ix = 0, iy = 0,           /// image position
    offsetX = 0, offsetY = 0, /// current offsets
    deltaX, deltaY,           /// deltas from mouse down
    mouseDown = false,        /// in mouse drag
    img = null,               /// background
    rect,                     /// rect position
    rectW = 200, rectH = 150; /// size of highlight area

ตั้งค่าฟังก์ชั่นหลักที่คุณใช้กำหนดขนาดตามขนาดหน้าต่าง (รวมถึงการปรับขนาดด้วย):

/// calc canvas w/h in relation to window as well as
/// setting rectangle in center with the pre-defined
/// width and height
function setSize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    rect = [canvas.width * 0.5 - rectW * 0.5,
            canvas.height * 0.5 - rectH * 0.5,
            rectW, rectH]
    update();
}

/// window resize so recalc canvas and rect
window.onresize = setSize;

ฟังก์ชันหลักในสิ่งนี้คือฟังก์ชันการวาด ที่นี่เราวาดภาพในตำแหน่งที่คำนวณโดยการเลื่อนเมาส์ (ดูหัวข้อถัดไป)

  • ขั้นตอนแรกในการทำให้ภาพดูจืดจางลงคือตั้งค่าอัลฟ่าลงประมาณ 0.2 (คุณสามารถวาดรูปสี่เหลี่ยมผืนผ้าโปร่งใสด้านบนก็ได้ แต่จะมีประสิทธิภาพมากกว่า)
  • จากนั้นจึงวาดภาพให้สมบูรณ์
  • รีเซ็ตอัลฟ่า
  • วาดช่องมองภาพโดยใช้การตัดที่มีการชดเชยที่แก้ไขแล้วสำหรับแหล่งที่มา

-

/// main draw
function update() {
    if (img === null) return;

    /// limit x/y as drawImage cannot draw with negative
    /// offsets for clipping
    if (ix + offsetX > rect[0]) ix = rect[0] - offsetX;
    if (iy + offsetY > rect[1]) iy = rect[1] - offsetY;

    /// clear background to clear off garbage
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    /// make everything transparent
    ctx.globalAlpha = 0.2;

    /// draw complete background
    ctx.drawImage(img, ix + offsetX, iy + offsetY);

    /// reset alpha as we need opacity for next draw
    ctx.globalAlpha = 1;

    /// draw a clipped version of the background and
    /// adjust for offset and image position
    ctx.drawImage(img, -ix - offsetX + rect[0],  /// sx
                       -iy - offsetY + rect[1],  /// sy
                       rect[2], rect[3],         /// sw/h

                       /// destination
                       rect[0], rect[1], rect[2], rect[3]);

    /// make a nice sharp border by offsetting it half pixel
    ctx.strokeRect(rect[0] + 0.5, rect[1] + 0.5, rect[2], rect[3]);
}

ตอนนี้มันเป็นเรื่องของการจัดการเมาส์ลง เลื่อนและขึ้น และคำนวณออฟเซ็ต -

ในเมาส์ด้านล่าง เราจะจัดเก็บตำแหน่งเมาส์ปัจจุบันที่เราจะใช้สำหรับการคำนวณเดลตาเมื่อเลื่อนเมาส์:

canvas.onmousedown = function(e) {

    /// don't do anything until we have an image
    if (img === null) return;

    /// correct mouse pos
    var coords = getPos(e),
        x = coords[0],
        y = coords[1];

    /// store current position to calc deltas
    deltaX = x;
    deltaY = y;

    /// here we go..
    mouseDown = true;
}

ที่นี่เราใช้สันดอนเพื่อหลีกเลี่ยงการกระโดดของภาพโดยตั้งค่ามุมไปที่ตำแหน่งเมาส์ เดลต้าจะถูกถ่ายโอนเป็นออฟเซ็ตไปยังฟังก์ชัน update:

canvas.onmousemove = function(e) {

    /// in a drag?
    if (mouseDown === true) {

        var coords = getPos(e),
            x = coords[0],
            y = coords[1];

        /// offset = current - original position
        offsetX = x - deltaX;
        offsetY = y - deltaY; 

        /// redraw what we have so far
        update();
    }
}

และสุดท้ายเมื่อเลื่อนเมาส์ขึ้น เราทำให้ออฟเซ็ตเป็นส่วนถาวรของตำแหน่งรูปภาพ:

document.onmouseup = function(e) {

    /// was in a drag?
    if (mouseDown === true) {
        /// not any more!!!
        mouseDown = false;

        /// make image pos. permanent
        ix += offsetX;
        iy += offsetY;

        /// so we need to reset offsets as well
        offsetX = offsetY = 0;
    }
}

สำหรับการซูมผืนผ้าใบ ฉันเชื่อว่าสิ่งนี้ได้รับคำตอบแล้วในโพสต์นี้ - คุณควรจะสามารถรวมสิ่งนี้เข้ากับคำตอบที่ให้ไว้ที่นี่:
ซูม Canvas ไปที่เคอร์เซอร์ของเมาส์

person Community    schedule 05.08.2013
comment
คุณโพสต์คำตอบอย่างแน่นอน ขอบคุณมาก! ตอนนี้ฉันมีช่องว่างภายในที่ใช้งานได้ แต่เกี่ยวกับการซูม ฉันเห็นโพสต์นั้นแล้ว แต่ในกรณีนั้น เมื่อใดก็ตามที่เราต้องการซูม เราจะต้องวาดรูปพื้นหลังทั้งหมดใหม่ (แปล มาตราส่วน) ใช่ไหม? ฉันพยายามเล่นกับฟังก์ชัน DrawImage เพื่อให้สามารถซูมได้โดยการถ่ายภาพพื้นหลังให้มากขึ้น วิธีนี้จะช่วยหลีกเลี่ยงการวาดพื้นหลังใหม่ สิ่งนี้จะเป็นไปได้ไหม? - person Emanuel; 06.08.2013
comment
@Emanuel คุณหมายถึงชอบใช้สี่เหลี่ยมเป็นแว่นขยายเหรอ? หากเป็นเช่นนั้น คุณสามารถดำเนินการดังนี้: jsfiddle.net/AbdiasSoftware/Us9nH/3 - person ; 06.08.2013
comment
ขอบคุณมากอีกครั้งสำหรับความช่วยเหลือของคุณ! มันก็เหมือนกับที่คุณโพสต์จริงๆ แต่ผมอยากซูมเข้า แต่ก็ซูมออกตามการเลื่อนเมาส์ด้วย แต่คุณสังเกตเห็นซอตัวแรกของคุณไหมว่าเมื่อคุณหมุนเมาส์ไปรอบๆ จะมีเอฟเฟกต์การขยายเมื่อคุณเลื่อนไปทางส่วนล่างของแผนที่ ขอบคุณ! - person Emanuel; 07.08.2013
comment
จริงๆ แล้ว ฉันคิดว่าเอฟเฟกต์นี้น่าจะมาถึงจุดสิ้นสุดของภาพแล้ว กรอบไฮไลต์ไปถึงจุดสิ้นสุดของภาพและปรับความกว้างของกรอบที่ถ่ายให้เป็นสี่เหลี่ยมเพื่อให้เกิดเอฟเฟกต์ที่ยืดออก - person Emanuel; 07.08.2013
comment
@KenFyrstenberg: ท่านฉันจะมีฟังก์ชั่นที่เคลื่อนย้ายได้เฉพาะบนผืนผ้าใบได้อย่างไร? และฉันจะซ่อนภาพส่วนเกินที่เกี่ยวข้องกับผืนผ้าใบได้อย่างไร? - person YouSer; 06.06.2014
comment
การวาด Img ในแต่ละครั้งไม่มีประสิทธิภาพหรือไม่ - ไม่ใช้การแปลจะดีกว่าไหม - person Jona; 13.02.2021

หากต้องการทำสิ่งที่คุณร้องขอ มันเป็นเพียงกรณีของการมีผืนผ้าใบ 2 ใบ โดยแต่ละผืนมีดัชนี z ที่แตกต่างกัน ผืนผ้าใบผืนหนึ่งเล็กกว่าอีกผืนหนึ่งและกำหนดตำแหน่งไว้ที่ x และ y ของเมาส์

จากนั้นคุณเพียงแค่แสดงภาพที่ถูกต้องบนผืนผ้าใบขนาดเล็กตามตำแหน่งของ x และ y บนผืนผ้าใบขนาดเล็กที่สัมพันธ์กับผืนผ้าใบขนาดใหญ่

อย่างไรก็ตาม คำถามของคุณคือการขอวิธีแก้ปัญหาเฉพาะ ซึ่งหากไม่มีคนทำและพวกเขาเต็มใจที่จะทิ้งโค้ดของพวกเขา คุณจะพบว่ามันยากที่จะได้รับคำตอบที่สมบูรณ์ ฉันหวังว่ามันจะเป็นไปด้วยดี

person Malcor    schedule 05.08.2013