Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support CanvasRenderingContext2D.filter #3793

Conversation

shallawa
Copy link
Contributor

@shallawa shallawa commented Aug 30, 2022

222707e

Support CanvasRenderingContext2D.filter
https://bugs.webkit.org/show_bug.cgi?id=198416
rdar://51303686

Reviewed by Simon Fraser.

This implements the canvas filter API. According to the specs, the filter will
be defined as a string very similar to the CSS filter definition. An SVG filter
can be accessed via a URL like this `filter : url(#id);`.

To implement this feature without many changes in the CanvasRenderingContext2D
code, the new class CanvasFilterTargetSwitcher will be added. In its constructor
we are going to switch the rendering context to a source ImageBuffer. The next
draw commands will be drawn to this ImageBuffer. In its destructor, the filter
will be applied to the source ImageBuffer and the result will be composited back
to the original context.

Specs link: https://html.spec.whatwg.org/multipage/canvas.html#canvasfilters

* LayoutTests/fast/canvas/canvas-filter-basics-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-filter-basics.html: Added.
* LayoutTests/fast/canvas/canvas-filter-bounding-rect-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-bounding-rect.html: Added.
* LayoutTests/fast/canvas/canvas-filter-drawing-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-drawing.html: Added.
* LayoutTests/fast/canvas/canvas-filter-repaint-rect-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-repaint-rect.html: Added.
* LayoutTests/fast/canvas/canvas-filter-save-restore-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-save-restore.html: Added.
* LayoutTests/fast/canvas/resources/100x100-green-rect-filter-blur.svg: Added.
* LayoutTests/fast/canvas/resources/100x100-green-rect-filter-drop-shadow.svg: Added.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.value-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/reset/2d.reset.state.filter-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.value-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.value.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/reset/2d.reset.state.filter-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/dom/idlharness.https_exclude=(Document_Window_HTML._)-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/dom/idlharness.worker-expected.txt:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/dom/idlharness.https_exclude=(Document_Window_HTML._)-expected.txt:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/dom/idlharness.worker-expected.txt:
* LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp:
(WebCore::CSSPropertyParserWorkerSafe::parseFilterString):
* Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.h:
* Source/WebCore/html/canvas/CanvasFilterTargetSwitcher.cpp: Added.
(WebCore::CanvasFilterTargetSwitcher::create):
(WebCore::CanvasFilterTargetSwitcher::CanvasFilterTargetSwitcher):
(WebCore::CanvasFilterTargetSwitcher::~CanvasFilterTargetSwitcher):
(WebCore::CanvasFilterTargetSwitcher::outsets const):
* Source/WebCore/html/canvas/CanvasFilterTargetSwitcher.h: Added.
(WebCore::CanvasFilterTargetSwitcher::expandedBounds const):
* Source/WebCore/html/canvas/CanvasFilters.idl:
* Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFilterStringWithoutUpdatingStyle):
(WebCore::CanvasRenderingContext2D::createFilter const):
(WebCore::CanvasRenderingContext2D::calculateFilterOutsets const):
* Source/WebCore/html/canvas/CanvasRenderingContext2D.h:
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::State::State):
(WebCore::CanvasRenderingContext2DBase::setFilterString):
(WebCore::CanvasRenderingContext2DBase::fillInternal):
(WebCore::CanvasRenderingContext2DBase::strokeInternal):
(WebCore::CanvasRenderingContext2DBase::fillRect):
(WebCore::CanvasRenderingContext2DBase::strokeRect):
(WebCore::CanvasRenderingContext2DBase::drawImage):
(WebCore::CanvasRenderingContext2DBase::drawingContext const):
(WebCore::CanvasRenderingContext2DBase::inflatedStrokeRect const):
(WebCore::CanvasRenderingContext2DBase::drawTextUnchecked):
(WebCore::CanvasRenderingContext2DBase::inflateStrokeRect const): Deleted.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h:
(WebCore::CanvasRenderingContext2DBase::filterString const):
(WebCore::CanvasRenderingContext2DBase::setFilterStringWithoutUpdatingStyle):
(WebCore::CanvasRenderingContext2DBase::createFilter const):
(WebCore::CanvasRenderingContext2DBase::calculateFilterOutsets const):
(WebCore::CanvasRenderingContext2DBase::setFilterTargetSwitcher):
* Source/WebCore/platform/RectEdges.h:
(WebCore::RectEdges::RectEdges):
* Source/WebCore/platform/graphics/FloatRect.h:
(WebCore::operator+):

