From: Joe Wreschnig Date: Wed, 3 Sep 2014 23:07:23 +0000 (+0200) Subject: Initial import. X-Git-Url: https://git.yukkurigames.com/?p=yukkurigames.com.git;a=commitdiff_plain;h=cbdec08b0e2956f810b20ec5068c6033ad2a4f22 Initial import. --- cbdec08b0e2956f810b20ec5068c6033ad2a4f22 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/css/FiraMono-Bold.woff b/css/FiraMono-Bold.woff new file mode 100644 index 0000000..e81f4ae Binary files /dev/null and b/css/FiraMono-Bold.woff differ diff --git a/css/FiraMono-Regular.woff b/css/FiraMono-Regular.woff new file mode 100644 index 0000000..0a04a4f Binary files /dev/null and b/css/FiraMono-Regular.woff differ diff --git a/css/FiraSans-Bold.woff b/css/FiraSans-Bold.woff new file mode 100644 index 0000000..415071c Binary files /dev/null and b/css/FiraSans-Bold.woff differ diff --git a/css/FiraSans-BoldItalic.woff b/css/FiraSans-BoldItalic.woff new file mode 100644 index 0000000..a4129c6 Binary files /dev/null and b/css/FiraSans-BoldItalic.woff differ diff --git a/css/FiraSans-Light.woff b/css/FiraSans-Light.woff new file mode 100644 index 0000000..f05e73a Binary files /dev/null and b/css/FiraSans-Light.woff differ diff --git a/css/FiraSans-LightItalic.woff b/css/FiraSans-LightItalic.woff new file mode 100644 index 0000000..43a73e8 Binary files /dev/null and b/css/FiraSans-LightItalic.woff differ diff --git a/css/FiraSans-Medium.woff b/css/FiraSans-Medium.woff new file mode 100644 index 0000000..5627227 Binary files /dev/null and b/css/FiraSans-Medium.woff differ diff --git a/css/FiraSans-MediumItalic.woff b/css/FiraSans-MediumItalic.woff new file mode 100644 index 0000000..f381487 Binary files /dev/null and b/css/FiraSans-MediumItalic.woff differ diff --git a/css/FiraSans-Regular.woff b/css/FiraSans-Regular.woff new file mode 100644 index 0000000..9ff4044 Binary files /dev/null and b/css/FiraSans-Regular.woff differ diff --git a/css/FiraSans-RegularItalic.woff b/css/FiraSans-RegularItalic.woff new file mode 100644 index 0000000..074c220 Binary files /dev/null and b/css/FiraSans-RegularItalic.woff differ diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..70a6fe9 --- /dev/null +++ b/css/main.css @@ -0,0 +1,442 @@ +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 300; + src: local('Fira Sans OT Light'), local('Fira Sans Light'), url(FiraSans-Light.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Sans'; + font-style: italic; + font-weight: 300; + src: local('Fira Sans OT Light Italic'), local('Fira Sans Light Italic'), url(FiraSans-LightItalic.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans OT'), local('Fira Sans'), url(FiraSans-Regular.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 700; + src: local('Fira Sans OT Bold'), local('Fira Sans Bold'), url(FiraSans-Bold.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Sans'; + font-style: italic; + font-weight: 400; + src: local('Fira Sans OT Italic'), local('Fira Sans Italic'), url(FiraSans-RegularItalic.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Sans'; + font-style: italic; + font-weight: 700; + src: local('Fira Sans OT Bold Italic'), local('Fira Sans Bold Italic'), url(FiraSans-BoldItalic.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Mono'; + font-style: normal; + font-weight: 400; + src: local('Fira Mono OT'), local('Fira Mono'), url(FiraMono-Regular.woff) format('woff'); +} + +@font-face { + font-family: 'Fira Mono'; + font-style: normal; + font-weight: 700; + src: local('Fira Mono OT Bold'), local('Fira Mono Bold'), url(FiraMono-Bold.woff) format('woff'); +} + +* { + list-style-type: none; + padding: 0; + margin: 0; + font-weight: normal; + text-decoration: none; +} + +a:link, [onclick] { + text-decoration: underline; + cursor: pointer; +} + +html { + font-family: "Fira Sans", sans-serif; + font-size: 16px; + background-color: rgb(226, 192, 242); + padding: 0 1em; +} + +body { + margin: 0 auto; + color: black; + background-color: white; + max-width: 56em; + padding: 0 1em; +} + +header { + border-top: solid rgb(206, 132, 242) 0.5em; + border-bottom: solid rgb(244, 126, 126) 0.5em; + border-radius: 2.5em; + height: 6em; + transition: border-color 0.5s; + white-space: nowrap; + text-align: right; + margin: 0 auto; +} + +header img { + float: left; + height: 100%; + width: auto; +} + +header h1 { + font-size: 3em; + font-weight: normal; + margin-right: 0.25em; + display: inline-block; + height: 100%; + line-height: 2em; +} + +header:hover { + border-top-color: rgb(244, 126, 126); + border-bottom-color: rgb(206, 132, 242); +} + +img.logo { + -webkit-transition: -webkit-transform 1.5s; + transition: transform 1.5s; + -webkit-transition-delay: 0.5s; + transition-delay: 0.5s; + -webkit-transition-timing-function: cubic-bezier(0.4, 0.2, 0.5, 1.3); + transition-timing-function: cubic-bezier(0.4, 0.2, 0.5, 1.3); +} + +img.logo:hover { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); +} + +h2 { + border-top: solid rgb(206, 132, 242) 0.0625em; + border-left: solid rgb(206, 132, 242) 0.0625em; + border-radius: 1em 0 0 1em; + font-size: 1.25em; + font-weight: 300; + margin-left: -0.67em; + margin-right: -0.67em; + margin-top: 2em; + margin-bottom: 0.5em; + padding-left: 0.5em; + padding-top: 0.125em; +} + +h3 { + border-top: solid rgb(206, 132, 242) 1px; + border-left: solid rgb(206, 132, 242) 1px; + border-radius: 1.5em; + display: inline-block; + font-size: 1.125em; + font-weight: 300; + margin-bottom: 0; + margin-left: -0.89em; + padding-left: 0.67em; + padding-right: 0.67em; + white-space: nowrap; +} + +a:link, [onclick] { + color: rgb(206, 132, 242); + transition: color 0.3s; +} + +a:visited { + color: rgb(206, 132, 242); +} + +a:hover, [onclick]:hover { + color: rgb(244, 126, 126); +} + +main { + display: block; + padding: 1em; + max-width: 50em; + margin: auto; +} + +main > p { + margin: 1em 0.5em; +} + +hr { + margin-top: 0; + margin-bottom: 1em; + border-bottom: solid rgb(206, 132, 242) 1px; + height: 2em; +} + +.highlight { + border-bottom: solid rgb(206, 132, 242) 0.125em; + border-top: solid rgb(206, 132, 242) 0.125em; + border-radius: 1em; + font-weight: 300; + padding: 1em 3em; + transition: border-radius 0.3s; + box-sizing: border-box; +} + +.highlight:hover { + border-radius: 3em; +} + +.game-preview { + padding: 0; + text-align: center; + width: 100%; + max-width: 37em; + margin: auto; +} + +.game-preview > li { + position: relative; + border: solid rgb(206, 132, 242) 1px; + margin-bottom: 1.5em; + margin-top: 1em; + margin-left: 2.5em; + border-left-width: 0; + height: 8em; + transition: border-radius 0.3s, border-color 0.3s; + padding-left: 4em; + box-sizing: border-box; + border-radius: 0 4em 4em 0; +} + +.game-preview > li:nth-child(even) { + padding-left: 0; + padding-right: 4em; + margin-right: 2.5em; + margin-left: 0; + border-left-width: 1px; + border-right-width: 0; + border-radius: 4em 0 0 4em; +} + +.game-preview > li:hover { + border-radius: 0 0.25em 0.25em 0; + border-color: rgb(244, 126, 126); +} + +.game-preview > li img { + border: solid rgb(206, 132, 242) 1px; + position: absolute; + border-radius: 50%; + top: -1px; + left: -4em; + height: 8em; + width: 8em; + opacity: 0.75; + transition: border-radius 0.3s, border-color 0.3s, opacity 0.3s; + box-sizing: border-box; +} + +.game-preview > li:nth-child(even) img { + left: auto; + right: -4em; +} + +.game-preview > li:hover img { + border-radius: 0; + border-color: rgb(244, 126, 126); + opacity: 1.0; +} + +.game-preview .info { + position: relative; + height: 100%; +} + +.game-preview .info h4 { + color: inherit; + font-style: italic; + padding-left: 0.125em; + padding-right: 0.125em; + text-decoration: none; + text-align: center; + box-sizing: border-box; + padding-top: 0.25em; +} + +.game-preview li:nth-child(odd) .info h4, +.game-preview li:nth-child(odd) .info ul { + margin-right: 6.5rem; +} + +.game-preview li:nth-child(even) .info h4, +.game-preview li:nth-child(even) .info ul { + margin-right: 0em; + margin-left: 6.5rem; +} + +h4 a:link { + text-decoration: none; +} + +.game-preview .info p { + padding: 0.25em; + text-align: center; + position: absolute; + left: 0; + right: 0; + top: 50%; + transform: translateY(-50%); + -webkit-transform: translateY(-50%); + margin-top: 0.125em; +} + +.game-preview .info ul { + bottom: 0.25em; + font-size: 0.75em; + position: absolute; + right: 0.125em; + left: 0.125em; + text-align: center; +} + +.game-preview .info li:before { + content: ' ~ '; +} + +.game-preview .info li:first-child:before { + content: ''; +} + +.game-preview .info li { + display: inline; + font-weight: 300; +} + +ul.download { + border-radius: 1em; + border: solid rgb(206, 132, 242) 0.125em; + font-weight: 300; + padding: 0.5em; + margin: 1em auto; + transition: border-radius 0.3s, border-color 0.3s; + white-space: nowrap; + display: table; +} + +ul.download:hover { + border-radius: 4px; + border-color: rgb(244, 126, 126); +} + +ul.download li { + list-style-type: none; + font-size: 1.25em; + margin-bottom: 0.8em; + text-align: center; +} + +ul.download li a { + text-decoration: none; +} + +ul.download li.sh { + margin-bottom: 0; + font-size: 0.75em; + font-family: "Fira Mono", monospace; + text-align: left; +} + +ul.download li:last-child { + margin-bottom: 0; +} + +.sh:before { + content: "$ "; +} + +input { + font-family: inherit; + font-size: 1em; +} + +.copyright { + margin: auto; + text-align: justify; + width: 75%; + font-size: 0.875em; + font-weight: 400; +} + +.copyright > p { + font-size: 0.875em; + font-weight: 300; +} + +.copyright:before { + content: "Copyright ©"; +} + +pre { + border-left: solid rgba(206, 132, 242, 0.5) 8px; + border-radius: 8px; + font-family: "Fira Mono", monospace; + margin-left: 1em; + overflow: auto; + padding-left: 2em; + padding: 0.5em; + transition: background-color 0.3s, border-color 0.3s, border-radius 0.3s; +} + +pre:hover { + background-color: rgba(206, 132, 242, 0.125); + border-color: rgb(206, 132, 242); + border-radius: 16px; +} + +code { + font-family: "Fira Mono", monospace; + transition: background-color 0.3s; +} + +code:hover { + background-color: rgba(206, 132, 242, 0.125); +} + +pre code:hover { + background-color: transparent; +} + +@media (max-width: 599px) { + html { font-size: 13px; } + + .optional { + display: none; + } + + ul.download li.sh:before { + content: ""; + } + + pre { + font-size: 0.875em; + } +} + +@media (max-width: 479px) { + html { font-size: 10px; } +} + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..1555e77 Binary files /dev/null and b/favicon.ico differ diff --git a/google44dc8921b920c50f.html b/google44dc8921b920c50f.html new file mode 100644 index 0000000..c3f4c69 --- /dev/null +++ b/google44dc8921b920c50f.html @@ -0,0 +1 @@ +google-site-verification: google44dc8921b920c50f.html \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..053e87f --- /dev/null +++ b/index.html @@ -0,0 +1,283 @@ + + + + + + + Yukkuri Games + + + + +
+ +
+
+

