Save
This commit is contained in:
12
.vscode/sftp.json
vendored
Normal file
12
.vscode/sftp.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "hashtalk",
|
||||||
|
"host": "host117523.hostido.net.pl",
|
||||||
|
"username": "www@hashtalk.pagedev.pl",
|
||||||
|
"password": "5AVudnX9F3KsU7p8ykLj",
|
||||||
|
"remotePath": "/public_html",
|
||||||
|
"protocol": "ftp",
|
||||||
|
"port": 0,
|
||||||
|
"uploadOnSave": false,
|
||||||
|
"useTempFile": false,
|
||||||
|
"openSsh": false
|
||||||
|
}
|
||||||
BIN
wp-content/plugins/.DS_Store
vendored
Normal file
BIN
wp-content/plugins/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
wp-content/plugins/elementor-addon/assets/.DS_Store
vendored
Normal file
BIN
wp-content/plugins/elementor-addon/assets/.DS_Store
vendored
Normal file
Binary file not shown.
31
wp-content/plugins/elementor-addon/assets/css/main.css
Normal file
31
wp-content/plugins/elementor-addon/assets/css/main.css
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.hashtalk-3d-element {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 160px;
|
||||||
|
height: 520px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hashtalk-3d-element canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hashtalk-3d-element--error::before {
|
||||||
|
content: "3D model loading error";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.hashtalk-3d-element {
|
||||||
|
height: 360px;
|
||||||
|
}
|
||||||
|
}
|
||||||
259
wp-content/plugins/elementor-addon/assets/js/main.js
Normal file
259
wp-content/plugins/elementor-addon/assets/js/main.js
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const initialized = new WeakSet();
|
||||||
|
|
||||||
|
const defaults = {
|
||||||
|
modelUrl: '',
|
||||||
|
autoRotateSpeed: 0.002,
|
||||||
|
cursorStrength: 0.45,
|
||||||
|
floatingStrength: 0.06,
|
||||||
|
modelScale: 2.6,
|
||||||
|
cameraZ: 5
|
||||||
|
};
|
||||||
|
|
||||||
|
function toNumber(value, fallback) {
|
||||||
|
const number = Number(value);
|
||||||
|
return Number.isFinite(number) ? number : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSettings(element) {
|
||||||
|
let parsed = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(element.getAttribute('data-hashtalk-3d') || '{}');
|
||||||
|
} catch (error) {
|
||||||
|
parsed = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
modelUrl: parsed.modelUrl || defaults.modelUrl,
|
||||||
|
autoRotateSpeed: toNumber(parsed.autoRotateSpeed, defaults.autoRotateSpeed),
|
||||||
|
cursorStrength: toNumber(parsed.cursorStrength, defaults.cursorStrength),
|
||||||
|
floatingStrength: toNumber(parsed.floatingStrength, defaults.floatingStrength),
|
||||||
|
modelScale: toNumber(parsed.modelScale, defaults.modelScale),
|
||||||
|
cameraZ: toNumber(parsed.cameraZ, defaults.cameraZ)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function init3D(element) {
|
||||||
|
if (!element || initialized.has(element)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.THREE || !THREE.GLTFLoader) {
|
||||||
|
console.warn('[Hashtalk 3D] Three.js or GLTFLoader is not loaded.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized.add(element);
|
||||||
|
|
||||||
|
const settings = getSettings(element);
|
||||||
|
|
||||||
|
if (!settings.modelUrl) {
|
||||||
|
console.warn('[Hashtalk 3D] Model URL is empty.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
|
||||||
|
const camera = new THREE.PerspectiveCamera(
|
||||||
|
35,
|
||||||
|
element.clientWidth / Math.max(element.clientHeight, 1),
|
||||||
|
0.1,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
camera.position.set(0, 0, settings.cameraZ);
|
||||||
|
|
||||||
|
const renderer = new THREE.WebGLRenderer({
|
||||||
|
alpha: true,
|
||||||
|
antialias: true
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.setSize(element.clientWidth, element.clientHeight);
|
||||||
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
||||||
|
renderer.setClearColor(0x000000, 0);
|
||||||
|
|
||||||
|
if ('outputEncoding' in renderer && THREE.sRGBEncoding) {
|
||||||
|
renderer.outputEncoding = THREE.sRGBEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.innerHTML = '';
|
||||||
|
element.appendChild(renderer.domElement);
|
||||||
|
|
||||||
|
const ambientLight = new THREE.AmbientLight(0xffffff, 0.95);
|
||||||
|
scene.add(ambientLight);
|
||||||
|
|
||||||
|
const keyLight = new THREE.DirectionalLight(0xffffff, 1.45);
|
||||||
|
keyLight.position.set(3, 4, 5);
|
||||||
|
scene.add(keyLight);
|
||||||
|
|
||||||
|
const fillLight = new THREE.DirectionalLight(0xff9a3d, 0.6);
|
||||||
|
fillLight.position.set(-4, -2, 3);
|
||||||
|
scene.add(fillLight);
|
||||||
|
|
||||||
|
const group = new THREE.Group();
|
||||||
|
scene.add(group);
|
||||||
|
|
||||||
|
const targetRotation = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0.45
|
||||||
|
};
|
||||||
|
|
||||||
|
const loader = new THREE.GLTFLoader();
|
||||||
|
|
||||||
|
loader.load(
|
||||||
|
settings.modelUrl,
|
||||||
|
function (gltf) {
|
||||||
|
const model = gltf.scene;
|
||||||
|
|
||||||
|
model.traverse(function (child) {
|
||||||
|
if (child.isMesh) {
|
||||||
|
child.castShadow = false;
|
||||||
|
child.receiveShadow = false;
|
||||||
|
|
||||||
|
if (child.material) {
|
||||||
|
child.material.needsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const box = new THREE.Box3().setFromObject(model);
|
||||||
|
const center = box.getCenter(new THREE.Vector3());
|
||||||
|
const size = box.getSize(new THREE.Vector3());
|
||||||
|
const maxAxis = Math.max(size.x, size.y, size.z) || 1;
|
||||||
|
const scale = settings.modelScale / maxAxis;
|
||||||
|
|
||||||
|
model.scale.setScalar(scale);
|
||||||
|
model.position.set(
|
||||||
|
-center.x * scale,
|
||||||
|
-center.y * scale,
|
||||||
|
-center.z * scale
|
||||||
|
);
|
||||||
|
|
||||||
|
group.add(model);
|
||||||
|
element.classList.add('hashtalk-3d-element--loaded');
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
function (error) {
|
||||||
|
console.error('[Hashtalk 3D] GLTF loading error:', error);
|
||||||
|
element.classList.add('hashtalk-3d-element--error');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function updateCursor(event) {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const x = ((event.clientX - rect.left) / Math.max(rect.width, 1)) * 2 - 1;
|
||||||
|
const y = -(((event.clientY - rect.top) / Math.max(rect.height, 1)) * 2 - 1);
|
||||||
|
|
||||||
|
targetRotation.y = x * -settings.cursorStrength;
|
||||||
|
targetRotation.x = y * -settings.cursorStrength * 0.55;
|
||||||
|
targetRotation.z = x * -settings.cursorStrength * 0.16;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetCursor() {
|
||||||
|
targetRotation.x = 0;
|
||||||
|
targetRotation.y = 0;
|
||||||
|
targetRotation.z = 0.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.addEventListener('mousemove', updateCursor);
|
||||||
|
element.addEventListener('mouseleave', resetCursor);
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
const width = element.clientWidth || 1;
|
||||||
|
const height = element.clientHeight || 1;
|
||||||
|
|
||||||
|
camera.aspect = width / height;
|
||||||
|
camera.updateProjectionMatrix();
|
||||||
|
renderer.setSize(width, height);
|
||||||
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
const resizeObserver = window.ResizeObserver ? new ResizeObserver(resize) : null;
|
||||||
|
|
||||||
|
if (resizeObserver) {
|
||||||
|
resizeObserver.observe(element);
|
||||||
|
} else {
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
}
|
||||||
|
|
||||||
|
let frameId = null;
|
||||||
|
|
||||||
|
function destroy() {
|
||||||
|
if (frameId) {
|
||||||
|
cancelAnimationFrame(frameId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resizeObserver) {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
} else {
|
||||||
|
window.removeEventListener('resize', resize);
|
||||||
|
}
|
||||||
|
|
||||||
|
element.removeEventListener('mousemove', updateCursor);
|
||||||
|
element.removeEventListener('mouseleave', resetCursor);
|
||||||
|
|
||||||
|
renderer.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
if (!document.body.contains(element)) {
|
||||||
|
destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frameId = requestAnimationFrame(animate);
|
||||||
|
|
||||||
|
const time = performance.now() * 0.001;
|
||||||
|
|
||||||
|
group.rotation.y += settings.autoRotateSpeed;
|
||||||
|
group.rotation.x += (targetRotation.x - group.rotation.x) * 0.055;
|
||||||
|
group.rotation.z += (targetRotation.z - group.rotation.z) * 0.055;
|
||||||
|
|
||||||
|
group.position.y = Math.sin(time * 1.35) * settings.floatingStrength;
|
||||||
|
|
||||||
|
const pulse = 1 + Math.sin(time * 1.8) * settings.floatingStrength * 0.35;
|
||||||
|
group.scale.set(pulse, pulse, pulse);
|
||||||
|
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
resize();
|
||||||
|
animate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAll(scope) {
|
||||||
|
const root = scope && scope.querySelectorAll ? scope : document;
|
||||||
|
root.querySelectorAll('.hashtalk-3d-element').forEach(init3D);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addElementorHook() {
|
||||||
|
if (!window.elementorFrontend || !window.elementorFrontend.hooks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.elementorFrontend.hooks.addAction(
|
||||||
|
'frontend/element_ready/3d_element.default',
|
||||||
|
function ($scope) {
|
||||||
|
const scopeElement = $scope && $scope[0] ? $scope[0] : $scope;
|
||||||
|
initAll(scopeElement);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
initAll(document);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
initAll(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.jQuery) {
|
||||||
|
window.jQuery(window).on('elementor/frontend/init', addElementorHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
addElementorHook();
|
||||||
|
})();
|
||||||
File diff suppressed because one or more lines are too long
31
wp-content/plugins/elementor-addon/assets/scss/main.scss
Normal file
31
wp-content/plugins/elementor-addon/assets/scss/main.scss
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.hashtalk-3d-element {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 160px;
|
||||||
|
height: 520px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hashtalk-3d-element canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hashtalk-3d-element--error::before {
|
||||||
|
content: "3D model loading error";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.hashtalk-3d-element {
|
||||||
|
height: 360px;
|
||||||
|
}
|
||||||
|
}
|
||||||
91
wp-content/plugins/elementor-addon/elementor-addon.php
Normal file
91
wp-content/plugins/elementor-addon/elementor-addon.php
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: Elementor Addon
|
||||||
|
* Description: Custom Elementor widgets for Hashtalk.
|
||||||
|
* Version: 1.0.0
|
||||||
|
* Author: Elementor Developer
|
||||||
|
* Text Domain: elementor-addon
|
||||||
|
*
|
||||||
|
* Requires Plugins: elementor
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
define( 'ELEMENTOR_ADDON_VERSION', '1.0.0' );
|
||||||
|
define( 'ELEMENTOR_ADDON_PATH', plugin_dir_path( __FILE__ ) );
|
||||||
|
define( 'ELEMENTOR_ADDON_URL', plugin_dir_url( __FILE__ ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register custom Elementor category.
|
||||||
|
*/
|
||||||
|
function elementor_addon_register_widget_category( $elements_manager ) {
|
||||||
|
$elements_manager->add_category(
|
||||||
|
'hashtalk',
|
||||||
|
[
|
||||||
|
'title' => esc_html__( 'Hashtalk', 'elementor-addon' ),
|
||||||
|
'icon' => 'fa fa-plug',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action( 'elementor/elements/categories_registered', 'elementor_addon_register_widget_category' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register widget files.
|
||||||
|
*/
|
||||||
|
function register_elementor_addon_widgets( $widgets_manager ) {
|
||||||
|
require_once ELEMENTOR_ADDON_PATH . 'widgets/3d-element.php';
|
||||||
|
|
||||||
|
$widgets_manager->register( new \Elementor_3d_Element() );
|
||||||
|
}
|
||||||
|
add_action( 'elementor/widgets/register', 'register_elementor_addon_widgets' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register frontend assets only. Elementor will enqueue them only when the widget is used.
|
||||||
|
*/
|
||||||
|
function elementor_addon_register_assets() {
|
||||||
|
$css_path = ELEMENTOR_ADDON_PATH . 'assets/css/main.css';
|
||||||
|
$js_path = ELEMENTOR_ADDON_PATH . 'assets/js/main.js';
|
||||||
|
|
||||||
|
$css_ver = file_exists( $css_path ) ? filemtime( $css_path ) : ELEMENTOR_ADDON_VERSION;
|
||||||
|
$js_ver = file_exists( $js_path ) ? filemtime( $js_path ) : ELEMENTOR_ADDON_VERSION;
|
||||||
|
|
||||||
|
if ( ! wp_script_is( 'three-js', 'registered' ) ) {
|
||||||
|
wp_register_script(
|
||||||
|
'three-js',
|
||||||
|
'https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js',
|
||||||
|
[],
|
||||||
|
'0.128.0',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! wp_script_is( 'three-gltfloader', 'registered' ) ) {
|
||||||
|
wp_register_script(
|
||||||
|
'three-gltfloader',
|
||||||
|
'https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.js',
|
||||||
|
[ 'three-js' ],
|
||||||
|
'0.128.0',
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_register_style(
|
||||||
|
'elementor-addon-main-css',
|
||||||
|
ELEMENTOR_ADDON_URL . 'assets/css/main.css',
|
||||||
|
[],
|
||||||
|
$css_ver
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'elementor-addon-main-js',
|
||||||
|
ELEMENTOR_ADDON_URL . 'assets/js/main.js',
|
||||||
|
[ 'three-js', 'three-gltfloader' ],
|
||||||
|
$js_ver,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action( 'wp_enqueue_scripts', 'elementor_addon_register_assets' );
|
||||||
|
add_action( 'elementor/frontend/after_register_scripts', 'elementor_addon_register_assets' );
|
||||||
|
add_action( 'elementor/frontend/after_register_styles', 'elementor_addon_register_assets' );
|
||||||
201
wp-content/plugins/elementor-addon/widgets/3d-element.php
Normal file
201
wp-content/plugins/elementor-addon/widgets/3d-element.php
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<?php
|
||||||
|
use Elementor\Widget_Base;
|
||||||
|
use Elementor\Controls_Manager;
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Elementor_3d_Element extends Widget_Base {
|
||||||
|
public function get_name() {
|
||||||
|
return '3d_element';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_title() {
|
||||||
|
return esc_html__( '3D Element', 'elementor-addon' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_icon() {
|
||||||
|
return 'eicon-3d-cube';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_categories() {
|
||||||
|
return [ 'hashtalk' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_keywords() {
|
||||||
|
return [ '3d', 'three', 'gltf', 'logo', 'hashtalk' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_style_depends() {
|
||||||
|
return [ 'elementor-addon-main-css' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_script_depends() {
|
||||||
|
return [ 'three-js', 'three-gltfloader', 'elementor-addon-main-js' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function register_controls() {
|
||||||
|
$this->start_controls_section(
|
||||||
|
'section_content',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( '3D Model', 'elementor-addon' ),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'model_url',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Model URL', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::TEXT,
|
||||||
|
'label_block' => true,
|
||||||
|
'default' => ELEMENTOR_ADDON_URL . 'assets/models/Logo_Hashtalk_Model.gltf',
|
||||||
|
'placeholder' => 'https://example.com/model.gltf',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_responsive_control(
|
||||||
|
'height',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Height', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::SLIDER,
|
||||||
|
'size_units' => [ 'px', 'vh' ],
|
||||||
|
'range' => [
|
||||||
|
'px' => [
|
||||||
|
'min' => 160,
|
||||||
|
'max' => 900,
|
||||||
|
],
|
||||||
|
'vh' => [
|
||||||
|
'min' => 20,
|
||||||
|
'max' => 100,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'default' => [
|
||||||
|
'size' => 520,
|
||||||
|
'unit' => 'px',
|
||||||
|
],
|
||||||
|
'selectors' => [
|
||||||
|
'{{WRAPPER}} .hashtalk-3d-element' => 'height: {{SIZE}}{{UNIT}};',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'auto_rotate_speed',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Auto Rotate Speed', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::NUMBER,
|
||||||
|
'min' => 0,
|
||||||
|
'max' => 0.08,
|
||||||
|
'step' => 0.001,
|
||||||
|
'default' => 0.008,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'cursor_strength',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Cursor Tracking Strength', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::NUMBER,
|
||||||
|
'min' => 0,
|
||||||
|
'max' => 1.5,
|
||||||
|
'step' => 0.05,
|
||||||
|
'default' => 0.45,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'floating_strength',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Floating Strength', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::NUMBER,
|
||||||
|
'min' => 0,
|
||||||
|
'max' => 0.5,
|
||||||
|
'step' => 0.01,
|
||||||
|
'default' => 0.06,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'model_scale',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Model Scale', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::NUMBER,
|
||||||
|
'min' => 0.1,
|
||||||
|
'max' => 10,
|
||||||
|
'step' => 0.1,
|
||||||
|
'default' => 2.6,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->add_control(
|
||||||
|
'camera_z',
|
||||||
|
[
|
||||||
|
'label' => esc_html__( 'Camera Distance', 'elementor-addon' ),
|
||||||
|
'type' => Controls_Manager::NUMBER,
|
||||||
|
'min' => 1,
|
||||||
|
'max' => 20,
|
||||||
|
'step' => 0.1,
|
||||||
|
'default' => 5,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->end_controls_section();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function render() {
|
||||||
|
$settings = $this->get_settings_for_display();
|
||||||
|
|
||||||
|
$model_url = ! empty( $settings['model_url'] )
|
||||||
|
? $settings['model_url']
|
||||||
|
: $this->get_default_model_url();
|
||||||
|
|
||||||
|
$model_url = $this->normalize_model_url( $model_url );
|
||||||
|
|
||||||
|
$config = [
|
||||||
|
'modelUrl' => esc_url_raw( $model_url ),
|
||||||
|
'autoRotateSpeed' => isset( $settings['auto_rotate_speed'] ) ? (float) $settings['auto_rotate_speed'] : 0.008,
|
||||||
|
'cursorStrength' => isset( $settings['cursor_strength'] ) ? (float) $settings['cursor_strength'] : 0.45,
|
||||||
|
'floatingStrength' => isset( $settings['floating_strength'] ) ? (float) $settings['floating_strength'] : 0.06,
|
||||||
|
'modelScale' => isset( $settings['model_scale'] ) ? (float) $settings['model_scale'] : 2.6,
|
||||||
|
'cameraZ' => isset( $settings['camera_z'] ) ? (float) $settings['camera_z'] : 5,
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
<div
|
||||||
|
class="hashtalk-3d-element"
|
||||||
|
data-hashtalk-3d="<?php echo esc_attr( wp_json_encode( $config ) ); ?>"
|
||||||
|
></div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get_default_model_url() {
|
||||||
|
return ELEMENTOR_ADDON_URL . 'assets/models/Logo_Hashtalk_Model.gltf';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalize_model_url( $url ) {
|
||||||
|
$url = trim( (string) $url );
|
||||||
|
|
||||||
|
if ( '' === $url ) {
|
||||||
|
return $this->get_default_model_url();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix: http://wp-content/plugins/...
|
||||||
|
$url = preg_replace( '#^https?://wp-content/#i', '/wp-content/', $url );
|
||||||
|
|
||||||
|
// Fix: wp-content/plugins/...
|
||||||
|
if ( 0 === strpos( $url, 'wp-content/' ) ) {
|
||||||
|
$url = '/' . $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix: /wp-content/plugins/...
|
||||||
|
if ( 0 === strpos( $url, '/wp-content/' ) ) {
|
||||||
|
$url = home_url( $url );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_ssl() ) {
|
||||||
|
$url = set_url_scheme( $url, 'https' );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.header-btn {
|
.header-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -32,4 +36,52 @@
|
|||||||
.header-btn .elementor-button .elementor-button-content-wrapper .elementor-button-icon svg {
|
.header-btn .elementor-button .elementor-button-content-wrapper .elementor-button-icon svg {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-tag {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 9px 3px 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.box-tag::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
clip-path: polygon(25% 0%, 100% 0%, 100% 50%, 0% 100%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 35px;
|
||||||
|
height: 45px;
|
||||||
|
left: 26px;
|
||||||
|
top: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
.box-tag::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
clip-path: polygon(0% 0%, 100% 0%, 75% 100%, 0% 100%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
top: 0;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 0;
|
||||||
|
transform: translateX(100%);
|
||||||
|
z-index: 0;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
.box-tag .elementor-heading-title {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.page-id-11 .hp-hero-box #hp-hero-3d {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.56;
|
||||||
|
}
|
||||||
|
body.page-id-11 .hp-hero-box #hp-hero-3d > .elementor-widget-container {
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
}/*# sourceMappingURL=custom.css.map */
|
}/*# sourceMappingURL=custom.css.map */
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sources":["custom.scss","custom.css"],"names":[],"mappings":"AAAA;EACC,kBAAA;ACCD;ADCC;EACC,WAAA;EACA,kBAAA;EACA,MAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,uDAAA;EACA,yBAAA;ACCF;ADEC;EACC,WAAA;EACA,kBAAA;EACA,MAAA;EACA,SAAA;EACA,YAAA;EACA,WAAA;EACA,qDAAA;EACA,yBAAA;ACAF;ADGC;EACC,4BAAA;ACDF;ADGE;EACC,cAAA;EACA,mBAAA;EACA,QAAA;ACDH;ADII;EACC,WAAA;EACA,YAAA;ACFL","file":"custom.css"}
|
{"version":3,"sources":["custom.scss","custom.css"],"names":[],"mappings":"AACC;EACC,gBAAA;ACAF;;ADIA;EACC,kBAAA;ACDD;ADGC;EACC,WAAA;EACA,kBAAA;EACA,MAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,uDAAA;EACA,yBAAA;ACDF;ADIC;EACC,WAAA;EACA,kBAAA;EACA,MAAA;EACA,SAAA;EACA,YAAA;EACA,WAAA;EACA,qDAAA;EACA,yBAAA;ACFF;ADKC;EACC,4BAAA;ACHF;ADKE;EACC,cAAA;EACA,mBAAA;EACA,QAAA;ACHH;ADMI;EACC,WAAA;EACA,YAAA;ACJL;;ADWA;EACC,kBAAA;EACA,qBAAA;EACA,yBAAA;EACA,mBAAA;EACA,mBAAA;ACRD;ADUC;EACC,WAAA;EACA,kBAAA;EACA,sDAAA;EACA,yBAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,MAAA;EACA,4BAAA;EACA,UAAA;ACRF;ADUC;EACC,WAAA;EACA,kBAAA;EACA,qDAAA;EACA,yBAAA;EACA,MAAA;EACA,WAAA;EACA,SAAA;EACA,2BAAA;EACA,UAAA;EACA,WAAA;ACRF;ADWC;EACC,kBAAA;ACTF;;ADeE;EACC,kBAAA;EACA,QAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,aAAA;ACZH;ADcG;EACC,YAAA;EACA,WAAA;ACZJ","file":"custom.css"}
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
p {
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header-btn {
|
.header-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -40,3 +46,58 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box-tag {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 9px 3px 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
background: #ffffff;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
clip-path: polygon(25% 0%, 100% 0%, 100% 50%, 0% 100%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 35px;
|
||||||
|
height: 45px;
|
||||||
|
left: 26px;
|
||||||
|
top: 0;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
clip-path: polygon(0% 0%, 100% 0%, 75% 100%, 0% 100%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
top: 0;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 0;
|
||||||
|
transform: translateX(100%);
|
||||||
|
z-index: 0;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elementor-heading-title {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.page-id-11 {
|
||||||
|
.hp-hero-box {
|
||||||
|
#hp-hero-3d {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.56;
|
||||||
|
|
||||||
|
> .elementor-widget-container {
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user