Canonical link: https://commits.webkit.org/278000@main

0944eb5

Misc iOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 wincairo
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-skia
✅ 🛠 🧪 jsc ✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 🧪 jsc-arm64 ✅ 🛠 tv ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 tv-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
✅ 🛠 🧪 merge ✅ 🛠 watch ✅ 🛠 jsc-armv7
✅ 🛠 watch-sim ✅ 🧪 jsc-armv7-tests

@shallawa shallawa requested review from cdumez and rniwa as code owners August 30, 2022 00:58
@shallawa shallawa self-assigned this Aug 30, 2022
@shallawa shallawa added Canvas Bugs related to the canvas element. WebKit Nightly Build labels Aug 30, 2022
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 30, 2022
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Aug 30, 2022
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from a8c57ff to a4e5558 Compare August 30, 2022 17:10
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 30, 2022
@shallawa shallawa marked this pull request as draft August 30, 2022 22:22
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Oct 14, 2022
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from a4e5558 to ee56e3d Compare October 14, 2022 00:35
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 14, 2022
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Oct 14, 2022
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from ee56e3d to e874780 Compare October 14, 2022 18:51
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 14, 2022
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Oct 16, 2022
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from e874780 to 7a2a1cc Compare October 16, 2022 23:32
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from 7a2a1cc to 9b0fc35 Compare October 17, 2022 00:07
@shallawa shallawa requested review from smfr, grorg and weinig October 17, 2022 00:09
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 17, 2022
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from c668981 to 22e09d3 Compare April 25, 2024 08:46
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 25, 2024
@shallawa shallawa removed the merging-blocked Applied to prevent a change from being merged label Apr 25, 2024
@shallawa shallawa force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from 22e09d3 to 0944eb5 Compare April 25, 2024 08:55
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 25, 2024
@shallawa shallawa added merge-queue Applied to send a pull request to merge-queue and removed merging-blocked Applied to prevent a change from being merged labels Apr 25, 2024
@webkit-ews-buildbot webkit-ews-buildbot added merging-blocked Applied to prevent a change from being merged and removed merge-queue Applied to send a pull request to merge-queue labels Apr 25, 2024
@shallawa shallawa added merge-queue Applied to send a pull request to merge-queue and removed merging-blocked Applied to prevent a change from being merged labels Apr 25, 2024
https://bugs.webkit.org/show_bug.cgi?id=198416
rdar://51303686

Reviewed by Simon Fraser.

This implements the canvas filter API. According to the specs, the filter will
be defined as a string very similar to the CSS filter definition. An SVG filter
can be accessed via a URL like this `filter : url(#id);`.

To implement this feature without many changes in the CanvasRenderingContext2D
code, the new class CanvasFilterTargetSwitcher will be added. In its constructor
we are going to switch the rendering context to a source ImageBuffer. The next
draw commands will be drawn to this ImageBuffer. In its destructor, the filter
will be applied to the source ImageBuffer and the result will be composited back
to the original context.

Specs link: https://html.spec.whatwg.org/multipage/canvas.html#canvasfilters

