Help with clone and clone into clone

Hi again.
It has been a while but I am now looking at wickeditor again to help with my projects at home.

I have forgoten so much and I need help with cloning clips and injecting clones and object.
Can anyone share the clone to stage/project script.

Also I was wondering if there is any info on the canvas white area size and if it has a class, id, or other handle I can use in my code to ad external scripts.

Cheers for any help

1 Like

Since I don’t have time to create a project to show you right now there are these forums posts Making clones and moving them

If you need to know anything thing that is not in these then tell me and I can make a project and show you

2 Likes

Also you can change the size of the canvas in the editor by using these - project.height and project.width. And when you export an wick editor project as an html the canvas is called but I haven’t really edited any of my html projects like that so I can’t really give you more

1 Like

The canvas has class:

Wick.Project

You can very easily do clones with

this.clone();
otherClip.clone();
project.otherOtherClip.clone();

var clonedClips = this.clips.map( (clip) => clip.clone);
var myClip = new Wick.Clip();
myClip.name = "Other Clip"

function myClipExplode() {
  var explosionClip = project.anims.clips[0].clone();
  this.opacity = 0;
  explosionClip.x = this.x;
  explosionClip.y = this.y;
  this.remove();
}

// clone into clone
// clone code
var lineage = this.lineage.filter((lin) => !lin.isRoot);

var clonedLineage lineage.map((lin) => lin.clone());

var clip = new Wick.Clip();

clip.name = lineage[lineage.length - 1].name;

clip.addObjects(clonedLineage)
1 Like

Thanks for this.

I have this now:

onEvent(‘load’, function () {
try {
// Get active frame of Layer 1
var frame = project.timeline.getChildren(‘Layer’)[0].activeFrame;

    // Prevent duplicate clones
    if (frame._children.find(c => c.name === 'cloneR_copy')) {
        console.log('cloneR_copy already exists. Skipping.');
        this.remove();
        return;
    }

    // Clone the reusable clip
    var newy = project.cloneR.clone();

    // Set clone properties to cover the stage
    newy.name = 'cloneR_copy';
    newy.x = 0;
    newy.y = 0;
    newy.originX = 0;
    newy.originY = 0;
    newy.width = 720;
    newy.height = 480;
    newy.scaleX = 1;
    newy.scaleY = 1;
    newy.opacity = 1;
    newy.rotation = 0;

    // Copy color if defined
    if ('color' in project.cloneR) {
        newy.color = project.cloneR.color;
    }

    // Add to the frame so it stays visible
    frame.addChild(newy);
    console.log('cloneR_copy added to stage.');

    // Optionally remove the loader clip
    setTimeout(() => this.remove(), 200);

} catch (err) {
    console.error('Error cloning cloneR:', err);
}

});

What are the properties of a clip and how can I make it remain after creating it like I can with a div?

Cheers
Luke

1 Like

Thanks FroggyWadd.

1 Like
onEvent(‘load’, function () {
try {
// Get active frame of Layer 1
var frame = project.timeline.getChildren(‘Layer’)[0].activeFrame;


    // Prevent duplicate clones
    if (frame._children.find(c => c.name === 'cloneR_copy')) {
        console.log('cloneR_copy already exists. Skipping.');
        this.remove();
        return;
    }

    // Clone the reusable clip
    var newy = project.cloneR.clone();

    // Set clone properties to cover the stage
    newy.name = 'cloneR_copy';
    newy.x = 0;
    newy.y = 0;
    newy.originX = 0;
    newy.originY = 0;
    newy.width = 720;
    newy.height = 480;
    newy.scaleX = 1;
    newy.scaleY = 1;
    newy.opacity = 1;
    newy.rotation = 0;

    // Copy color if defined
    if ('color' in project.cloneR) {
        newy.color = project.cloneR.color;
    }

    // Add to the frame so it stays visible
    frame.addChild(newy);
    console.log('cloneR_copy added to stage.');

    // Optionally remove the loader clip
    setTimeout(() => this.remove(), 200);

} catch (err) {
    console.error('Error cloning cloneR:', err);
}


});

Thanks moobfield,

But I keep getting - Error: Unexpected token ILLEGAL on line 4 in script “default”.
for var frame = project.timeline.getChildren(‘Layer’)[0].activeFrame;

Is there a version of wickeditor that doesn’ throe this error?

Luke

Actually the thing I am attempting is to create a dropdown combobox that drags in my scripts from a CSV on my github.

This is the csv on github:

id=“Box1”|@|code=“try { console.log(‘Box1 context:’, typeof project, typeof project.timeline); var frame = project.timeline.getChildren(‘Layer’)[0].activeFrame; if (!frame.isKeyframe) frame.convertToKeyframe(); var newClip = new Wick.Clip(); newClip.name = ‘RedBox’; newClip.x = 0; newClip.y = 0; newClip.width = project.width; newClip.height = project.height; newClip.fillColor = ‘red’; frame.addChild(newClip); frame._cachedSerializeData = frame._cachedSerializeData || {}; frame._cachedSerializeData.children = frame._cachedSerializeData.children || []; frame._cachedSerializeData.children.push(newClip.uuid); console.log(‘:white_check_mark: RedBox created with UUID:’, newClip.uuid); } catch (e) { console.error(‘:x: Error creating RedBox:’, e); }”|@|id=“Box2”|@|code=“try { console.log(‘Box2 context:’, typeof project, typeof project.timeline); var frame = project.timeline.getChildren(‘Layer’)[0].activeFrame; if (!frame.isKeyframe) frame.convertToKeyframe(); var newClip = new Wick.Clip(); newClip.name = ‘BlueBox’; newClip.x = 0; newClip.y = 0; newClip.width = project.width; newClip.height = project.height; newClip.fillColor = ‘blue’; frame.addChild(newClip); frame._cachedSerializeData = frame._cachedSerializeData || {}; frame._cachedSerializeData.children = frame._cachedSerializeData.children || []; frame._cachedSerializeData.children.push(newClip.uuid); console.log(‘:white_check_mark: BlueBox created with UUID:’, newClip.uuid); } catch (e) { console.error(‘:x: Error creating BlueBox:’, e); }”