Games

+ +

For Games

+ + +

Not Games (Yet?)

+ +

Game Jams

+ +
+ + diff --git a/logotype.png b/logotype.png new file mode 100644 index 0000000..3f3d63a Binary files /dev/null and b/logotype.png differ diff --git a/logotype_horizontal_1.png b/logotype_horizontal_1.png new file mode 100644 index 0000000..a845d24 Binary files /dev/null and b/logotype_horizontal_1.png differ diff --git a/logotype_horizontal_2.png b/logotype_horizontal_2.png new file mode 100644 index 0000000..7ae1d09 Binary files /dev/null and b/logotype_horizontal_2.png differ diff --git a/logotype_medium.png b/logotype_medium.png new file mode 100644 index 0000000..603f77c Binary files /dev/null and b/logotype_medium.png differ diff --git a/logotype_small.png b/logotype_small.png new file mode 100644 index 0000000..3d5893b Binary files /dev/null and b/logotype_small.png differ diff --git a/string-lerp/index.html b/string-lerp/index.html new file mode 100644 index 0000000..b6b1fc3 --- /dev/null +++ b/string-lerp/index.html @@ -0,0 +1,133 @@ + + + + + + + String Lerp - Yukkuri Games + + + + + +
+ + + Yukkuri Games + +

String Lerp