* LayoutTests/fast/canvas/canvas-filter-basics-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-filter-basics.html: Added.
* LayoutTests/fast/canvas/canvas-filter-bounding-rect-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-bounding-rect.html: Added.
* LayoutTests/fast/canvas/canvas-filter-drawing-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-drawing.html: Added.
* LayoutTests/fast/canvas/canvas-filter-repaint-rect-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-repaint-rect.html: Added.
* LayoutTests/fast/canvas/canvas-filter-save-restore-expected.html: Added.
* LayoutTests/fast/canvas/canvas-filter-save-restore.html: Added.
* LayoutTests/fast/canvas/resources/100x100-green-rect-filter-blur.svg: Added.
* LayoutTests/fast/canvas/resources/100x100-green-rect-filter-drop-shadow.svg: Added.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.canvasFilterObject.tentative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/filters/2d.filter.value-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/reset/2d.reset.state.filter-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.tentative.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.value-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/filters/2d.filter.value.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/reset/2d.reset.state.filter-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/reset/2d.reset.state.filter.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/dom/idlharness.https_exclude=(Document_Window_HTML._)-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/dom/idlharness.worker-expected.txt:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/dom/idlharness.https_exclude=(Document_Window_HTML._)-expected.txt:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/html/dom/idlharness.worker-expected.txt:
* LayoutTests/platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.cpp:
(WebCore::CSSPropertyParserWorkerSafe::parseFilterString):
* Source/WebCore/css/parser/CSSPropertyParserWorkerSafe.h:
* Source/WebCore/html/canvas/CanvasFilterTargetSwitcher.cpp: Added.
(WebCore::CanvasFilterTargetSwitcher::create):
(WebCore::CanvasFilterTargetSwitcher::CanvasFilterTargetSwitcher):
(WebCore::CanvasFilterTargetSwitcher::~CanvasFilterTargetSwitcher):
(WebCore::CanvasFilterTargetSwitcher::outsets const):
* Source/WebCore/html/canvas/CanvasFilterTargetSwitcher.h: Added.
(WebCore::CanvasFilterTargetSwitcher::expandedBounds const):
* Source/WebCore/html/canvas/CanvasFilters.idl:
* Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFilterStringWithoutUpdatingStyle):
(WebCore::CanvasRenderingContext2D::createFilter const):
(WebCore::CanvasRenderingContext2D::calculateFilterOutsets const):
* Source/WebCore/html/canvas/CanvasRenderingContext2D.h:
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::State::State):
(WebCore::CanvasRenderingContext2DBase::setFilterString):
(WebCore::CanvasRenderingContext2DBase::fillInternal):
(WebCore::CanvasRenderingContext2DBase::strokeInternal):
(WebCore::CanvasRenderingContext2DBase::fillRect):
(WebCore::CanvasRenderingContext2DBase::strokeRect):
(WebCore::CanvasRenderingContext2DBase::drawImage):
(WebCore::CanvasRenderingContext2DBase::drawingContext const):
(WebCore::CanvasRenderingContext2DBase::inflatedStrokeRect const):
(WebCore::CanvasRenderingContext2DBase::drawTextUnchecked):
(WebCore::CanvasRenderingContext2DBase::inflateStrokeRect const): Deleted.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h:
(WebCore::CanvasRenderingContext2DBase::filterString const):
(WebCore::CanvasRenderingContext2DBase::setFilterStringWithoutUpdatingStyle):
(WebCore::CanvasRenderingContext2DBase::createFilter const):
(WebCore::CanvasRenderingContext2DBase::calculateFilterOutsets const):
(WebCore::CanvasRenderingContext2DBase::setFilterTargetSwitcher):
* Source/WebCore/platform/RectEdges.h:
(WebCore::RectEdges::RectEdges):
* Source/WebCore/platform/graphics/FloatRect.h:
(WebCore::operator+):

Canonical link: https://commits.webkit.org/278000@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/Support-CanvasRenderingContext2D-filter branch from 0944eb5 to 222707e Compare April 25, 2024 21:07
@webkit-commit-queue
Copy link
Collaborator

Committed 278000@main (222707e): https://commits.webkit.org/278000@main

Reviewed commits have been landed. Closing PR #3793 and removing active labels.

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Apr 25, 2024
@webkit-commit-queue webkit-commit-queue merged commit 222707e into WebKit:main Apr 25, 2024
@pencil
Copy link

pencil commented Apr 26, 2024

Awesome to finally see this merged. Thanks everyone who helped getting it across the finish line! ❤️

@shallawa shallawa deleted the eng/Support-CanvasRenderingContext2D-filter branch May 1, 2024 19:40
@quinton-ashley
Copy link

quinton-ashley commented Jun 12, 2024

@pencil So will this be implemented in Safari soon?

EDIT: I see it's available for testing in Safari Tech Preview currently

@saghul
Copy link

saghul commented Jun 12, 2024

I see it's available in Safari TP >= 194. You do need to enable this feature flag. FWIW it's not working for our use case (video background blur) I'll need to dig deeper...

