我想构建类似于desmos的东西,你可以在画布中绘制图形然后移动它。
到目前为止我已经成功了,但唯一剩下的就是用户输入。
使用<input type="text">
标签我希望用户编写例如:
"5x + 2"
结果应为:
var f = 5*x + 2;
我搜索了很多方法来执行此操作,我发现的唯一内容是JavaScript中的一些Maths库和eval()
函数。最后一个非常有用,因为我可以用图中的x
值替换x
,它可以用来构建函数的图形。问题是当我想移动图表时它会滞后很多,所以这不是最好的主意。
我确信它会滞后,因为eval()
函数必须每次为画布的每个x值转换字符串大约40-50次。
我想要实现的是将字符串转换为Math函数一次,然后使用它。
有可能吗?任何人都可以请帮助
编辑1 : 这是我的功能:
function f (pixelX) {
var x = getCoordX (pixelX);
var f = 2 * x + 2;
return getPixelY(f);
}
答案 0 :(得分:4)
回答你的问题(即使这不能解决你的问题)。
你可以这样做。
var myString = "5 * x + 2";
var f = Function("x", "return " + myString);
这会从function
创建string
。第一个参数是第一个参数的名称x
,第二个参数是函数的主体(return
语句);
然后你可以这样称呼:
f(3)
,结果为17
。
请注意,您必须在等式中编写乘法,例如5 * x
,而不是5x
。
这样您只需将字符串评估为函数一次,然后您可以使用不同的参数多次调用它。
问题不在于eval
需要很长时间才能计算,但是重新绘制画布非常昂贵。尝试限制绘制数量或仅在requestAnimationFrame
回调中调用绘制函数,这样浏览器只有在准备好时才会重绘画布。
答案 1 :(得分:3)
您可以使用eval,但每个浏览器的JavaScript引擎可能会有不同的行为。
这是一个简单的查找和替换:
function solveForX(equation, xValue) {
var expanded = equation.replace(/(\d+(?:\.\d+|))x/g, '$1 * x');
return eval(expanded.replace(/x/g, xValue));
}
console.log(solveForX("5x + 2", 3)); // 17
console.log(solveForX("-4.2x + 3x", 5)); // -6
&#13;
.as-console-wrapper { top: 0; max-height: 100% !important; }
&#13;
const expFormat = '(\\d+(?:\\.\\d+|)){{@}}';
var expressionCache = {};
function lookupExpansion(v) {
if (!expressionCache[v]) {
expressionCache[v] = new RegExp(expFormat.replace(/\{\{\@\}\}/, v), 'g');
}
return expressionCache[v];
}
function toFunction(equation, variables) {
variables.forEach(variable => {
equation = equation.replace(lookupExpansion(variable), '$1 * ' + variable);
});
equation = equation.replace(/\b([a-z])([a-z])\b/g, '$1 * $2');
console.log('[DEBUG]: Expanded => ' + equation);
return Function.apply(null, variables.concat('return ' + equation));
}
// ======================== Simple ============================== //
var simpleMultiVariableFn = toFunction("x + 4x + 2y", ['x', 'y']);
console.log(simpleMultiVariableFn(3, 5)); // 25
// ======================== Advanced ============================ //
var slopeInterceptFunction = (slope, yIntercept) => {
return x => toFunction("mx + b", ['m', 'x', 'b']).call(null, slope, x, yIntercept);
};
var interceptFn = slopeInterceptFunction(1, 2); // Reusable!
console.log(interceptFn(3)); // 5
console.log(interceptFn(4)); // 6
&#13;
.as-console-wrapper { top: 0; max-height: 100% !important; }
&#13;
使用花车和负数。