+
+
+

+ String Lerp is a JavaScript module to interpolate (lerp, + blend, tween) between two string values, that is, + progressively turn one string into another. It + uses Levenshtein + distance measurements along with other heuristics to try + to blend between two strings as naturally as possible. +

+ +

+ Not really sure what that means? Try it out. +

+
+
+ + +
+ +
+
+
+ Try a different string pair +
+
+

API

+

In a browser, use

+
<script type="text/javascript" src="string-lerp.js"></script>
+

In Node.js and other non-browser environments,

+
var stringLerp = require("./string-lerp")
+ +

Then,

+
var result = stringLerp.lerp(source, target, amount);
+    // `source' is the string to start with
+    // `target' is the string to finish with
+    // `amount' is an amount to edit the strings, between 0 and 1,
+    //          e.g. 0.23 = 23% from source to target
+

+ The internal diff and patch routines + are also exposed, as diffLerp is too slow for + very long strings unless you compute and store the diff list + ahead of time. +

+

License

+ +
+ + diff --git a/string-lerp/string-lerp-1.0.0.tar.gz b/string-lerp/string-lerp-1.0.0.tar.gz new file mode 100644 index 0000000..9ff0779 Binary files /dev/null and b/string-lerp/string-lerp-1.0.0.tar.gz differ diff --git a/string-lerp/string-lerp-1.0.0.zip b/string-lerp/string-lerp-1.0.0.zip new file mode 100644 index 0000000..fff9cae Binary files /dev/null and b/string-lerp/string-lerp-1.0.0.zip differ diff --git a/string-lerp/string-lerp.js b/string-lerp/string-lerp.js new file mode 100644 index 0000000..5473199 --- /dev/null +++ b/string-lerp/string-lerp.js @@ -0,0 +1,307 @@ +/* string-lerp - progressively turn one string into another + Copyright 2014 Joe Wreschnig + Licensed under the terms of the GNU GPL v2 or later + @license http://www.gnu.org/licenses/gpl-2.0.html + @source: http://yukkurigames.com/string-lerp/ +*//* + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + As additional permission, you may distribute the program or works + based on it without the copy of the GNU GPL normally required, + provided you include this license notice and a URL through which + recipients can access the corresponding source code. +*/ + +/*globals exports, Uint32Array */ + +(function (exports) { + "use strict"; + + var MAX_MATRIX_SIZE = 256 * 256; + + function costMatrix(source, target, ins, del, sub) { + /** Calculate the Levenshtein cost matrix for source and target + + If source and target are strings, they cannot contain any + astral or combining codepoints. Such data must be passed + as arrays of strings with one element per glyph. + + ins, del, and sub are the costs for insertion, deletion, + and substition respectively. Their default value is 1. If + only ins is passed, del and sub are set to the same cost. + If ins and del are passed, sub is set to the more + expensive of the two. + + The matrix is returned as a flat typed array. + + Following http://en.wikipedia.org/wiki/Levenshtein_distance + */ + ins = ins === undefined ? 1 : (ins | 0); + del = (del | 0) || ins; + sub = (sub | 0) || Math.max(ins, del); + var m = source.length + 1; + var n = target.length + 1; + var d = new Uint32Array(m * n); + var i, j; + for (i = 1; i < m; ++i) + d[n * i] = i; + for (j = 1; j < n; ++j) + d[j] = j; + for (j = 1; j < n; ++j) + for (i = 1; i < m; ++i) + if (source[i - 1] === target[j - 1]) + d[n * i + j] = d[n * (i - 1) + j - 1]; + else + d[n * i + j] = Math.min(del + d[n * (i - 1) + j ], + ins + d[n * i + j - 1], + sub + d[n * (i - 1) + j - 1]); + return d; + } + + // First, note that deletion is just substition with nothing, so + // any DEL operation can be replaced by a SUB. Second, the + // operation code *is* the necessary slice offset for applying the + // diff. + var INS = 0, SUB = 1; + + function editPath(costs, target) { + /** Given a cost matrix and a target, create an edit list */ + var path = []; + var j = target.length; + var n = j + 1; + var i = costs.length / n - 1; + while (i || j) { + var sub = (i && j) ? costs[n * (i - 1) + j - 1] : Infinity; + var del = i ? costs[n * (i - 1) + j] : Infinity; + var ins = j ? costs[n * i + j - 1] : Infinity; + if (sub <= ins && sub <= del) { + if (costs[n * i + j] !== costs[n * (i - 1) + j - 1]) + path.push([SUB, i - 1, target[j - 1]]); + --i; --j; + } else if (ins <= del) { + path.push([INS, i, target[j - 1]]); + --j; + } else { + path.push([SUB, i - 1, ""]); + --i; + } + } + return path; + } + + function diff(source, target, ins, del, sub) { + /** Create a list of edits to turn source into target + + ins, del, and sub are as passed to costMatrix. + */ + return editPath(costMatrix(source, target, ins, del, sub), target); + } + + function patchArray(diff, source) { + for (var i = 0; i < diff.length; ++i) { + var edit = diff[i]; + source.splice(edit[1], edit[0], edit[2]); + } + return source; + } + + function patchString(diff, source) { + for (var i = 0; i < diff.length; ++i) { + var edit = diff[i]; + var head = source.slice(0, edit[1]); + var tail = source.slice(edit[1] + edit[0]); + source = head + edit[2] + tail; + } + return source; + } + + function patch(diff, source) { + /** Apply a list of edits to source */ + var patcher = Array.isArray(source) ? patchArray : patchString; + return patcher(diff, source); + } + + // Matches if a string contains combining characters or astral + // codepoints (technically, the first half surrogate of an astral + // codepoint). + var MULTI = /[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uD800-\uDBFF\uFE20-\uFE2F]/; + + // Match an entire (potentially astral) codepoint and any + // combining characters following it. + var GLYPH = /[\0-\u02FF\u0370-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uD800-\uFE1F\uFE30-\uFFFF][\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uDC00-\uDFFF\uFE20-\uFE2F]*/g; + + function diffLerpAstral(source, target, amount) { + // This split is not perfect for all languages, but at least + // it won't create invalid surrogate pairs or orphaned + // combining characters. + var sourceGlyphs = source.match(GLYPH) || []; + var targetGlyphs = target.match(GLYPH) || []; + var edits = diff(targetGlyphs, sourceGlyphs, 2, 2, 3); + // The edit path works from the string end, forwards, because + // that's how Levenshtein edits work. To match LTR reading + // direction (and the behavior of fastLerp), swap the strings + // and invert the parameter when editing. + var partial = edits.slice(0, Math.round((1 - amount) * edits.length)); + return patchArray(partial, targetGlyphs).join(""); + } + + function diffLerpBasic(source, target, amount) { + var edits = diff(target, source, 2, 2, 3); + // The edit path works from the string end, forwards, because + // that's how Levenshtein edits work. To match LTR reading + // direction (and the behavior of fastLerp), swap the strings + // and invert the parameter when editing. + var partial = edits.slice(0, Math.round((1 - amount) * edits.length)); + return patchString(partial, target); + } + + function diffLerp(source, target, amount) { + /** Interpolate between two strings using edit operations + + This interpolation algorithm applys a partial edit of one + string into the other. This produces nice looking results, + but can take a significant amount of time and memory to + compute the edits. It is not recommended for strings + longer than a few hundred characters. + */ + + if (source.match(MULTI) || target.match(MULTI)) + return diffLerpAstral(source, target, amount); + else + return diffLerpBasic(source, target, amount); + } + + var NUMBERS = /(-?\d{1,20}(?:\.\d{1,20})?)/g; + + function areNumericTwins(source, target) { + /** Check if a and b differ only in numerals */ + return source.replace(NUMBERS, "0") === target.replace(NUMBERS, "0"); + } + + function nlerp(source, target, amount) { + return source + (target - source) * amount; + } + + function numericLerp(source, target, amount) { + /** Interpolate numerically between strings containing numbers + + Numbers may have a leading "-" and a single "." to mark + the decimal point, but something must be after the ".". + No other floating point syntax (e.g. 1e6) is supported. + They are treated as fixed-point values, with the point's + position itself interpolating. + + For example, numericLerp("0.0", "100".0, 0.123) === "12.3" + because the "." in "0.0" is interpreted as a decimal + point. But numericLerp("0.", "100.", 0.123) === "12." + because the strings are interpreted as integers followed + by a full stop. + + Calling this functions on strings that differ in more than + numerals gives undefined results. + */ + + var targetParts = target.split(NUMBERS); + var match; + var i = 1; + while ((match = NUMBERS.exec(source))) { + var sourcePart = match[0]; + var targetPart = targetParts[i]; + var part = nlerp(+sourcePart, +targetPart, amount); + var sourcePoint = sourcePart.indexOf("."); + var targetPoint = targetPart.indexOf("."); + var point = Math.round(nlerp( + sourcePoint >= 0 ? (sourcePart.length - 1) - sourcePoint : 0, + targetPoint >= 0 ? (targetPart.length - 1) - targetPoint : 0, + amount)); + targetParts[i] = part.toFixed(point); + i += 2; + } + return targetParts.join(""); + } + + function fastLerpAstral(source, target, amount) { + var sourceGlyphs = source.match(GLYPH) || []; + var targetGlyphs = target.match(GLYPH) || []; + var sourceLength = Math.round(sourceGlyphs.length * amount); + var targetLength = Math.round(targetGlyphs.length * amount); + var head = targetGlyphs.slice(0, targetLength); + var tail = sourceGlyphs.slice(sourceLength, sourceGlyphs.length); + head.push.apply(head, tail); + return head.join(""); + } + + function fastLerpBasic(source, target, amount) { + var sourceLength = Math.round(source.length * amount); + var targetLength = Math.round(target.length * amount); + var head = target.substring(0, targetLength); + var tail = source.substring(sourceLength, source.length); + return head + tail; + } + + function fastLerp(source, target, amount) { + /** Interpolate between two strings based on length + + This interpolation algorithm progressively replaces the + front of one string with another. This approach is fast + but does not look good when the strings are similar. + */ + + // TODO: Consider fast-pathing this even more for very large + // strings, e.g. in the megabyte range. These are large enough + // that it should be fine to just pick a codepoint and search + // for the nearest glyph start. + if (source.match(MULTI) || target.match(MULTI)) + return fastLerpAstral(source, target, amount); + else + return fastLerpBasic(source, target, amount); + } + + function lerp(source, target, amount) { + /** Interpolate between two strings as best as possible + + If the strings are identical aside from numbers in them, + they are passed through numericLerp. + + If the strings are not numbers and short, they are passed + through diffLerp. + + Otherwise, they are passed through fastLerp. + */ + source = source.toString(); + target = target.toString(); + + // Fast path for boundary cases. + if (amount === 0) return source; + if (amount === 1) return target; + + if (areNumericTwins(source, target)) + return numericLerp(source, target, amount); + + // Numeric lerps should over- and under-shoot when fed numbers + // outside 0 to 1, but other types cannot. + if (amount < 0) return source; + if (amount > 1) return target; + + var n = source.length * target.length; + var appropriate = (n && n < MAX_MATRIX_SIZE) ? diffLerp : fastLerp; + return appropriate(source, target, amount); + } + + exports.costMatrix = costMatrix; + exports.patch = patch; + exports.diff = diff; + exports.fastLerp = fastLerp; + exports.diffLerp = diffLerp; + exports.numericLerp = numericLerp; + exports.lerp = lerp; + +})(typeof exports === "undefined" ? (this.stringLerp = {}) : exports); diff --git a/thumbnails/123456789.png b/thumbnails/123456789.png new file mode 100644 index 0000000..693bcd7 Binary files /dev/null and b/thumbnails/123456789.png differ diff --git a/thumbnails/bulletml.png b/thumbnails/bulletml.png new file mode 100644 index 0000000..fa76325 Binary files /dev/null and b/thumbnails/bulletml.png differ diff --git a/thumbnails/enjoyable.png b/thumbnails/enjoyable.png new file mode 100644 index 0000000..d51c46f Binary files /dev/null and b/thumbnails/enjoyable.png differ diff --git a/thumbnails/featherfall.png b/thumbnails/featherfall.png new file mode 100644 index 0000000..ba14859 Binary files /dev/null and b/thumbnails/featherfall.png differ diff --git a/thumbnails/lagomorph.png b/thumbnails/lagomorph.png new file mode 100644 index 0000000..cbf3397 Binary files /dev/null and b/thumbnails/lagomorph.png differ diff --git a/thumbnails/matrixcreatrix.png b/thumbnails/matrixcreatrix.png new file mode 100644 index 0000000..a71cd42 Binary files /dev/null and b/thumbnails/matrixcreatrix.png differ diff --git a/thumbnails/psvzipper.png b/thumbnails/psvzipper.png new file mode 100644 index 0000000..80a5e3f Binary files /dev/null and b/thumbnails/psvzipper.png differ diff --git a/thumbnails/pwl6.png b/thumbnails/pwl6.png new file mode 100644 index 0000000..9372fd5 Binary files /dev/null and b/thumbnails/pwl6.png differ diff --git a/thumbnails/rogue1980.png b/thumbnails/rogue1980.png new file mode 100644 index 0000000..156e680 Binary files /dev/null and b/thumbnails/rogue1980.png differ diff --git a/thumbnails/string-lerp.png b/thumbnails/string-lerp.png new file mode 100644 index 0000000..bd2fa9b Binary files /dev/null and b/thumbnails/string-lerp.png differ diff --git a/thumbnails/webcart1000.png b/thumbnails/webcart1000.png new file mode 100644 index 0000000..3ad09a3 Binary files /dev/null and b/thumbnails/webcart1000.png differ