{"id":8808,"date":"2026-01-25T08:43:23","date_gmt":"2026-01-25T07:43:23","guid":{"rendered":"https:\/\/innovacore.group\/?post_type=portfolio&p=8808"},"modified":"2026-03-17T15:53:04","modified_gmt":"2026-03-17T13:53:04","slug":"contribly","status":"publish","type":"portfolio","link":"https:\/\/innovacore.group\/fr\/portfolio\/contribly\/","title":{"rendered":"Contribly &#8211; Booster l&rsquo;engagement des lecteurs"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Contribly is a SaaS platform born at The Guardian, designed to master Community Generated Content (CGC) at scale. It streamlines the collection, moderation, and instant publishing of user stories, photos, and videos. By turning passive readers into active contributors, Contribly saves editorial teams significant time while drastically boosting loyalty, time-on-page, and first-party data collection for publishers and brands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>La plateforme SaaS pour collecter, mod\u00e9rer et publier le contenu communautaire \u00e0 grande \u00e9chelle.<\/p>\n","protected":false},"featured_media":2369,"parent":0,"template":"","meta":{"inline_featured_image":false,"company_name":"Contribly","summary":"La plateforme SaaS pour collecter, mod\u00e9rer et publier le contenu communautaire \u00e0 grande \u00e9chelle.","mission":"<p>Transformer l'engagement du public en un atout strat\u00e9gique pour l'entreprise. La mission de Contribly est d'aider les \u00e9diteurs \u00e0 instaurer une confiance et une pertinence profondes en rendant sans effort l'inclusion des lecteurs dans l'histoire, en convertissant l'engagement en donn\u00e9es propri\u00e9taires pr\u00e9cieuses et en croissance des abonnements.<\/p>\n","impact":"<p>Contribly red\u00e9finit la relation \u00e9diteur-audience en passant de la \"diffusion\" \u00e0 une conversation bidirectionnelle. Il offre aux r\u00e9dactions un mod\u00e8le d'\u00ab \u00e9change de valeur \u00bb qui g\u00e9n\u00e8re un trafic \u00e0 l'\u00e9preuve des algorithmes et des donn\u00e9es de grande valeur, essentielles pour rendre les mod\u00e8les \u00e9conomiques des m\u00e9dias robustes face \u00e0 la d\u00e9pendance vis-\u00e0-vis des plateformes sociales.<\/p>\n","company_logo":"https:\/\/innovacore.group\/wp-content\/uploads\/contribly_logo-innovacore-optimized.jpg","website_url":"https:\/\/www.contribly.com\/","linkedin_url":"https:\/\/www.linkedin.com\/company\/contribly\/","location":"Northwich, Royaume-Uni","founded_year":"","key_numbers":{"item-0":{"metric_label":"Temps pass\u00e9 sur la page","metric_value":"3-10x"},"item-1":{"metric_label":"Engagement Social","metric_value":"3x"},"item-2":{"metric_label":"Croissance des t\u00e9l\u00e9chargements d'app","metric_value":"44%"}},"hiring_status":"furtif","sector":"saas","company_type":"start-up","audience":["b2b"],"geo_scope":["mondial"],"business_model":["saas"],"funding_stage":"en cours","partnership_type":"mise \u00e0 niveau","logo_animation":"<div id=\"contribly-particle-root\">\r\n    <canvas id=\"contriblyCanvas\"><\/canvas>\r\n<\/div>\r\n\r\n<style>\r\n    #contribly-particle-root {\r\n        width: 100%;\r\n        height: 300px;\r\n        display: flex;\r\n        justify-content: center;\r\n        align-items: center;\r\n        background: transparent;\r\n        overflow: hidden;\r\n        cursor: crosshair;\r\n    }\r\n<\/style>\r\n\r\n<script>\r\n(function() {\r\n    const canvas = document.getElementById('contriblyCanvas');\r\n    const ctx = canvas.getContext('2d', { willReadFrequently: true });\r\n    const root = document.getElementById('contribly-particle-root');\r\n    \r\n    let width, height;\r\n    let particles = [];\r\n    let mouse = { x: -1000, y: -1000 };\r\n    const particleColor = '#f5f5f5'; \/\/ Gris clair demand\u00e9\r\n    let time = 0;\r\n\r\n    function init() {\r\n        width = root.offsetWidth;\r\n        height = 300;\r\n        \r\n        const dpr = window.devicePixelRatio || 1;\r\n        canvas.width = width * dpr;\r\n        canvas.height = height * dpr;\r\n        canvas.style.width = width + 'px';\r\n        canvas.style.height = height + 'px';\r\n        ctx.scale(dpr, dpr);\r\n\r\n        createLogoParticles();\r\n    }\r\n\r\n    function createLogoParticles() {\r\n        particles = [];\r\n        const cx = width \/ 2;\r\n        const cy = height \/ 2;\r\n        const isMobile = width < 600;\r\n\r\n        \/\/ --- 1. CONFIGURATION DU DESSIN ---\r\n        ctx.fillStyle = 'white';\r\n        ctx.strokeStyle = 'white';\r\n\r\n        \/\/ Dimensions relatives\r\n        \/\/ On augmente un peu la taille de l'ic\u00f4ne pour bien voir les d\u00e9tails\r\n        const iconSize = isMobile ? 60 : 100; \r\n        const fontSize = isMobile ? 35 : 60;\r\n        const gap = isMobile ? 15 : 30;\r\n\r\n        \/\/ Typo\r\n        ctx.font = `bold ${fontSize}px \"Poppins\", \"Montserrat\", Arial, sans-serif`;\r\n        const textMetrics = ctx.measureText('Contribly');\r\n        const textWidth = textMetrics.width;\r\n\r\n        \/\/ Centrage\r\n        const totalWidth = iconSize + gap + textWidth;\r\n        const startX = cx - (totalWidth \/ 2);\r\n        const centerY = cy;\r\n\r\n        \/\/ --- 2. DESSIN DE L'IC\u00d4NE (Complexe et fid\u00e8le) ---\r\n        const ix = startX;\r\n        const iy = centerY - (iconSize \/ 2);\r\n        const centerIx = ix + iconSize \/ 2;\r\n        const centerIy = iy + iconSize \/ 2;\r\n\r\n        \/\/ A. Le cadre carr\u00e9 (fin)\r\n        ctx.lineWidth = iconSize * 0.03;\r\n        ctx.strokeRect(ix, iy, iconSize, iconSize);\r\n\r\n        \/\/ B. Le Point Central (Le plus gros)\r\n        const centerDotRad = iconSize * 0.12;\r\n        ctx.beginPath();\r\n        ctx.arc(centerIx, centerIy, centerDotRad, 0, Math.PI * 2);\r\n        ctx.fill();\r\n\r\n        \/\/ C. Les Points P\u00e9riph\u00e9riques (Tailles et positions vari\u00e9es)\r\n        const networkRad = iconSize * 0.36; \/\/ Distance au centre\r\n        const bigRad = iconSize * 0.075;   \/\/ Rayon des \"gros\" points p\u00e9riph\u00e9riques\r\n        const smallRad = iconSize * 0.045; \/\/ Rayon des \"petits\" points\r\n\r\n        \/\/ D\u00e9finition manuelle des 6 points pour respecter le logo :\r\n        \/\/ Angles approximatifs en radians et taille associ\u00e9e.\r\n        const pointsDef = [\r\n            { angle: -0.4, size: smallRad }, \/\/ Haut-Droite (petit)\r\n            { angle: 0.3,  size: smallRad }, \/\/ Droite (petit)\r\n            { angle: 1.2,  size: bigRad },   \/\/ Bas-Droite (gros)\r\n            { angle: 2.6,  size: bigRad },   \/\/ Bas-Gauche (gros)\r\n            { angle: 3.5,  size: smallRad }, \/\/ Gauche (petit)\r\n            { angle: 4.5,  size: bigRad }    \/\/ Haut-Gauche (gros)\r\n        ];\r\n\r\n        ctx.lineWidth = iconSize * 0.025; \/\/ Lignes de connexion fines\r\n\r\n        pointsDef.forEach(pt => {\r\n            const px = centerIx + Math.cos(pt.angle) * networkRad;\r\n            const py = centerIy + Math.sin(pt.angle) * networkRad;\r\n\r\n            \/\/ 1. La ligne de connexion\r\n            ctx.beginPath();\r\n            ctx.moveTo(centerIx, centerIy);\r\n            ctx.lineTo(px, py);\r\n            ctx.stroke();\r\n\r\n            \/\/ 2. Le point\r\n            ctx.beginPath();\r\n            ctx.arc(px, py, pt.size, 0, Math.PI * 2);\r\n            ctx.fill();\r\n        });\r\n\r\n\r\n        \/\/ --- 3. DESSIN DU TEXTE ---\r\n        const textX = startX + iconSize + gap;\r\n        ctx.textAlign = 'left';\r\n        ctx.textBaseline = 'middle';\r\n        ctx.fillText('Contribly', textX, centerY);\r\n\r\n\r\n        \/\/ --- 4. SCAN DES PIXELS (Densit\u00e9 \u00e9lev\u00e9e pour le d\u00e9tail) ---\r\n        const density = 3;\r\n        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\r\n        const dataWidth = canvas.width; \r\n\r\n        for (let y = 0; y < canvas.height; y += density) {\r\n            for (let x = 0; x < canvas.width; x += density) {\r\n                if (imageData[(y * dataWidth + x) * 4 + 3] > 128) {\r\n                    const dpr = window.devicePixelRatio || 1;\r\n                    particles.push({\r\n                        x: x \/ dpr,\r\n                        y: y \/ dpr,\r\n                        originX: x \/ dpr,\r\n                        originY: y \/ dpr,\r\n                        vx: 0, \r\n                        vy: 0,\r\n                        \/\/ Taille de particule l\u00e9g\u00e8rement variable pour le c\u00f4t\u00e9 \"soft\"\r\n                        size: Math.random() * 1.2 + 0.8, \r\n                    });\r\n                }\r\n            }\r\n        }\r\n        \r\n        ctx.clearRect(0, 0, width, height);\r\n    }\r\n\r\n    function draw() {\r\n        ctx.clearRect(0, 0, width, height);\r\n        \r\n        \/\/ --- PHYSIQUE \"SOFT\" ---\r\n        time += 0.02; \/\/ Vitesse d'ondulation lente\r\n\r\n        ctx.fillStyle = particleColor;\r\n        \r\n        particles.forEach(p => {\r\n            \/\/ 1. Respiration lente et ample\r\n            const waveX = Math.sin(time * 0.5 + p.y * 0.03) * 3;\r\n            const waveY = Math.cos(time * 0.4 + p.x * 0.03) * 3;\r\n\r\n            \/\/ 2. Interaction Souris douce\r\n            const dx = mouse.x - p.x;\r\n            const dy = mouse.y - p.y;\r\n            const dist = Math.sqrt(dx*dx + dy*dy);\r\n            const radius = 100;\r\n\r\n            let repelX = 0;\r\n            let repelY = 0;\r\n\r\n            if (dist < radius) {\r\n                const force = (radius - dist) \/ radius;\r\n                const angle = Math.atan2(dy, dx);\r\n                \/\/ Force mod\u00e9r\u00e9e (10) pour une r\u00e9pulsion visible mais pas violente\r\n                repelX = -Math.cos(angle) * force * 10;\r\n                repelY = -Math.sin(angle) * force * 10;\r\n            }\r\n\r\n            const targetX = p.originX + waveX;\r\n            const targetY = p.originY + waveY;\r\n\r\n            \/\/ 3. Physique fluide (Retour \u00e9lastique mou et forte friction)\r\n            const ax = (targetX - p.x) * 0.02; \/\/ Retour tr\u00e8s souple\r\n            const ay = (targetY - p.y) * 0.02;\r\n\r\n            p.vx += ax;\r\n            p.vy += ay;\r\n            p.vx += repelX * 0.2; \/\/ Application douce de la force souris\r\n            p.vy += repelY * 0.2;\r\n            \r\n            \/\/ Friction \u00e9lev\u00e9e pour l'effet \"flottant dans l'eau\"\r\n            p.vx *= 0.92; \r\n            p.vy *= 0.92;\r\n\r\n            p.x += p.vx;\r\n            p.y += p.vy;\r\n\r\n            ctx.beginPath();\r\n            ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);\r\n            ctx.fill();\r\n        });\r\n\r\n        requestAnimationFrame(draw);\r\n    }\r\n\r\n    const updateMouse = (e) => {\r\n        const r = canvas.getBoundingClientRect();\r\n        const cx = e.touches ? e.touches[0].clientX : e.clientX;\r\n        const cy = e.touches ? e.touches[0].clientY : e.clientY;\r\n        mouse.x = cx - r.left;\r\n        mouse.y = cy - r.top;\r\n    };\r\n\r\n    window.addEventListener('resize', init);\r\n    canvas.addEventListener('mousemove', updateMouse);\r\n    canvas.addEventListener('touchmove', updateMouse, {passive: true});\r\n    canvas.addEventListener('mouseleave', () => { mouse.x = -1000; mouse.y = -1000; });\r\n    canvas.addEventListener('touchend', () => { mouse.x = -1000; mouse.y = -1000; });\r\n\r\n    setTimeout(init, 100);\r\n    draw();\r\n})();\r\n<\/script>"},"pt":[],"pipeline":[],"class_list":["post-8808","portfolio","type-portfolio","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/portfolio\/8808","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/portfolio"}],"about":[{"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/types\/portfolio"}],"version-history":[{"count":1,"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/portfolio\/8808\/revisions"}],"predecessor-version":[{"id":8809,"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/portfolio\/8808\/revisions\/8809"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/media\/2369"}],"wp:attachment":[{"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/media?parent=8808"}],"wp:term":[{"taxonomy":"pt","embeddable":true,"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/pt?post=8808"},{"taxonomy":"pipeline","embeddable":true,"href":"https:\/\/innovacore.group\/fr\/wp-json\/wp\/v2\/pipeline?post=8808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}