diff --git a/modules/canvaskit/canvaskit/extra.html b/modules/canvaskit/canvaskit/extra.html
index 91c8738ec3..d41ff72e90 100644
--- a/modules/canvaskit/canvaskit/extra.html
+++ b/modules/canvaskit/canvaskit/extra.html
@@ -1,4 +1,4 @@
-
+
CanvasKit Extra features (Skia via Web Assembly)
@@ -183,8 +183,9 @@
}
const context = CanvasKit.currentContext();
const canvas = surface.getCanvas();
+ canvas.translate(250, 450);
- const particles = CanvasKit.MakeParticles(JSON.stringify(snowfall));
+ const particles = CanvasKit.MakeParticles(JSON.stringify(curves));
particles.start(Date.now() / 1000.0, true);
function drawFrame(canvas) {
@@ -197,58 +198,35 @@
surface.requestAnimationFrame(drawFrame);
}
-const snowfall = {
- "MaxCount": 4096,
+const curves = {
+ "MaxCount": 1000,
"Drawable": {
"Type": "SkCircleDrawable",
- "Radius": 1
+ "Radius": 2
},
"EffectCode": [
"void effectSpawn(inout Effect effect) {",
- " effect.rate = 30;",
- "}",
- "",
- "void effectUpdate(inout Effect effect) {",
+ " effect.rate = 200;",
+ " effect.color = float4(1, 0, 0, 1);",
"}",
""
],
"Code": [
"void spawn(inout Particle p) {",
- " p.lifetime = 10;",
- " p.vel.y = 10 + rand * 20;",
- " p.vel.x = -5 + 10 * rand;",
- " p.pos.x = rand * 500;",
+ " p.lifetime = 3 + rand;",
+ " p.vel.y = -50;",
"}",
"",
"void update(inout Particle p) {",
- " p.scale = size(p.age);",
+ " float w = mix(15, 3, p.age);",
+ " p.pos.x = sin(radians(p.age * 320)) * mix(25, 10, p.age) + mix(-w, w, rand);",
+ " if (rand < 0.5) { p.pos.x = -p.pos.x; }",
+ "",
+ " p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand)) / 255;",
"}",
""
],
- "Bindings": [
- {
- "Type": "SkCurveBinding",
- "Name": "size",
- "Curve": {
- "XValues": [],
- "Segments": [
- {
- "Type": "Cubic",
- "Ranged": true,
- "Bidirectional": false,
- "A0": 10,
- "B0": 10,
- "C0": 10,
- "D0": 0,
- "A1": 10,
- "B1": 0,
- "C1": 0,
- "D1": 0
- }
- ]
- }
- }
- ]
+ "Bindings": []
};
function SurfaceAPI1(CanvasKit) {
diff --git a/modules/particles/include/SkCurve.h b/modules/particles/include/SkCurve.h
deleted file mode 100644
index c308aa563e..0000000000
--- a/modules/particles/include/SkCurve.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-* Copyright 2019 Google LLC
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#ifndef SkCurve_DEFINED
-#define SkCurve_DEFINED
-
-#include "include/core/SkColor.h"
-#include "include/private/SkTArray.h"
-
-class SkFieldVisitor;
-class SkRandom;
-
-/**
- * SkCurve implements a keyframed 1D function, useful for animating values over time. This pattern
- * is common in digital content creation tools. An SkCurve might represent rotation, scale, opacity,
- * or any other scalar quantity.
- *
- * An SkCurve has a logical domain of [0, 1], and is made of one or more SkCurveSegments.
- * Each segment describes the behavior of the curve in some sub-domain. For an SkCurve with N
- * segments, there are (N - 1) intermediate x-values that subdivide the domain. The first and last
- * x-values are implicitly 0 and 1:
- *
- * 0 ... x[0] ... x[1] ... ... 1
- * Segment_0 Segment_1 ... Segment_N-1
- *
- * Each segment describes a function over [0, 1] - x-values are re-normalized to the segment's
- * domain when being evaluated. The segments are cubic polynomials, defined by four values (fMin).
- * These are the values at x=0 and x=1, as well as control points at x=1/3 and x=2/3.
- *
- * For segments with fConstant == true, only the first value is used (fMin[0]).
- *
- * Each segment has two additional features for creating interesting (and varied) animation:
- * - A segment can be ranged. Ranged segments have two sets of coefficients, and a random value
- * taken from the particle's SkRandom is used to lerp betwen them. Typically, the SkRandom is
- * in the same state at each call, so this value is stable. That causes a ranged SkCurve to
- * produce a single smooth cubic function somewhere within the range defined by fMin and fMax.
- * - A segment can be bidirectional. In that case, after a value is computed, it will be negated
- * 50% of the time.
- */
-
-enum SkCurveSegmentType {
- kConstant_SegmentType,
- kLinear_SegmentType,
- kCubic_SegmentType,
-};
-
-struct SkCurveSegment {
- float eval(float x, float t, bool negate) const;
- void visitFields(SkFieldVisitor* v);
-
- void setConstant(float c) {
- fType = kConstant_SegmentType;
- fRanged = false;
- fMin[0] = c;
- }
-
- float fMin[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- float fMax[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
- int fType = kConstant_SegmentType;
- bool fRanged = false;
- bool fBidirectional = false;
-};
-
-struct SkCurve {
- SkCurve(float c = 0.0f) {
- fSegments.push_back().setConstant(c);
- }
-
- float eval(float x, SkRandom& random) const;
- void visitFields(SkFieldVisitor* v);
-
- // It should always be true that (fXValues.count() + 1) == fSegments.count()
- SkTArray fXValues;
- SkTArray fSegments;
-};
-
-/**
- * SkColorCurve is similar to SkCurve, but keyframes 4D values - specifically colors. Because
- * negative colors rarely make sense, SkColorCurves do not support bidirectional segments, but
- * support all other features (including cubic interpolation).
- */
-
-struct SkColorCurveSegment {
- SkColorCurveSegment() {
- for (int i = 0; i < 4; ++i) {
- fMin[i] = { 1.0f, 1.0f, 1.0f, 1.0f };
- fMax[i] = { 1.0f, 1.0f, 1.0f, 1.0f };
- }
- }
-
- SkColor4f eval(float x, float t) const;
- void visitFields(SkFieldVisitor* v);
-
- void setConstant(SkColor4f c) {
- fType = kConstant_SegmentType;
- fRanged = false;
- fMin[0] = c;
- }
-
- SkColor4f fMin[4];
- SkColor4f fMax[4];
-
- int fType = kConstant_SegmentType;
- bool fRanged = false;
-};
-
-struct SkColorCurve {
- SkColorCurve(SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f }) {
- fSegments.push_back().setConstant(c);
- }
-
- SkColor4f eval(float x, SkRandom& random) const;
- void visitFields(SkFieldVisitor* v);
-
- SkTArray fXValues;
- SkTArray fSegments;
-};
-
-#endif // SkCurve_DEFINED
diff --git a/modules/particles/include/SkParticleBinding.h b/modules/particles/include/SkParticleBinding.h
index 184bb07f8d..39665f6af0 100644
--- a/modules/particles/include/SkParticleBinding.h
+++ b/modules/particles/include/SkParticleBinding.h
@@ -14,8 +14,6 @@
#include
-struct SkCurve;
-struct SkColorCurve;
class SkParticleEffect;
class SkParticleEffectParams;
class SkRandom;
@@ -60,14 +58,6 @@ public:
* each kind of binding is described below.
*/
- // Binds an SkCurve to an effect's SkSL. The curve is a one-dimensional function, described
- // in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a single float value.
- static sk_sp MakeCurve(const char* name, const SkCurve& curve);
-
- // Binds an SkColorCurve to an effect's SkSL. The curve is a one-dimensional, function,
- // described in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a float4 value.
- static sk_sp MakeColorCurve(const char* name, const SkColorCurve& curve);
-
// Binds an SkPath to an effect's SkSL. The path is specified using SVG syntax. It is called
// in the SkSL as 'name(t)'. 't' is a normalized distance along the path. This returns a float4
// value, containing the position in .xy, and the normal in .zw.
diff --git a/modules/particles/include/SkReflected.h b/modules/particles/include/SkReflected.h
index 9ad3520161..beb7291844 100644
--- a/modules/particles/include/SkReflected.h
+++ b/modules/particles/include/SkReflected.h
@@ -15,7 +15,6 @@
#include // std::function
#include
-struct SkCurve;
class SkFieldVisitor;
struct SkPoint;
class SkString;
@@ -163,9 +162,6 @@ public:
};
virtual void visit(const char*, int&, const EnumStringMapping*, int count) = 0;
- // Specific virtual signature for SkCurve, to allow for heavily customized UI in SkGuiVisitor.
- virtual void visit(const char* name, SkCurve& c);
-
// Default visit function for structs with no special behavior. It is assumed that any such
// struct implements visitFields(SkFieldVisitor*) to recursively visit each of its fields.
template
diff --git a/modules/particles/particles.gni b/modules/particles/particles.gni
index 49a313ab57..bd0bce1f50 100644
--- a/modules/particles/particles.gni
+++ b/modules/particles/particles.gni
@@ -7,7 +7,6 @@
_src = get_path_info("src", "abspath")
skia_particle_sources = [
- "$_src/SkCurve.cpp",
"$_src/SkParticleBinding.cpp",
"$_src/SkParticleDrawable.cpp",
"$_src/SkParticleEffect.cpp",
diff --git a/modules/particles/src/SkCurve.cpp b/modules/particles/src/SkCurve.cpp
deleted file mode 100644
index f54ab31166..0000000000
--- a/modules/particles/src/SkCurve.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-* Copyright 2019 Google LLC
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
-
-#include "include/utils/SkRandom.h"
-#include "modules/particles/include/SkCurve.h"
-#include "modules/particles/include/SkReflected.h"
-
-constexpr SkFieldVisitor::EnumStringMapping gCurveSegmentTypeMapping[] = {
- { kConstant_SegmentType, "Constant" },
- { kLinear_SegmentType, "Linear" },
- { kCubic_SegmentType, "Cubic" },
-};
-
-static SkColor4f operator+(SkColor4f c1, SkColor4f c2) {
- return { c1.fR + c2.fR, c1.fG + c2.fG, c1.fB + c2.fB, c1.fA + c2.fA };
-}
-
-static SkColor4f operator-(SkColor4f c1, SkColor4f c2) {
- return { c1.fR - c2.fR, c1.fG - c2.fG, c1.fB - c2.fB, c1.fA - c2.fA };
-}
-
-template
-static T eval_cubic(const T* pts, float x) {
- float ix = (1 - x);
- return pts[0]*(ix*ix*ix) + pts[1]*(3*ix*ix*x) + pts[2]*(3*ix*x*x) + pts[3]*(x*x*x);
-}
-
-template
-static T eval_segment(const T* pts, float x, int type) {
- switch (type) {
- case kLinear_SegmentType:
- return pts[0] + (pts[3] - pts[0]) * x;
- case kCubic_SegmentType:
- return eval_cubic(pts, x);
- case kConstant_SegmentType:
- default:
- return pts[0];
- }
-}
-
-float SkCurveSegment::eval(float x, float t, bool negate) const {
- float result = eval_segment(fMin, x, fType);
- if (fRanged) {
- result += (eval_segment(fMax, x, fType) - result) * t;
- }
- if (fBidirectional && negate) {
- result = -result;
- }
- return result;
-}
-
-void SkCurveSegment::visitFields(SkFieldVisitor* v) {
- v->visit("Type", fType, gCurveSegmentTypeMapping, SK_ARRAY_COUNT(gCurveSegmentTypeMapping));
- v->visit("Ranged", fRanged);
- v->visit("Bidirectional", fBidirectional);
- v->visit("A0", fMin[0]);
- if (fType == kCubic_SegmentType) {
- v->visit("B0", fMin[1]);
- v->visit("C0", fMin[2]);
- }
- if (fType != kConstant_SegmentType) {
- v->visit("D0", fMin[3]);
- }
- if (fRanged) {
- v->visit("A1", fMax[0]);
- if (fType == kCubic_SegmentType) {
- v->visit("B1", fMax[1]);
- v->visit("C1", fMax[2]);
- }
- if (fType != kConstant_SegmentType) {
- v->visit("D1", fMax[3]);
- }
- }
-}
-
-float SkCurve::eval(float x, SkRandom& random) const {
- SkASSERT(fSegments.count() == fXValues.count() + 1);
-
- int i = 0;
- for (; i < fXValues.count(); ++i) {
- if (x <= fXValues[i]) {
- break;
- }
- }
-
- float rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
- float rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
- float segmentX = (x - rangeMin) / (rangeMax - rangeMin);
- if (!sk_float_isfinite(segmentX)) {
- segmentX = rangeMin;
- }
- SkASSERT(0.0f <= segmentX && segmentX <= 1.0f);
-
- // Always pull t and negate here, so that the stable generator behaves consistently, even if
- // our segments use an inconsistent feature-set.
- float t = random.nextF();
- bool negate = random.nextBool();
- return fSegments[i].eval(segmentX, t, negate);
-}
-
-void SkCurve::visitFields(SkFieldVisitor* v) {
- v->visit("XValues", fXValues);
- v->visit("Segments", fSegments);
-
- // Validate and fixup
- if (fSegments.empty()) {
- fSegments.push_back().setConstant(0.0f);
- }
- fXValues.resize_back(fSegments.count() - 1);
- for (int i = 0; i < fXValues.count(); ++i) {
- fXValues[i] = SkTPin(fXValues[i], i > 0 ? fXValues[i - 1] : 0.0f, 1.0f);
- }
-}
-
-SkColor4f SkColorCurveSegment::eval(float x, float t) const {
- SkColor4f result = eval_segment(fMin, x, fType);
- if (fRanged) {
- result = result + (eval_segment(fMax, x, fType) - result) * t;
- }
- return result;
-}
-
-void SkColorCurveSegment::visitFields(SkFieldVisitor* v) {
- v->visit("Type", fType, gCurveSegmentTypeMapping, SK_ARRAY_COUNT(gCurveSegmentTypeMapping));
- v->visit("Ranged", fRanged);
- v->visit("A0", fMin[0]);
- if (fType == kCubic_SegmentType) {
- v->visit("B0", fMin[1]);
- v->visit("C0", fMin[2]);
- }
- if (fType != kConstant_SegmentType) {
- v->visit("D0", fMin[3]);
- }
- if (fRanged) {
- v->visit("A1", fMax[0]);
- if (fType == kCubic_SegmentType) {
- v->visit("B1", fMax[1]);
- v->visit("C1", fMax[2]);
- }
- if (fType != kConstant_SegmentType) {
- v->visit("D1", fMax[3]);
- }
- }
-}
-
-SkColor4f SkColorCurve::eval(float x, SkRandom& random) const {
- SkASSERT(fSegments.count() == fXValues.count() + 1);
-
- int i = 0;
- for (; i < fXValues.count(); ++i) {
- if (x <= fXValues[i]) {
- break;
- }
- }
-
- float rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
- float rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
- float segmentX = (x - rangeMin) / (rangeMax - rangeMin);
- if (!sk_float_isfinite(segmentX)) {
- segmentX = rangeMin;
- }
- SkASSERT(0.0f <= segmentX && segmentX <= 1.0f);
- return fSegments[i].eval(segmentX, random.nextF());
-}
-
-void SkColorCurve::visitFields(SkFieldVisitor* v) {
- v->visit("XValues", fXValues);
- v->visit("Segments", fSegments);
-
- // Validate and fixup
- if (fSegments.empty()) {
- fSegments.push_back().setConstant(SkColor4f{ 1.0f, 1.0f, 1.0f, 1.0f });
- }
- fXValues.resize_back(fSegments.count() - 1);
- for (int i = 0; i < fXValues.count(); ++i) {
- fXValues[i] = SkTPin(fXValues[i], i > 0 ? fXValues[i - 1] : 0.0f, 1.0f);
- }
-}
diff --git a/modules/particles/src/SkParticleBinding.cpp b/modules/particles/src/SkParticleBinding.cpp
index 12b48b3c03..e1a45324a1 100644
--- a/modules/particles/src/SkParticleBinding.cpp
+++ b/modules/particles/src/SkParticleBinding.cpp
@@ -12,7 +12,6 @@
#include "include/utils/SkParsePath.h"
#include "include/utils/SkRandom.h"
#include "include/utils/SkTextUtils.h"
-#include "modules/particles/include/SkCurve.h"
#include "modules/particles/include/SkParticleEffect.h"
#include "modules/particles/include/SkReflected.h"
#include "src/sksl/SkSLCompiler.h"
@@ -21,96 +20,6 @@ void SkParticleBinding::visitFields(SkFieldVisitor* v) {
v->visit("Name", fName);
}
-// Exposes an SkCurve as an external, callable value. c(x) returns a float.
-class SkCurveExternalValue : public SkParticleExternalValue {
-public:
- SkCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkCurve& curve)
- : SkParticleExternalValue(name, compiler, *compiler.context().fFloat_Type)
- , fCurve(curve) { }
-
- bool canCall() const override { return true; }
- int callParameterCount() const override { return 1; }
- void getCallParameterTypes(const SkSL::Type** outTypes) const override {
- outTypes[0] = fCompiler.context().fFloat_Type.get();
- }
-
- void call(int index, float* arguments, float* outReturn) override {
- *outReturn = fCurve.eval(*arguments, fRandom[index]);
- }
-
-private:
- SkCurve fCurve;
-};
-
-class SkCurveBinding : public SkParticleBinding {
-public:
- SkCurveBinding(const char* name = "", const SkCurve& curve = 0.0f)
- : SkParticleBinding(name)
- , fCurve(curve) {}
-
- REFLECTED(SkCurveBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkParticleBinding::visitFields(v);
- v->visit("Curve", fCurve);
- }
-
- std::unique_ptr toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr(
- new SkCurveExternalValue(fName.c_str(), compiler, fCurve));
- }
-
-private:
- SkCurve fCurve;
-};
-
-// Exposes an SkColorCurve as an external, callable value. c(x) returns a float4.
-class SkColorCurveExternalValue : public SkParticleExternalValue {
-public:
- SkColorCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkColorCurve& curve)
- : SkParticleExternalValue(name, compiler, *compiler.context().fFloat4_Type)
- , fCurve(curve) {
- }
-
- bool canCall() const override { return true; }
- int callParameterCount() const override { return 1; }
- void getCallParameterTypes(const SkSL::Type** outTypes) const override {
- outTypes[0] = fCompiler.context().fFloat_Type.get();
- }
-
- void call(int index, float* arguments, float* outReturn) override {
- SkColor4f color = fCurve.eval(*arguments, fRandom[index]);
- memcpy(outReturn, color.vec(), 4 * sizeof(float));
- }
-
-private:
- SkColorCurve fCurve;
-};
-
-class SkColorCurveBinding : public SkParticleBinding {
-public:
- SkColorCurveBinding(const char* name = "",
- const SkColorCurve& curve = SkColor4f{ 1.0f, 1.0f, 1.0f, 1.0f })
- : SkParticleBinding(name)
- , fCurve(curve) {
- }
-
- REFLECTED(SkColorCurveBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkParticleBinding::visitFields(v);
- v->visit("Curve", fCurve);
- }
-
- std::unique_ptr toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr(
- new SkColorCurveExternalValue(fName.c_str(), compiler, fCurve));
- }
-
-private:
- SkColorCurve fCurve;
-};
-
class SkEffectExternalValue : public SkParticleExternalValue {
public:
SkEffectExternalValue(const char* name, SkSL::Compiler& compiler,
@@ -295,15 +204,6 @@ private:
SkPathContours fContours;
};
-sk_sp SkParticleBinding::MakeCurve(const char* name, const SkCurve& curve) {
- return sk_sp(new SkCurveBinding(name, curve));
-}
-
-sk_sp SkParticleBinding::MakeColorCurve(const char* name,
- const SkColorCurve& curve) {
- return sk_sp(new SkColorCurveBinding(name, curve));
-}
-
sk_sp SkParticleBinding::MakeEffectBinding(
const char* name, sk_sp params) {
return sk_sp(new SkEffectBinding(name, params));
@@ -315,8 +215,6 @@ sk_sp SkParticleBinding::MakePathBinding(const char* name, co
void SkParticleBinding::RegisterBindingTypes() {
REGISTER_REFLECTED(SkParticleBinding);
- REGISTER_REFLECTED(SkCurveBinding);
- REGISTER_REFLECTED(SkColorCurveBinding);
REGISTER_REFLECTED(SkEffectBinding);
REGISTER_REFLECTED(SkPathBinding);
REGISTER_REFLECTED(SkTextBinding);
diff --git a/modules/particles/src/SkParticleEffect.cpp b/modules/particles/src/SkParticleEffect.cpp
index 3a9e5fbe16..db6724b2e3 100644
--- a/modules/particles/src/SkParticleEffect.cpp
+++ b/modules/particles/src/SkParticleEffect.cpp
@@ -8,7 +8,6 @@
#include "modules/particles/include/SkParticleEffect.h"
#include "include/core/SkPaint.h"
-#include "modules/particles/include/SkCurve.h"
#include "modules/particles/include/SkParticleBinding.h"
#include "modules/particles/include/SkParticleDrawable.h"
#include "modules/particles/include/SkReflected.h"
diff --git a/modules/particles/src/SkReflected.cpp b/modules/particles/src/SkReflected.cpp
index 94e59cac67..247f7a7234 100644
--- a/modules/particles/src/SkReflected.cpp
+++ b/modules/particles/src/SkReflected.cpp
@@ -7,8 +7,6 @@
#include "modules/particles/include/SkReflected.h"
-#include "modules/particles/include/SkCurve.h"
-
SkSTArray<16, const SkReflected::Type*, true> SkReflected::gTypes;
void SkReflected::VisitTypes(std::function visitor) {
@@ -16,9 +14,3 @@ void SkReflected::VisitTypes(std::function visitor) {
visitor(type);
}
}
-
-void SkFieldVisitor::visit(const char* name, SkCurve& c) {
- this->enterObject(name);
- c.visitFields(this);
- this->exitObject();
-}
diff --git a/resources/particles/curves.json b/resources/particles/curves.json
index 864e7ed7ab..a3db6a5279 100644
--- a/resources/particles/curves.json
+++ b/resources/particles/curves.json
@@ -7,6 +7,7 @@
"EffectCode": [
"void effectSpawn(inout Effect effect) {",
" effect.rate = 200;",
+ " effect.color = float4(1, 0, 0, 1);",
"}",
""
],
@@ -17,50 +18,13 @@
"}",
"",
"void update(inout Particle p) {",
- " p.pos.x = wave(p.age);",
- " p.color = color(p.age);",
+ " float w = mix(15, 3, p.age);",
+ " p.pos.x = sin(radians(p.age * 320)) * mix(25, 10, p.age) + mix(-w, w, rand);",
+ " if (rand < 0.5) { p.pos.x = -p.pos.x; }",
+ "",
+ " p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand)) / 255;",
"}",
""
],
- "Bindings": [
- {
- "Type": "SkCurveBinding",
- "Name": "wave",
- "Curve": {
- "XValues": [],
- "Segments": [
- {
- "Type": "Cubic",
- "Ranged": true,
- "Bidirectional": true,
- "A0": -20,
- "B0": 50,
- "C0": -30,
- "D0": -10,
- "A1": 20,
- "B1": 60,
- "C1": -20,
- "D1": 0
- }
- ]
- }
- },
- {
- "Type": "SkColorCurveBinding",
- "Name": "color",
- "Curve": {
- "XValues": [],
- "Segments": [
- {
- "Type": "Linear",
- "Ranged": true,
- "A0": [ 1, 0, 0, 1 ],
- "D0": [ 1, 0.735294, 0, 1 ],
- "A1": [ 1, 0.588235, 0, 1 ],
- "D1": [ 0.941177, 1, 0, 1 ]
- }
- ]
- }
- }
- ]
+ "Bindings": []
}
\ No newline at end of file
diff --git a/site/user/modules/particles.md b/site/user/modules/particles.md
index ad3046396d..8dfbcad356 100644
--- a/site/user/modules/particles.md
+++ b/site/user/modules/particles.md
@@ -38,7 +38,7 @@ Samples
@@ -87,7 +87,7 @@ Samples
}).ready().then((CK) => {
CanvasKit = CK;
ParticleExample(CanvasKit, 'confetti', confetti, 200, 200);
- ParticleExample(CanvasKit, 'curves', curves, 200, 200);
+ ParticleExample(CanvasKit, 'curves', curves, 200, 300);
ParticleExample(CanvasKit, 'fireworks', fireworks, 200, 300);
ParticleExample(CanvasKit, 'raincloud', raincloud, 200, 100);
ParticleExample(CanvasKit, 'text', text, 75, 250);
@@ -178,7 +178,8 @@ const curves = {
},
"EffectCode": [
"void effectSpawn(inout Effect effect) {",
- " effect.rate = 200; effect.pos.y = 100;",
+ " effect.rate = 200;",
+ " effect.color = float4(1, 0, 0, 1);",
"}",
""
],
@@ -189,52 +190,15 @@ const curves = {
"}",
"",
"void update(inout Particle p) {",
- " p.pos.x = wave(p.age);",
- " p.color = color(p.age);",
+ " float w = mix(15, 3, p.age);",
+ " p.pos.x = sin(radians(p.age * 320)) * mix(25, 10, p.age) + mix(-w, w, rand);",
+ " if (rand < 0.5) { p.pos.x = -p.pos.x; }",
+ "",
+ " p.color.g = (mix(75, 220, p.age) + mix(-30, 30, rand)) / 255;",
"}",
""
],
- "Bindings": [
- {
- "Type": "SkCurveBinding",
- "Name": "wave",
- "Curve": {
- "XValues": [],
- "Segments": [
- {
- "Type": "Cubic",
- "Ranged": true,
- "Bidirectional": true,
- "A0": -20,
- "B0": 50,
- "C0": -30,
- "D0": -10,
- "A1": 20,
- "B1": 60,
- "C1": -20,
- "D1": 0
- }
- ]
- }
- },
- {
- "Type": "SkColorCurveBinding",
- "Name": "color",
- "Curve": {
- "XValues": [],
- "Segments": [
- {
- "Type": "Linear",
- "Ranged": true,
- "A0": [ 1, 0, 0, 1 ],
- "D0": [ 1, 0.735294, 0, 0.2 ],
- "A1": [ 1, 0.588235, 0, 1 ],
- "D1": [ 0.941177, 1, 0, 0.2 ]
- }
- ]
- }
- }
- ]
+ "Bindings": []
};
const fireworks = {