From 2cb2ffd2eaa688cc5ce2493f757c4f6085fe7e2e Mon Sep 17 00:00:00 2001 From: ivanvl01 Date: Wed, 2 Mar 2022 14:36:45 +0200 Subject: [PATCH] first commit --- .babelrc | 25 ++++++ .browserlistrc | 6 ++ .eslintignore | 1 + .eslintrc | 60 ++++++++++++++ .gitignore | 73 +++++++++++++++++ README.md | 34 ++++++++ clip/clip.css | 69 ++++++++++++++++ clip/clip.html | 30 +++++++ clip/clip.js | 36 +++++++++ clip/incidents.js | 135 ++++++++++++++++++++++++++++++++ clip/initParams.js | 23 ++++++ demo/clip.css | 14 ++++ demo/id.js | 1 + demo/index.html | 32 ++++++++ demo/index.js | 81 +++++++++++++++++++ demo/scripts/initParamsApply.js | 10 +++ demo/scripts/pathHandler.js | 42 ++++++++++ demo/webpack.config.js | 48 ++++++++++++ package.json | 67 ++++++++++++++++ renovate.json | 10 +++ 20 files changed, 797 insertions(+) create mode 100644 .babelrc create mode 100644 .browserlistrc create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 README.md create mode 100644 clip/clip.css create mode 100644 clip/clip.html create mode 100644 clip/clip.js create mode 100644 clip/incidents.js create mode 100644 clip/initParams.js create mode 100644 demo/clip.css create mode 100644 demo/id.js create mode 100644 demo/index.html create mode 100644 demo/index.js create mode 100644 demo/scripts/initParamsApply.js create mode 100644 demo/scripts/pathHandler.js create mode 100644 demo/webpack.config.js create mode 100644 package.json create mode 100644 renovate.json diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..77d1a69 --- /dev/null +++ b/.babelrc @@ -0,0 +1,25 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": "> 0.25%, not dead", + "useBuiltIns": "usage", + "corejs": "3.18", + } + ] + ], + "exclude": [ + "node_modules/**" + ], + "plugins": [ + "@babel/plugin-proposal-class-properties", + "@babel/plugin-syntax-jsx", + [ + "@babel/plugin-transform-react-jsx", + { + "pragma": "MotorCortex.utils.createDOMElement" + } + ] + ] +} diff --git a/.browserlistrc b/.browserlistrc new file mode 100644 index 0000000..5e9641b --- /dev/null +++ b/.browserlistrc @@ -0,0 +1,6 @@ +{ +"browserslist": [ + ">0.2%", + "not ie <= 11" + ] +} \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..4187d67 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +bundle.js \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..30ff6ca --- /dev/null +++ b/.eslintrc @@ -0,0 +1,60 @@ +{ + "parser": "@babel/eslint-parser", + "extends": [ + "eslint:recommended", + "prettier" + ], + "plugins": [ + "babel", + "prettier" + ], + "env": { + "browser": true, + "node": true + }, + "globals": { + "document": false, + "escape": false, + "navigator": false, + "unescape": false, + "window": false, + "describe": true, + "before": true, + "it": true, + "expect": true, + "sinon": true + }, + "rules": { + "prettier/prettier": [ + "error" + ], + "linebreak-style": [ + "error", + "unix" + ], + "semi": [ + "error", + "always" + ], + "no-console": [ + "error", + { + "allow": [ + "warn", + "error", + "info" + ] + } + ], + "prefer-promise-reject-errors": "error", + "prefer-const": [ + "error", + { + "destructuring": "any", + "ignoreReadBeforeAssign": false + } + ], + "no-var": "error", + "no-unused-vars": "error" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32662e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# Node modules +node_modules +demo/bundle.js +demo/bundle.js.LICENSE.txt + +#Package JSON Lock +package-lock.json + +# Coverage +coverage + +# Output folders +build +compiled +.nyc_output + +# Cachses +.awcache +.rpt2_cache + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +# VSCode +.vscode + +# Cloud9 +.c9revisions +.c9 + +# Intelij +.idea +cmake-build-*/ + +# Sublime text +*.iws +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace + +# OSX +.DS_Store +.AppleDouble +.LSOverride +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows +*.lnk +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +$RECYCLE.BIN/ +[Dd]esktop.ini +*.cab +*.msi +*.msix +*.msm +*.msp \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..58be884 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# motorcortex-clip-starter + +## Purpose + +This repository is a starter boilerplate for creating MotorCortex Clips with DCode. Do not use this repo directly. Instead, use it from the **[Donkeyclip CLI](https://github.com/donkeyclip/cli)** + +## Structure and Contents + +It includes: + +- a pre-configured webpack so you don't have to care about setting up your project +- pre-configured eslint and babel +- a "clip" folder in order for you to use to define your Clip and Incidents. The folder + contains the `clip.js` file which is just a starting point for your Clip. +- a "demo" folder that is there just for the needs of viewing, debugging and creating + your Clip through DCode. + +## How to use + +Once you've created your new Clip you have the ability to publish it through the [donkeyclip](https://donkeyclip.com) page. You can then embed your clip in any site you want!. + +## Commands + +- `npm run build`: builds the demo +- `npm start`: builds and starts the demo +- `npm render`: render the demo to mp4 video see [@donkeyclip/video-renderer](https://github.com/donkeyclip/video-renderer) from more + +## Have fun!!! + +## License + +[MIT License](https://opensource.org/licenses/MIT) + +[](https://donkeyclip.com) diff --git a/clip/clip.css b/clip/clip.css new file mode 100644 index 0000000..4789444 --- /dev/null +++ b/clip/clip.css @@ -0,0 +1,69 @@ +* { + --color: {{ initParams.color }}; +} + +.root { + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + height: 100%; + background-color: #121212; +} + + +.blob-wrapper { + filter: url("#goo"); + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.blob { + position: absolute; + left: -20%; + top: 50%; + width: 100px; + height: 100px; + line-height: 100px; + text-align: center; + color: white; + font-size: 40px; + border-radius: 100%; + margin-top: -50px; + margin-left: -50px; + background-color: rgba(147,92,255,1) ; + +} + +.br{ + background-image: linear-gradient(90deg, rgba(52,200,255,1) 0%, rgba(52,200,255,1) 100%); + left: 120%; +} + +.logo{ + position: absolute; + left: 50.5%; + top: 49%; + transform: translate(-50%, -50%); + opacity: 0; +} + +.logo-path{ + stroke-dasharray: 200; + stroke-dashoffset: 200; + stroke-width:12; + stroke:#121212 +} + + +.logo-text{ + position: absolute; + width: 0px; + transform: translate(-50%, -50%); + top: 50%; + left: 52%; +} + diff --git a/clip/clip.html b/clip/clip.html new file mode 100644 index 0000000..656612a --- /dev/null +++ b/clip/clip.html @@ -0,0 +1,30 @@ +
+
+
+
+
+ + + + + + + + + + + + + +
diff --git a/clip/clip.js b/clip/clip.js new file mode 100644 index 0000000..30d0f19 --- /dev/null +++ b/clip/clip.js @@ -0,0 +1,36 @@ +import { HTMLClip } from "@donkeyclip/motorcortex"; +import html from "./clip.html"; +import css from "!!raw-loader!./clip.css"; +import { comboBr,comboBl,opacity ,left,width,color} from "./incidents"; +import { initParamsValidationRules, initParams } from "./initParams"; + +export const clip = new HTMLClip({ + html, + css, + host: document.getElementById("clip"), + initParamsValidationRules, + initParams: initParams[1].value, + containerParams: { + width: "800px", + height: "450px", + }, +}); + + + + +clip.addIncident(left("45%",".bl", 500), 0); +clip.addIncident(left("55%",".br", 500), 0); +clip.addIncident(comboBr(".br"), 500); +clip.addIncident(comboBl(".bl"), 500); +clip.addIncident(comboBl(".br"), 900); +clip.addIncident(comboBr(".bl"), 900); +clip.addIncident(left("50%",".br,.bl", 200), 1300); +clip.addIncident(opacity(1,".logo", 1000,"easeOutQuart"), 1500); +clip.addIncident(width("430px",".logo-text", 1000,"easeOutQuart"), 2500); +clip.addIncident(left("60%",".logo-text", 850,"easeOutQuart"), 2500); +clip.addIncident(left("25%",".br,.bl", 850,"easeOutQuart"), 2500); +clip.addIncident(left("25.5%",".logo", 850,"easeOutQuart"), 2500); +clip.addIncident(color("linear-gradient(90deg, rgba(52,200,255,1) 0%, rgba(147,92,255,1) 100%)",".br", 200,"easeOutQuart"), 1500); + + diff --git a/clip/incidents.js b/clip/incidents.js new file mode 100644 index 0000000..cc4d242 --- /dev/null +++ b/clip/incidents.js @@ -0,0 +1,135 @@ +import { CSSEffect,Combo } from "@donkeyclip/motorcortex"; + +export const left = ( value,selector, duration, easing = "linear") => + new CSSEffect( + { + animatedAttrs: { + left:value + }, + }, + { + selector, + duration, + easing, + } + ); + +export const opacity = (value,selector, duration, easing = "linear") => + new CSSEffect( + { + animatedAttrs: { + opacity: value, + }, + }, + { + selector, + duration, + easing, + } + ); + + export const width = (value,selector, duration, easing = "linear") => + new CSSEffect( + { + animatedAttrs: { + width: value, + }, + }, + { + selector, + duration, + easing, + } + ); + + export const color = (value,selector, duration, easing = "linear") => + new CSSEffect( + { + animatedAttrs: { + backgroundImage: value, + }, + }, + { + selector, + duration, + easing, + } + ); + + export const comboBl = (selector) => + new Combo( + { + incidents: [ + { + incidentClass: CSSEffect, + attrs: { + animatedAttrs: { + top: "45%", + left: "50%" + } + }, + props: { + duration: 200, + }, + position: 0 + }, + { + incidentClass: CSSEffect, + attrs: { + animatedAttrs: { + top: "50%", + left: "55%" + } + }, + props: { + duration: 200, + }, + position: 200 + }, + + ] + }, + { + selector, + easing:"easeOutQuart", + } + ); + + export const comboBr = (selector) => + new Combo( + { + incidents: [ + { + incidentClass: CSSEffect, + attrs: { + animatedAttrs: { + top: "55%", + left: "50%" + } + }, + props: { + duration: 200, + }, + position: 0 + }, + { + incidentClass: CSSEffect, + attrs: { + animatedAttrs: { + top: "50%", + left: "45%" + } + }, + props: { + duration: 200, + }, + position: 200 + }, + + ] + }, + { + selector, + easing:"easeOutQuart", + } + ); \ No newline at end of file diff --git a/clip/initParams.js b/clip/initParams.js new file mode 100644 index 0000000..70a712e --- /dev/null +++ b/clip/initParams.js @@ -0,0 +1,23 @@ +export const initParamsValidationRules = { + color: { + label: "Text Color", + type: "color", + optional: true, + default: "white", + }, +}; + +export const initParams = [ + { + name: "Default", + value: { + color: "white", + }, + }, + { + name: "Red Color", + value: { + color: "red", + }, + }, +]; diff --git a/demo/clip.css b/demo/clip.css new file mode 100644 index 0000000..c11507a --- /dev/null +++ b/demo/clip.css @@ -0,0 +1,14 @@ +html, +body { + margin: 0; + background-color: #282828; + position: relative; + width: 100%; + height: 100%; +} + +#projector, +#clip { + width: 100% !important; + height: 100% !important; +} diff --git a/demo/id.js b/demo/id.js new file mode 100644 index 0000000..9ae5e86 --- /dev/null +++ b/demo/id.js @@ -0,0 +1 @@ +export default "b901bbdd-7ab8-4b0b-916d-7994948c8787"; \ No newline at end of file diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..5c524b3 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,32 @@ + + + + + + + Donkeyclip | MotorCortex + + + + + + +
+
+
+ + + diff --git a/demo/index.js b/demo/index.js new file mode 100644 index 0000000..1bacc59 --- /dev/null +++ b/demo/index.js @@ -0,0 +1,81 @@ +import { utils } from "@donkeyclip/motorcortex"; +import Player from "@donkeyclip/motorcortex-player"; +import { clip } from "../clip/clip"; +import clipId from "./id"; +import { initParams } from "../clip/initParams"; +import initParamsApply from "./scripts/initParamsApply"; + +const liveDef = clip.exportLiveDefinition(); +liveDef.props.id = clip.id; + +const clipDef = clip.exportDefinition(); +let player; +window.addEventListener("message", (event) => { + if (event.data.what === "initParamsChange") { + const newLiveDef = initParamsApply(liveDef, event.data.initParams); + document.getElementById("projector").innerHTML = "
"; + const newClipContainer = document.getElementById("clip"); + // set clip container's dimensions + newClipContainer.style.width = clip.props.containerParams.width; + newClipContainer.style.height = clip.props.containerParams.height; + newLiveDef.props.host = newClipContainer; + const newclip = utils.clipFromDefinition(newLiveDef); + if (newclip.nonBlockingErrorClip) { + // if the initParams validation has failed + return alert("Error with init params"); + } + player = new Player({ clip: newclip }); + } +}); + +const clipContainer = document.getElementById("clip"); +// set clip container's dimensions +clipContainer.style.width = clip.props.containerParams.width; +clipContainer.style.height = clip.props.containerParams.height; + +const searchQuery = window.location.search.split("?")[1] || ""; +const params = searchQuery.split("&").map((pair) => pair.split("=")); +const searchOptions = {}; +for (const i in params) { + searchOptions[params[i][0]] = params[i][1]; +} + +let playerOptions = {}; +if (searchOptions.settings) { + try { + playerOptions = JSON.parse(atob(searchOptions.settings)); + } catch (e) { + console.error("Invalid options:", searchOptions.settings); + } +} + +window.top.postMessage( + { + what: "clipLoaded", + clipDims: clip.props.containerParams, + clipDef: JSON.parse(JSON.stringify(clipDef)), + clipId, + initParams, + selectedParamsIndex: searchOptions.initParams, + }, + "*" +); + +player = new Player({ + clip, + timeFormat: "ms", + ...playerOptions, + onMillisecondChange: (ms) => { + window.top.postMessage( + { + what: "msChanged", + millisecond: ms, + }, + "*" + ); + }, +}); + +if (searchOptions.initParams) { + player.changeInitParams(initParams[searchOptions.initParams].value); +} diff --git a/demo/scripts/initParamsApply.js b/demo/scripts/initParamsApply.js new file mode 100644 index 0000000..a194c7e --- /dev/null +++ b/demo/scripts/initParamsApply.js @@ -0,0 +1,10 @@ +/** + * + * @param {object} liveDefinition - the exported live definition of the Clip + * @param {object} params - the params passed by the user + * @returns {object} - the new live definition to be used for constructing the new Clip + */ +export default function initParamsApply(liveDefinition, params) { + liveDefinition.props.initParams = params; + return liveDefinition; +} diff --git a/demo/scripts/pathHandler.js b/demo/scripts/pathHandler.js new file mode 100644 index 0000000..aeb71e8 --- /dev/null +++ b/demo/scripts/pathHandler.js @@ -0,0 +1,42 @@ +export const addToObject = function ( + currentObject, + path, + value, + replace = false +) { + const arrayPath = path.split("."); + + for (let i = 0; i < arrayPath.length - 1; i++) { + if (!Object.prototype.hasOwnProperty.call(currentObject, arrayPath[i])) { + currentObject[arrayPath[i]] = {}; + } + currentObject = currentObject[arrayPath[i]]; + } + + if ( + replace === false && + Object.prototype.hasOwnProperty.call( + currentObject, + arrayPath[arrayPath.length - 1] + ) + ) { + return false; + } + + currentObject[arrayPath[arrayPath.length - 1]] = value; + return true; +}; + +export const getFromObject = function (currentObject, path) { + const arrayPath = path.split("."); + let lastValue; + + for (let i = 0; i < arrayPath.length; i++) { + if (!Object.prototype.hasOwnProperty.call(currentObject, arrayPath[i])) { + return undefined; + } + lastValue = currentObject[arrayPath[i]]; + currentObject = currentObject[arrayPath[i]]; + } + return lastValue; +}; diff --git a/demo/webpack.config.js b/demo/webpack.config.js new file mode 100644 index 0000000..f7dfbba --- /dev/null +++ b/demo/webpack.config.js @@ -0,0 +1,48 @@ +const path = require("path"); +const webpack = require("webpack"); + +module.exports = { + context: path.resolve(__dirname), + + entry: "./index.js", + + output: { + path: path.resolve(__dirname, "./"), + // the output bundle + filename: "./bundle.js", + }, + + module: { + rules: [ + { + test: /\.css$/i, + use: ["to-string-loader", "style-loader", "css-loader"], + }, + { + test: /\.html$/i, + loader: "html-loader", + }, + { + test: /\.js$/, + use: "babel-loader", + exclude: /node_modules/, + }, + ], + }, + + plugins: [ + // enable HMR globally + new webpack.HotModuleReplacementPlugin(), + + // do not emit compiled assets that include errors + new webpack.NoEmitOnErrorsPlugin(), + ], + + devServer: { + host: "127.0.0.1", + port: 8090, + historyApiFallback: false, + hot: true, + static: path.join(__dirname), + }, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..d2a114e --- /dev/null +++ b/package.json @@ -0,0 +1,67 @@ +{ + "name": "@donkeyclip/motorcortex-clip-starter", + "version": "1.0.0", + "description": "Starter repo for creating Donkey Clips", + "author": "", + "repository": { + "type": "git", + "url": "https://github.com/donkeyclip/motorcortex-clip-starter" + }, + "engines": { + "node": ">=12" + }, + "scripts": { + "build": "webpack --mode=production --config ./demo/webpack.config.js", + "lint": "eslint -c .eslintrc src/**/*.js", + "lint:fix": "npm run lint -- --fix", + "start": "npm run build & webpack serve --mode=development --config ./demo/webpack.config.js", + "test": "HERE GOES YOUR TEST TASK", + "test:prod": "npm run lint", + "render": "node node_modules/dclip-video-renderer" + }, + "keywords": [ + "motorcortex", + "donkeyclip" + ], + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + }, + "devDependencies": { + "@donkeyclip/motorcortex": "7.8.0", + "html-loader": "3.1.0", + "raw-loader": "4.0.2", + "@babel/core": "7.16.12", + "@babel/eslint-parser": "7.16.5", + "@babel/plugin-syntax-jsx": "7.16.7", + "@babel/plugin-transform-react-jsx": "7.16.7", + "@babel/preset-env": "7.16.11", + "@donkeyclip/motorcortex-player": "2.5.0", + "@donkeyclip/video-renderer": "0.0.1", + "@rollup/plugin-babel": "5.3.0", + "@rollup/plugin-commonjs": "21.0.1", + "@rollup/plugin-json": "4.1.0", + "@rollup/plugin-node-resolve": "13.1.3", + "@size-limit/preset-big-lib": "6.0.4", + "babel-loader": "8.2.3", + "concurrently": "6.5.1", + "core-js": "3.20.3", + "css-loader": "6.5.1", + "eslint": "7.32.0", + "eslint-config-prettier": "8.3.0", + "eslint-config-standard": "16.0.3", + "eslint-plugin-babel": "5.3.1", + "eslint-plugin-import": "2.25.4", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-prettier": "4.0.0", + "eslint-plugin-promise": "5.2.0", + "prettier": "2.5.1", + "rimraf": "3.0.2", + "size-limit": "6.0.4", + "style-loader": "3.3.1", + "webpack": "5.67.0", + "webpack-cli": "4.9.2", + "webpack-dev-server": "4.7.3" + } +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..d92ce4b --- /dev/null +++ b/renovate.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "config:base", + ":separateMajorReleases", + ":automergeMinor", + ":disablePeerDependencies", + ":semanticCommits", + ":automergeBranch" + ] +}