【问题标题】:JavaScript Painting Application Save SlotsJavaScript 绘画应用程序保存槽
【发布时间】:2014-02-11 23:01:21
【问题描述】:

我已经在 J​​avaScript 中创建了一个绘画应用程序,现在正尝试包含一些保存槽,用户可以在其中保存和加载他们的作品(使用 localStorage())。我已经设法理清了实际的保存/加载机制,但是遇到了加载界面的问题。

在其中,我有八个较小的画布元素(每个保存槽一个),我想显示保存时主画布上显示的内容的图像 - 保存时将加载的内容的快照图像被恢复(即使页面关闭,这些插槽也保持不变)。我的问题是我无法让较小的画布元素显示正确的图像 - 图像仅显示在第一个中,并且不会移动到第二个,依此类推。

目前,我已经为每个小画布分配了自己的画布和上下文变量,如下所示:

var slot1 = $('#slot01');
var context1 = slot1.get(0).getContext('2d');
var slot2 = $('#slot02');
var context2 = slot2.get(0).getContext('2d');
var slot3 = $('#slot03');
var context3 = slot3.get(0).getContext('2d');
var slot4 = $('#slot04');

使我能够单独访问每一个。我正在使用if 语句来检测是否设置了localStorage() 键,然后使用它来查看是否应该填充下一个插槽。不幸的是,这种方法似乎不起作用。

if(localStorage.getItem("painting01"))
    {
        var painting = new Image;
        painting.src = localStorage.getItem("painting");
        context2.drawImage(painting, 0, 0);

        var painting02 = localStorage.setItem("painting02", slot2.toDataURL("image/png"));
    }
else if(localStorage.getItem("painting02"))
    {
        var painting = new Image;
        painting.src = localStorage.getItem("painting");
        context3.drawImage(painting, 0, 0);

        var painting03 = localStorage.setItem("painting03", slot3.toDataURL("image/png"));
    }
else if(localStorage.getItem("painting03"))
    {
        var painting = new Image;
        painting.src = localStorage.getItem("painting");
        context4.drawImage(painting, 0, 0);

        var painting04 = localStorage.setItem("painting04", slot4.toDataURL("image/png"));
    }

我不确定我是否走在正确的道路上,或者在这个问题上走的是完全错误的方向,但我希望能得到一些帮助来解决这个问题 - 我希望我已经解释得足够清楚了。 谢谢!

【问题讨论】:

    标签: javascript jquery canvas save local-storage


    【解决方案1】:

    您正在使用 8 个类似的画布:8 是一个足够高的数字,可以使用数组、更通用的循环/函数甚至某些类,我认为您应该通过这种方式澄清代码来进行调试。

    下面我只是举一个小例子来说明我的意思:

    这是将“加载”插槽的代码:

    // store all your slot data here
    var slots     = [];
    var slotCount = 8 ;
    
    // retrieve all slots.
    for (var i=0; i<slotCount; i++) slots[i] = getSlot(i);
    
    // retrieve the i-th slot.
    function getSlot(i) { 
       var thisCanvas = $('#slot' + i.toFixed(2)); // retrieve canvas
       var thisContext = thisSlot.get(0).getContext('2d');  // retrive canvas's context2d
       var thisStoredImage = localStorage.getItem("painting" + i.toFixed(2) ); // check localstorage
       // build one object with all this data and return it
       return { index : i , 
                canvas : thisCanvas, 
                context : thisContext, 
                storedImage : thisStoredImage };
    }
    

    这些插槽的一些使用示例:

    // returns a free slot if found, or null if none found.
    function findFreeSlot() {
        for (var i = 0; i<slotCount; i++) { // iterate through slots.
            var thisSlot = slots[i];
            if (!thisSlot.storedImage) return thisSlot;
        }
        return null;
    }
    
    // add event handler for all slots
    function hookAllSlots() {
        for (var i = 0; i<slotCount; i++) {
            var thisSlot = slots[i];
            thisSlot.canvas.addEventListener('click', slotClicked.bind(null, thisSlot) );
        }
    }
    
     // function called when [slot] is clicked.
     function slotClicked(slot) {
          // here, slot is the slot that was last clicked.
          // you have access slot.index, slot.canvas, ...
     }
    

    【讨论】:

    • 您好,感谢您的帮助。您是否介意更详细地说明代码的工作原理,以便我更好地了解如何调整它?
    • mmm...我不确定如何进一步澄清,因为无论如何,以我的编程风格,我会创建一个“Slot”类和一个“SlotCollection”类,并拥有所有对象-面向...我在这里所做的是将一堆变量替换为包含对象的数组。数组的每个对象都包含有关插槽的所有数据。然后您可以将此插槽数据发送到任何函数。我不知道如何进一步解释,显然我可以重构您的应用程序,使其 100% 干净,但它不是免费的。很难回答“如何适应”,因为我不知道你的应用程序的其余部分。干杯。
    • 我添加了一些 cmets 希望对您有所帮助。
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多