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 https://forum.wickeditor.com/t/making-clones-and-moving-them/2127

https://forum.wickeditor.com/t/simple-clone-project-tutorial/3336

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.