diff --git a/README.md b/README.md index ca7aece86..3b455d67a 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,8 @@ If you want to play around with different blending modes, you can add a `blend: If you need a layers to have a different opacity then you can add the `opacity: 0.7` field to the layersOrder `options` object as well. +If you want to have a layer _ignored_ in the DNA uniqueness check, you can set `bypassDNA: true` in the `options` object. This has the effect of making sure the rest of the traits are unique while not considering the `Background` Layers as traits, for example. The layers _are_ included in the final image. + To use a different metadata attribute name you can add the `displayName: "Awesome Eye Color"` to the `options` object. All options are optional and can be addes on the same layer if you want to. Here is an example on how you can play around with both filter fields: @@ -120,7 +122,11 @@ const layerConfigurations = [ { growEditionSizeTo: 5, layersOrder: [ - { name: "Background" }, + { name: "Background" , { + options: { + bypassDNA: false; + } + }}, { name: "Eyeball" }, { name: "Eye color", diff --git a/src/config.js b/src/config.js index b000f97b4..06dc4c5bf 100644 --- a/src/config.js +++ b/src/config.js @@ -30,7 +30,11 @@ const layerConfigurations = [ { growEditionSizeTo: 5, layersOrder: [ - { name: "Background" }, + { name: "Background", + options: { + bypassDNA: true + } + }, { name: "Eyeball" }, { name: "Eye color" }, { name: "Iris" }, diff --git a/src/main.js b/src/main.js index 989c82ab2..97c7f44a4 100644 --- a/src/main.js +++ b/src/main.js @@ -66,7 +66,8 @@ const getRarityWeight = (_str) => { }; const cleanDna = (_str) => { - var dna = Number(_str.split(":").shift()); + const withoutOptions = removeQueryStrings(_str) + var dna = Number(withoutOptions.split(":").shift()); return dna; }; @@ -107,6 +108,10 @@ const layersSetup = (layersOrder) => { layerObj.options?.["opacity"] != undefined ? layerObj.options?.["opacity"] : 1, + bypassDNA: + layerObj.options?.["bypassDNA"] !== undefined + ? layerObj.options?.["bypassDNA"] + : false })); return layers; }; @@ -231,8 +236,49 @@ const constructLayerToDna = (_dna = "", _layers = []) => { return mappedDnaToLayers; }; +/** + * In some cases a DNA string may contain optional query parameters for options + * such as bypassing the DNA isUnique check, this function filters out those + * items without modifying the stored DNA. + * + * @param {String} _dna New DNA string + * @returns new DNA string with any items that should be filtered, removed. + */ +const filterDNAOptions = (_dna) => { + const dnaItems = _dna.split(DNA_DELIMITER) + const filteredDNA = dnaItems.filter(element => { + const query = /(\?.*$)/; + const querystring = query.exec(element); + if (!querystring) { + return true + } + const options = querystring[1].split("&").reduce((r, setting) => { + const keyPairs = setting.split("="); + return { ...r, [keyPairs[0]]: keyPairs[1] }; + }, []); + + return options.bypassDNA + }) + + return filteredDNA.join(DNA_DELIMITER) +} + +/** + * Cleaning function for DNA strings. When DNA strings include an option, it + * is added to the filename with a ?setting=value query string. It needs to be + * removed to properly access the file name before Drawing. + * + * @param {String} _dna The entire newDNA string + * @returns Cleaned DNA string without querystring parameters. + */ +const removeQueryStrings = (_dna) => { + const query = /(\?.*$)/; + return _dna.replace(query, '') +} + const isDnaUnique = (_DnaList = new Set(), _dna = "") => { - return !_DnaList.has(_dna); + const _filteredDNA = filterDNAOptions(_dna); + return !_DnaList.has(_filteredDNA); }; const createDna = (_layers) => { @@ -249,7 +295,7 @@ const createDna = (_layers) => { random -= layer.elements[i].weight; if (random < 0) { return randNum.push( - `${layer.elements[i].id}:${layer.elements[i].filename}` + `${layer.elements[i].id}:${layer.elements[i].filename}${layer.bypassDNA? '?bypassDNA=true' : ''}` ); } } @@ -364,7 +410,7 @@ const startCreating = async () => { )}` ); }); - dnaList.add(newDna); + dnaList.add(filterDNAOptions(newDna)); editionCount++; abstractedIndexes.shift(); } else {