Screenshot 2024-06-13 at 00 18 40

@quinton-ashley
Copy link

quinton-ashley commented Jun 12, 2024

@saghul Yeah I'm also experiencing that blur doesn't work. ctx.filter is set to "none" by default instead of undefined so it seems like it's enabled.

ctx.filter = "blur(6px)"

But after changing it, it still says its set to "none" and does nothing to the canvas.

@shallawa
Copy link
Contributor Author

@saghul Yeah I'm also experiencing that blur doesn't work. ctx.filter is set to "none" by default instead of undefined so it seems like it's enabled.

ctx.filter = "blur(6px)"

But after changing it, it still says its set to "none" and does nothing to the canvas.

@quinton-ashley This should work with any image source. Does this bug happen when applying the filter to a video in the canvas? can you please file this bug in https://bugs.webkit.org?

@quinton-ashley
Copy link

quinton-ashley commented Jun 13, 2024

I'm trying to use it with an offscreen canvas with an image drawn on it, which is then drawn to a visible canvas.

@quinton-ashley
Copy link

@shallawa I submitted the bug report
https://bugs.webkit.org/show_bug.cgi?id=275436

@mercuryVM
Copy link

mercuryVM commented Jun 29, 2024

Conducting some tests using Safari Technology Preview, apparently when you create a canvas using document.createElement("canvas"), it does not work properly, and setting ctx.filter always returns none. It only works correctly if the canvas is added to the body of the HTML page.

However, unlike OffscreenCanvas, theoretically a canvas created through document.createElement can access the DOM and, consequently, the SVG filters.

Will this functionality be supported?

@mercuryVM
Copy link

This code, for example, presents different results in Safari and Chrome.

<html>

<body>
    <svg width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink">
        <filter id="filter" filterRes="1">
            <feColorMatrix type="matrix" values="1 0 0 0 1  0 0.5 0 0 0  0 0 1 0 0  0 0 0 1 0 0 0 0 0 0 0" />
        </filter>
    </svg>
</body>
<script>
    const canvas = document.createElement("canvas");
    const filter = document.querySelector('#filter feColorMatrix');

    canvas.width = 800;
    canvas.height = 600;

    const ctx = canvas.getContext('2d');

    const _color = {
        redMultiplier: 0,
        redOffset: 0,
        greenMultiplier: 1,
        greenOffset: 0,
        blueMultiplier: 1,
        blueOffset: 0,
        alphaMultiplier: 0.1,
        alphaOffset: 0
    }

    let matrix_str = `${_color.redMultiplier} 0 0 0 ${_color.redOffset / 255} 0 ${_color.greenMultiplier} 0 0 ${_color.greenOffset / 255} 0 0 ${_color.blueMultiplier} 0 ${_color.blueOffset / 255} 0 0 0 ${_color.alphaMultiplier} ${_color.alphaOffset / 255}`;

    filter.setAttribute('values', matrix_str);

    ctx.filter = 'url(#filter)';

    const img = new Image();
    img.src = "https://t4.ftcdn.net/jpg/04/38/82/85/360_F_438828559_QccWdc3zAULf7uLTzekIt5XlOEnGj6X0.jpg";
    img.onload = () => {
        ctx.drawImage(img, 0, 0)
        document.body.appendChild(canvas);
    }

</script>

</html>

In Safari, setting a filter on a CanvasRenderingContext2D where the canvas is not part of the document always keeps the filter as none.
But if you add the canvas to the document before setting the filter, everything works normally.

...

document.body.appendChild(canvas);

//It works in Safari because the canvas is in the document
ctx.filter = 'url(#filter)';

const img = new Image();
img.src = "https://t4.ftcdn.net/jpg/04/38/82/85/360_F_438828559_QccWdc3zAULf7uLTzekIt5XlOEnGj6X0.jpg";
img.onload = () => {
    ctx.drawImage(img, 0, 0)
}

Just wanting to know if it will remain this way or if it has been fixed in #30074, as my application depends on this functionality to perform color transformations not supported by OffscreenCanvas.

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Canvas Bugs related to the canvas element.
Projects
None yet
Development

Successfully merging this pull request may close these issues.