From 84f3ce50fcf2a16fd0feea4a6b6c2bcc04da08a8 Mon Sep 17 00:00:00 2001 From: lvpengwei Date: Thu, 2 Nov 2023 08:26:29 -0500 Subject: [PATCH] Add web demo. (#21) --- web/demo/TGFXDemoBindings.cpp | 118 ++++++++++++++++++++++++++++++++++ web/demo/index.ts | 7 ++ web/script/build.sh | 5 ++ 3 files changed, 130 insertions(+) create mode 100644 web/demo/TGFXDemoBindings.cpp diff --git a/web/demo/TGFXDemoBindings.cpp b/web/demo/TGFXDemoBindings.cpp new file mode 100644 index 00000000..cc0f1539 --- /dev/null +++ b/web/demo/TGFXDemoBindings.cpp @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making tgfx available. +// +// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "tgfx/opengl/webgl/WebGLWindow.h" + +using namespace emscripten; +using namespace tgfx; + +class TGFXView { + public: + explicit TGFXView(std::string canvasID) : canvasID(std::move(canvasID)) { + updateSize(); + } + + void updateSize() { + if (!canvasID.empty()) { + emscripten_get_canvas_element_size(canvasID.c_str(), &_width, &_height); + surface = nullptr; + } + } + + void draw() { + if (surface == nullptr) { + createSurface(); + } + if (surface == nullptr) { + return; + } + auto device = window->getDevice(); + auto context = device->lockContext(); + if (context == nullptr) { + return; + } + auto canvas = surface->getCanvas(); + canvas->clear(); + tgfx::Paint paint; + paint.setColor(tgfx::Color{0.0f, 0.8f, 0.0f, 1.f}); + if (drawCount % 2 == 0) { + auto rect = tgfx::Rect::MakeXYWH(20, 20, 100, 100); + canvas->drawRect(rect, paint); + } else { + int tileSize = 8; + for (int y = 0; y < _height; y += tileSize) { + bool draw = (y / tileSize) % 2 == 1; + for (int x = 0; x < _width; x += tileSize) { + if (draw) { + auto rect = + tgfx::Rect::MakeXYWH(static_cast(x), static_cast(y), + static_cast(tileSize), static_cast(tileSize)); + canvas->drawRect(rect, paint); + } + draw = !draw; + } + } + } + surface->flush(); + context->submit(); + window->present(context); + device->unlock(); + drawCount++; + } + + private: + void createSurface() { + if (_width <= 0 || _height <= 0) { + return; + } + if (window == nullptr) { + window = WebGLWindow::MakeFrom(canvasID); + } + if (window == nullptr) { + return; + } + auto device = window->getDevice(); + auto context = device->lockContext(); + if (context == nullptr) { + return; + } + surface = window->createSurface(context); + device->unlock(); + } + + std::string canvasID; + std::shared_ptr window; + std::shared_ptr surface; + int _width = 0; + int _height = 0; + int drawCount = 0; +}; + +EMSCRIPTEN_BINDINGS(TGFXDemo) { + class_("TGFXView") + .smart_ptr>("TGFXView") + .class_function("_Make", optional_override([](const std::string& canvasID) { + if (canvasID.empty()) { + return std::shared_ptr(nullptr); + } + return std::make_shared(canvasID); + })) + .function("updateSize", &TGFXView::updateSize) + .function("draw", &TGFXView::draw); +} diff --git a/web/demo/index.ts b/web/demo/index.ts index 6d80c02e..275ac054 100644 --- a/web/demo/index.ts +++ b/web/demo/index.ts @@ -9,4 +9,11 @@ window.onload = async () => { document.getElementById('container')!.style.display = 'block'; TGFXModule.ScalerContext.isEmoji('测试'); TGFXModule.ScalerContext.isEmoji('👍'); + if (TGFXModule.TGFXView) { + const view = TGFXModule.TGFXView._Make('#tgfx'); + document.getElementById('tgfx')!.onclick = () => { + view.draw(); + }; + view.draw(); + } }; diff --git a/web/script/build.sh b/web/script/build.sh index 898d7ee6..1158b7cb 100755 --- a/web/script/build.sh +++ b/web/script/build.sh @@ -21,6 +21,10 @@ emcmake cmake -S $SOURCE_DIR -B $BUILD_DIR -G Ninja -DCMAKE_BUILD_TYPE="$CMAKE_B cmake --build $BUILD_DIR --target tgfx +if [[ $@ == *demo* ]]; then + DEMO_FILE=$SOURCE_DIR/web/demo/TGFXDemoBindings.cpp +fi + emcc $RELEASE_CONF -std=c++17 \ -I$SOURCE_DIR/include/ \ -I$SOURCE_DIR/src/ \ @@ -39,6 +43,7 @@ emcc $RELEASE_CONF -std=c++17 \ -s ENVIRONMENT="web,worker" \ -s EXPORT_ES6=1 \ -s USE_ES6_IMPORT_META=0 \ + $DEMO_FILE \ -o ../src/wasm/tgfx.js if test $? -eq 0; then