The delimiter is the |@| and the dropdown is created like this:

onEvent(‘load’, function () {
try {
// Avoid duplicate containers
var existingContainer = document.getElementById(‘textBoxContainer’);
if (existingContainer) {
console.log(‘Text box container already exists, skipping creation’);
return;
}

    // Get container or fallback
    var container = document.querySelector('.settings-input-container');
    if (!container) {
        console.warn('settings-input-container not found, using document.body');
        container = document.body;
    }

    // Create outer div
    var textBoxDiv = document.createElement('div');
    textBoxDiv.id = 'textBoxContainer';
    textBoxDiv.className = 'toolbox-item';
    textBoxDiv.style.cssText = 'display:inline-block;background:#222;border:1px solid transparent;padding:5px;margin:0 5px;vertical-align:middle;z-index:1000;';

    // Create select
    var select = document.createElement('select');
    select.id = 'textBox';
    select.style.cssText = 'width:150px;padding:2px;font:inherit;color:#fff;background:#333;border:1px solid #444;';

    // Append select to wrapper
    var selectContainer = document.createElement('div');
    selectContainer.className = 'tool-button-select-container';
    selectContainer.appendChild(select);
    textBoxDiv.appendChild(selectContainer);

    // Add Hide button
    var hideButton = document.createElement('button');
    hideButton.innerText = 'Hide';
    hideButton.style.cssText = 'margin-left:5px;font:inherit;color:#fff;background:#222;border:1px solid transparent;padding:2px;';
    hideButton.onclick = function () {
        textBoxDiv.style.display = 'none';
    };
    textBoxDiv.appendChild(hideButton);

    // Insert dropdown
    if (container.firstChild) {
        container.insertBefore(textBoxDiv, container.firstChild);
    } else {
        container.appendChild(textBoxDiv);
    }
    console.log('✅ Dropdown container inserted');

    // CSV fetch
    const csvUrl = 'https://mygit.github.io/W-EAddons/canvasActions.csv';
    console.log('Fetching CSV from:', csvUrl);

    fetch(csvUrl)
        .then(response => {
            if (!response.ok) throw new Error('Fetch failed: ' + response.status);
            return response.text();
        })
        .then(rawCsv => {
            const clean = rawCsv.replace(/\n|\r|\u200B/g, '').trim();
            const entries = clean.split('|@|').filter(e => e.trim().length > 0);
            console.log('✅ Entries loaded:', entries);

            for (let i = 0; i < entries.length; i += 2) {
                const idEntry = entries[i];
                const codeEntry = entries[i + 1];
                if (!idEntry || !codeEntry) {
                    console.warn('⚠️ Incomplete pair at index', i);
                    continue;
                }

                const idMatch = idEntry.match(/id="([^"]+)"/);
                const codeMatch = codeEntry.match(/code="([\s\S]*)"/);

                if (idMatch && codeMatch) {
                    const id = idMatch[1];
                    var option = document.createElement('option');
                    option.value = id.toLowerCase();
                    option.text = id;
                    option.style.color = '#fff';
                    select.appendChild(option);
                } else {
                    console.warn('⚠️ Malformed entry:', idEntry, codeEntry);
                }
            }

            select.addEventListener('change', function () {
                const selectedValue = select.value;
                console.log('🔘 Selected:', selectedValue);

                const matchIndex = entries.findIndex((e, i) =>
                    i % 2 === 0 && e.toLowerCase().includes(`id="${selectedValue}"`)
                );

                if (matchIndex >= 0) {
                    const codeEntry = entries[matchIndex + 1];
                    const codeMatch = codeEntry.match(/code="([\s\S]*)"/);

                    if (codeMatch) {
                        const code = codeMatch[1];
                        console.log('▶️ Executing code for', selectedValue);
                        try {
                            eval(code);
                        } catch (evalError) {
                            console.error('❌ Eval failed for', selectedValue, evalError);
                        }
                    } else {
                        console.error('❌ No code match found for', selectedValue);
                    }
                } else {
                    console.error('❌ No matching ID for:', selectedValue);
                }
            });
        })
        .catch(error => {
            console.error('❌ CSV Load Error:', error);
        });

    // Exported project visibility
    if (window.Wick && !Wick.isEditor) {
        textBoxDiv.style.display = 'block';
    }

    this.remove(); // destroy the loader clip
} catch (e) {
    console.error('❌ Script Error:', e);
}

});

I want to create permanent clips by choosing items from the dropdown.

L

You need to clone, copy from the library or make a clip.